Merge pull request #10 from cheeaun/main

Update from main
This commit is contained in:
Chee Aun 2022-12-18 13:07:45 +08:00 committed by GitHub
commit 818c8e61cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 303 additions and 50 deletions

BIN
design/logo-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

1
design/logo-3.svg Normal file
View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"><rect id="Logo-simple" serif:id="Logo simple" x="0" y="0" width="63.994" height="63.994" style="fill:none;"/><g id="Logo-simple1" serif:id="Logo simple"><path d="M56.352,22.413c-1.293,-5.447 -5.633,-10.525 -10.622,-12.696c-5.656,-2.462 -17.315,-3.499 -23.317,-2.075c-5.293,1.256 -10.462,5.488 -12.696,10.621c-2.462,5.657 -3.499,17.316 -2.075,23.318c1.293,5.447 5.633,10.525 10.621,12.696c5.657,2.462 17.316,3.499 23.318,2.075c5.293,-1.256 10.462,-5.488 12.696,-10.622c2.462,-5.656 3.499,-17.315 2.075,-23.317Z" style="fill:#d8e7fe;stroke:#a4bff7;stroke-width:6px;"/><path d="M38.644,24.754c0.838,4.163 1.381,10.15 1.004,15.758" style="fill:none;stroke:#6892e2;stroke-width:6px;"/><path d="M27.013,23.719c-1.56,3.95 -3.152,9.747 -3.77,15.333" style="fill:none;stroke:#6892e2;stroke-width:6px;"/></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -2,11 +2,15 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Phanpy</title>
<meta name="color-scheme" content="dark light" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<meta name="apple-mobile-web-app-title" content="Phanpy" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<link rel="canonical" href="https://phanpy.social" />
</head>
<body>
<div id="app"></div>

74
package-lock.json generated
View file

@ -19,6 +19,7 @@
"preact-router": "~4.1.0",
"react-intersection-observer": "~9.4.1",
"string-length": "~5.0.1",
"use-resize-observer": "~9.1.0",
"valtio": "~1.7.6"
},
"devDependencies": {
@ -27,7 +28,7 @@
"autoprefixer": "~10.4.13",
"postcss": "~8.4.20",
"postcss-dark-theme-class": "~0.7.3",
"vite": "4.0.1"
"vite": "~4.0.1"
}
},
"node_modules/@ampproject/remapping": {
@ -848,6 +849,11 @@
"@jridgewell/sourcemap-codec": "1.4.14"
}
},
"node_modules/@juggle/resize-observer": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="
},
"node_modules/@preact/preset-vite": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.5.0.tgz",
@ -1996,6 +2002,19 @@
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.0"
},
"peerDependencies": {
"react": "^18.2.0"
}
},
"node_modules/react-intersection-observer": {
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz",
@ -2042,6 +2061,15 @@
"fsevents": "~2.3.2"
}
},
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@ -2205,6 +2233,18 @@
"tslib": "^2.0.3"
}
},
"node_modules/use-resize-observer": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz",
"integrity": "sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==",
"dependencies": {
"@juggle/resize-observer": "^3.3.1"
},
"peerDependencies": {
"react": "16.8.0 - 18",
"react-dom": "16.8.0 - 18"
}
},
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
@ -2836,6 +2876,11 @@
"@jridgewell/sourcemap-codec": "1.4.14"
}
},
"@juggle/resize-observer": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
"integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="
},
"@preact/preset-vite": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.5.0.tgz",
@ -3702,6 +3747,16 @@
"loose-envify": "^1.1.0"
}
},
"react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"peer": true,
"requires": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.0"
}
},
"react-intersection-observer": {
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz",
@ -3733,6 +3788,15 @@
"fsevents": "~2.3.2"
}
},
"scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"peer": true,
"requires": {
"loose-envify": "^1.1.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@ -3847,6 +3911,14 @@
"tslib": "^2.0.3"
}
},
"use-resize-observer": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz",
"integrity": "sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==",
"requires": {
"@juggle/resize-observer": "^3.3.1"
}
},
"use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",

View file

@ -20,6 +20,7 @@
"preact-router": "~4.1.0",
"react-intersection-observer": "~9.4.1",
"string-length": "~5.0.1",
"use-resize-observer": "~9.1.0",
"valtio": "~1.7.6"
},
"devDependencies": {
@ -28,7 +29,7 @@
"autoprefixer": "~10.4.13",
"postcss": "~8.4.20",
"postcss-dark-theme-class": "~0.7.3",
"vite": "4.0.1"
"vite": "~4.0.1"
},
"postcss": {
"plugins": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -121,16 +121,6 @@ a.mention span {
.timeline.flat > li {
border-bottom: none;
}
/* .timeline li.insignificant {
filter: opacity(0.5);
background-color: var(--bg-faded-color);
}
.timeline li.insignificant > * {
opacity: 0.75;
}
.timeline li.insignificant:hover > * {
opacity: 1;
} */
.timeline.contextual > li {
--width: 3px;
@ -471,7 +461,7 @@ button.carousel-dot[disabled].active {
background-color: var(--bg-color);
width: 100%;
max-width: calc(40em - 50px - 16px);
border-radius: 36px 36px 0 0;
border-radius: 16px 16px 0 0;
padding: 16px;
box-shadow: 0 -1px 32px var(--divider-color);
animation: slide-up 0.2s ease-out;

View file

@ -1,12 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" clip-rule="evenodd" viewBox="0 0 381 368">
<path fill="#d8e7fe" d="M79 82.3C68.4 80.8 23 73 20.3 49.1c-3-27 43.8-41.5 77.6-40.3 20.1.7 44 6.3 55.8 9.4l3.2-1.5a102 102 0 0 1 46-9.5c19.6.1 54.4 11.5 78 36.4A109 109 0 0 1 297 69.3a175.8 175.8 0 0 1 31.5 26c24.7 26.6 53.2 83.5 36.9 109.4a116.7 116.7 0 0 1-17.3 21.8c2.1 10.6 3.2 15.8 3.2 20.8 0 6.6-9.9 41.3-16 56.2-6 15-14.5 35.7-19.3 39.9-4.8 4-33.8 3.5-39.6-2.2-5.9-5.8-7.9-31.3-7.9-31.3l-2.2-2.7c-4.1 1-7.9 1.8-10.7 2-2 .2-14.6 46.7-19.3 50.7-4.8 4-44 4.8-49.4-.2-2.4-2.2-3.3-10.5-3.6-19.6-2.2-.3-5.6-1-6.8-2.2-1.6-1.5-4.4-25.1-5.3-32.2-7-2.8-14.9-7-17.7-8.9-4.2-3-21.9-14.1-28.4-14-9 0-43.3 11-55.1 11.6-6.4.4-11.4-1.2-16.8-5.2-10.4-7.7-15.7-32.3-12.3-43.4 2.7-8.7 48-28 52-39.3a71.9 71.9 0 0 0 1.9-27H88c-11.9 0-36.1 4-59-9.7C6.5 156.1 6.9 141 7.5 127c.6-13.8 16.4-26.4 22.9-28.5 4.8-1.5 18.6-2 30.4-7.5C68 87.6 74 85 79 82.3ZM103.6 65 86.8 78a74 74 0 0 0 16.9-13.1Z"/>
<path fill="#edcafe" stroke="#a4bff7" stroke-linecap="round" stroke-miterlimit="1.5" stroke-width="8" d="M122.2 177.4s6 10.2 8 16c1.9 5.9 9.6 28.2 20.9 27.8 11.2-.3 15-9.8 16-12.3 1.9-4.5 3-15.7 1.8-21.4-10.3-.5-20-3.3-27.5-12.7l-19.2 2.6Z"/>
<path fill="none" stroke="#a4bff7" stroke-linecap="round" stroke-linejoin="miter" stroke-miterlimit="1.5" stroke-width="8" d="M268.6 309.9s2 25.5 7.9 31.3c5.8 5.7 34.8 6.3 39.6 2.2 4.8-4.2 13.4-24.9 19.4-39.8 6-15 15.9-49.7 15.9-56.3 0-6.6-1.9-13.8-5.8-33.5-3.9-19.6-37.9-142-64.6-170.2-23.6-25-58.4-36.3-78-36.4a102 102 0 0 0-46 9.5c-21.7 9.9-36.2 28.4-48.5 42.9C96.2 74 88.7 78 60.7 90.9c-11.8 5.5-25.6 6-30.4 7.5-6.5 2-22.3 14.7-23 28.5-.5 14-1 29.2 21.9 43 22.8 13.6 47 9.5 59 9.6 10.8.1 26.9-.8 34-2.5 4-1 10-2.5 14.6-2 2.7.2 4-.5 5 .5 1.5 1.6 5.4 6.5 11.4 9 6 2.4 10.4 3.7 15.2 3.4 4.8-.3 10-2.6 13.7-5.3"/>
<path fill="#d8e7fe" d="M269.7 53.8s34.4 15.3 59 41.6c24.6 26.5 53 83.4 36.8 109.3-16.3 26-37.7 41.5-56.6 38-19-3.6-53.4-48.3-62-70-7.5-18.9-15.2-57-6-105.3 3.9-20.1 28.8-13.6 28.8-13.6"/>
<path fill="none" stroke="#a4bff7" stroke-linecap="round" stroke-miterlimit="1.5" stroke-width="8" d="M269.7 53.8s34.4 15.3 59 41.6c24.6 26.5 53 83.4 36.8 109.3-16.3 26-37.7 41.5-56.6 38-19-3.6-53.4-48.3-62-70-7.5-18.9-15.2-57-6-105.3M152 17.6c-8.4-2.2-31.7-8-54-8.8-33.8-1.2-80.6 13.3-77.6 40.3 3 27 60.6 33.5 60.6 33.5m14 99.1s2.1 13.6-2 24.8c-4 11.3-49.3 30.6-52 39.3-3.4 11 1.9 35.7 12.3 43.4 5.4 4 10.4 5.6 16.8 5.2 11.8-.6 46-11.5 55.1-11.6 6.5-.1 24.2 11 28.4 14 4.2 3 19.8 10.7 27 11.7"/>
<path fill="none" stroke="#a4bff7" stroke-linecap="round" stroke-miterlimit="1.5" stroke-width="8" d="M174.4 299.5s6.7 6 8.1 12.4c1.5 6.4-1 42.7 4.5 47.8 5.4 5 44.6 4.1 49.4.2 4.7-4 17.4-50.5 19.3-50.6 14.5-1.4 51.2-14.8 56-20m-140.3 18.9s3.3 28 5.2 29.7c1.9 1.9 4.4 2 4.4 2"/>
<path fill="#6892e2" d="M203 97.5c1.7.3 5.2 12.1 1.8 25.1-4 15.7-10.4 19.8-12.4 19.6-5.8-.4 3.4-46 10.6-44.7Z"/>
<path fill="#4c73b3" d="M48.5 94.6s17-28 44.7-25.8c25.8 2 43.7 25 45.2 28.5a43 43 0 0 1 2.5 23c-2.2 5.2-30.8 12-37.3 10-6.5-2-21-38.5-33.3-39.1-12.7-.7-21.8 3.4-21.8 3.4ZM66.9 7.2S24.5 24.1 25.3 43c.6 15.4 42.8 20.2 44 24.4 1.1 3.8-15.7 8.2-25 8.2-9.5 0-28.8-5.2-29.7-22.3C13.3 26.1 46 8 67 7.3ZM295 164.3c3.4-.7 42.5 27 40.4 57.5-1.6 23.9-18.4 28.6-24.7 28.6-18 .1-30.2-24.2-30.2-24.2s4.4 4.3 7.2 4.4c2.8 0 .7-45.3 1.9-52 1-5.7 1.1-13.3 5.4-14.3Zm46.5-10.8c4.1-3.6 37 18.7 38.5 46.5 1.4 25.7-27 30.2-30.7 29.6-1.9-.3 3.9-5.4 5.8-11.6 2-6.1-12.6-51.9-13.6-56.3-.6-2.6-1.1-7.2 0-8.2Z"/>
<path fill="#a4bff7" d="M354.5 237.2s11.4 8.3 11.2 11.6c-.4 4.7-12.8 7.8-12.8 7.8l-3 .2 1.5-21.6 3 2Z"/>
<path fill="none" stroke="#6892e2" stroke-linecap="round" stroke-miterlimit="1.5" stroke-width="8" d="M40.3 124.1c2.2 7.5 4.1 18.2 4.3 28.4M24.8 120c-5.4 6.2-5.1 18.3-4 25.7"/>
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5" clip-rule="evenodd" viewBox="0 0 64 64">
<path fill="none" d="M0 0h63.99v63.99H0z"/>
<g stroke-width="6">
<path fill="#d8e7fe" stroke="#a4bff7" d="M56.35 22.41a19.43 19.43 0 0 0-10.62-12.7c-5.66-2.46-17.32-3.5-23.32-2.07a19.43 19.43 0 0 0-12.7 10.62c-2.46 5.66-3.5 17.32-2.07 23.32a19.43 19.43 0 0 0 10.62 12.7c5.66 2.46 17.32 3.5 23.32 2.07a19.43 19.43 0 0 0 12.7-10.62c2.46-5.66 3.5-17.31 2.07-23.32Z"/>
<path fill="none" stroke="#6892e2" d="M38.64 24.75a63.7 63.7 0 0 1 1 15.76M27.01 23.72a63.64 63.64 0 0 0-3.77 15.33"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 703 B

View file

@ -2,7 +2,7 @@
color: var(--outline-color);
}
#account-container header{
#account-container header {
display: flex;
align-items: center;
gap: 8px;
@ -16,8 +16,10 @@
#account-container .stats {
display: flex;
flex-wrap: wrap;
gap: 16px;
column-gap: 16px;
row-gap: 4px;
opacity: 0.75;
font-size: 90%;
}
#account-container .actions {
@ -29,3 +31,27 @@
#account-container .actions button {
align-self: flex-end;
}
#account-container .profile-metadata {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
#account-container .profile-field {
flex-grow: 1;
font-size: 90%;
background-color: var(--bg-faded-color);
padding: 12px;
border-radius: 8px;
filter: saturate(0.75);
line-height: 1.25;
}
#account-container .profile-field b {
font-size: 90%;
color: var(--text-insignificant-color);
text-transform: uppercase;
}
#account-container .profile-field p {
margin: 0;
}

View file

@ -104,7 +104,7 @@ function Account({ account }) {
{!info || uiState === 'loading' ? (
<>
<header>
<Avatar size="xxl" />
<Avatar size="xxxl" />
</header>
<div class="note">
@ -120,7 +120,7 @@ function Account({ account }) {
) : (
<>
<header>
<Avatar url={avatar} size="xxl" />
<Avatar url={avatar} size="xxxl" />
<NameText account={info} showAcct external />
</header>
<div
@ -129,6 +129,18 @@ function Account({ account }) {
__html: enhanceContent(note, { emojis }),
}}
/>
<div class="profile-metadata">
{fields.map(({ name, value }) => (
<div class="profile-field" key={name}>
<b>{name}</b>
<p
dangerouslySetInnerHTML={{
__html: value,
}}
/>
</div>
))}
</div>
<p class="stats">
<span>
<b title={statusesCount}>{shortenNumber(statusesCount)}</b> Posts
@ -141,6 +153,20 @@ function Account({ account }) {
<b title={followersCount}>{shortenNumber(followersCount)}</b>{' '}
Followers
</span>
{!!createdAt && (
<span>
Joined:{' '}
<b>
<time datetime={createdAt}>
{Intl.DateTimeFormat('en', {
year: 'numeric',
month: 'short',
day: 'numeric',
}).format(new Date(createdAt))}
</time>
</b>
</span>
)}
</p>
<p class="actions">
{followedBy ? <span class="tag">Following you</span> : <span />}{' '}

View file

@ -6,6 +6,7 @@ const SIZES = {
l: 24,
xl: 32,
xxl: 50,
xxxl: 64,
};
function Avatar({ url, size, alt = '' }) {

View file

@ -174,6 +174,43 @@
.status .content {
margin-top: 8px;
}
.timeline-deck .status .content {
max-height: 50vh;
max-height: 50dvh;
overflow: hidden;
position: relative;
}
.timeline-deck .status .content.truncated {
mask-image: linear-gradient(
to top,
transparent,
rgba(0, 0, 0, 0.5) 1em,
black 1.5em
);
}
.timeline-deck .status .content.truncated:after {
content: attr(data-read-more);
line-height: 1;
display: inline-block;
position: absolute;
inset-block-end: 1.5em;
left: 50%;
transform: translateX(-50%);
color: var(--text-color);
background-color: var(--bg-faded-color);
border: 1px dashed var(--link-color);
padding: 0.75em 1em;
border-radius: 10em;
font-size: 90%;
white-space: nowrap;
box-shadow: 0 0 0 1px var(--bg-color), 0 -5px 10px var(--bg-color),
0 -5px 15px var(--bg-color), 0 -5px 20px var(--bg-color);
transition: transform 0.5s ease-in-out;
}
.timeline-deck .status .content.truncated:hover:after {
color: var(--link-color);
transform: translateX(-50%) translateY(-2px) scale(1.01);
}
.status .content p {
margin-block: 0.75em;
}
@ -460,6 +497,7 @@ a.card:hover {
min-height: 40px;
min-width: 40px;
padding: 0 8px;
font-variant-numeric: tabular-nums;
}
.status .actions > button.plain {
color: inherit;

View file

@ -4,6 +4,7 @@ import { getBlurHashAverageColor } from 'fast-blurhash';
import mem from 'mem';
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
import { InView } from 'react-intersection-observer';
import useResizeObserver from 'use-resize-observer';
import { useSnapshot } from 'valtio';
import Loader from '../components/loader';
@ -614,12 +615,39 @@ function Status({
);
}
const [actionsUIState, setActionsUIState] = useState(null); // boost-loading, favourite-loading, bookmark-loading
const [showEdited, setShowEdited] = useState(false);
const carouselRef = useRef(null);
const currentYear = new Date().getFullYear();
const spoilerContentRef = useRef(null);
useResizeObserver({
ref: spoilerContentRef,
onResize: () => {
if (spoilerContentRef.current) {
const { scrollHeight, clientHeight } = spoilerContentRef.current;
spoilerContentRef.current.classList.toggle(
'truncated',
scrollHeight > clientHeight,
);
}
},
});
const contentRef = useRef(null);
useResizeObserver({
ref: contentRef,
onResize: () => {
if (contentRef.current) {
const { scrollHeight, clientHeight } = contentRef.current;
contentRef.current.classList.toggle(
'truncated',
scrollHeight > clientHeight,
);
}
},
});
const readMoreText = 'Read more →';
return (
<div
class={`status ${
@ -715,7 +743,12 @@ function Status({
>
{!!spoilerText && sensitive && (
<>
<div class="content">
<div
class="content"
lang={language}
ref={spoilerContentRef}
data-read-more={readMoreText}
>
<p>{spoilerText}</p>
</div>
<button
@ -734,6 +767,9 @@ function Status({
)}
<div
class="content"
lang={language}
ref={contentRef}
data-read-more={readMoreText}
onClick={(e) => {
let { target } = e;
if (target.parentNode.tagName.toLowerCase() === 'a') {
@ -1160,7 +1196,7 @@ function StatusButton({
{!!count && (
<>
{' '}
<small>{shortenNumber(count)}</small>
<small title={count}>{shortenNumber(count)}</small>
</>
)}
</button>

View file

@ -218,6 +218,10 @@ code {
flex-grow: 1;
}
.insignificant {
color: var(--text-insignificant-color);
}
/* KEYFRAMES */
@keyframes fade-in {

View file

@ -16,13 +16,13 @@ function Home({ hidden }) {
const [uiState, setUIState] = useState('default');
const [showMore, setShowMore] = useState(false);
const statusIterator = useRef(
masto.timelines.getHomeIterable({
const homeIterator = useRef(
masto.timelines.iterateHome({
limit: LIMIT,
}),
).current;
async function fetchStatuses(firstLoad) {
const allStatuses = await statusIterator.next(
const allStatuses = await homeIterator.next(
firstLoad
? {
limit: LIMIT,
@ -83,8 +83,16 @@ function Home({ hidden }) {
if (diffMins > 1) {
console.log('visible', { lastHidden, diffMins });
setTimeout(() => {
loadStatuses(true);
states.homeNew = [];
(async () => {
const newStatus = await masto.timelines.fetchHome({
limit: 1,
});
if (newStatus.length && newStatus[0].id !== states.home[0].id) {
states.homeNew = newStatus;
}
})();
// loadStatuses(true);
// states.homeNew = [];
}, 100);
}
}
@ -133,7 +141,7 @@ function Home({ hidden }) {
<Icon icon="notification" size="l" alt="Notifications" />
</a>
</div>
{snapStates.homeNew.length > 0 && (
{snapStates.homeNew.length > 1 && (
<button
class="updates-button"
type="button"

View file

@ -3,6 +3,10 @@
padding: 16px !important;
gap: 16px;
}
.only-mentions .notification:not(.mention),
.only-mentions .timeline-empty {
display: none;
}
.notification.skeleton {
color: var(--outline-color);
}
@ -30,7 +34,11 @@
max-height: 160px;
overflow: hidden;
/* fade out mask gradient bottom */
mask-image: linear-gradient(rgba(0, 0, 0, 1), rgba(0, 0, 0, 1) 50%, transparent);
mask-image: linear-gradient(
rgba(0, 0, 0, 1),
rgba(0, 0, 0, 1) 50%,
transparent
);
filter: saturate(0.25);
}
.notification .status-link:hover {
@ -47,3 +55,23 @@
.notification-content p:first-child {
margin-top: 0;
}
#mentions-option {
float: right;
margin-top: 0.5em;
}
#mentions-option label {
color: var(--text-insignificant-color);
display: inline-block;
padding: 1em 16px;
position: relative;
cursor: pointer;
z-index: 1;
font-size: 90%;
background-color: var(--bg-blur-color);
border-radius: 2em;
}
#mentions-option label:has(:checked) {
color: var(--text-color);
background-color: var(--bg-color);
}

View file

@ -97,6 +97,18 @@ function Notification({ notification }) {
</>
)}
{text}
{type === 'mention' && (
<span class="insignificant">
{' '}
{' '}
<relative-time
datetime={notification.createdAt}
format="micro"
threshold="P1D"
prefix=""
/>
</span>
)}
</p>
{_accounts?.length > 1 && (
<p>
@ -192,9 +204,10 @@ function Notifications() {
const snapStates = useSnapshot(states);
const [uiState, setUIState] = useState('default');
const [showMore, setShowMore] = useState(false);
const [onlyMentions, setOnlyMentions] = useState(false);
const notificationsIterator = useRef(
masto.notifications.getIterator({
masto.notifications.iterate({
limit: LIMIT,
}),
).current;
@ -273,7 +286,7 @@ function Notifications() {
// console.log(groupedNotifications);
return (
<div class="deck-container" ref={scrollableRef}>
<div class="timeline-deck deck">
<div class={`timeline-deck deck ${onlyMentions ? 'only-mentions' : ''}`}>
<header>
<div class="header-side">
<a href="#" class="button plain">
@ -310,6 +323,18 @@ function Notifications() {
</button>
)}
</header>
<div id="mentions-option">
<label>
<input
type="checkbox"
checked={onlyMentions}
onChange={(e) => {
setOnlyMentions(e.target.checked);
}}
/>{' '}
Only mentions
</label>
</div>
{snapStates.notifications.length ? (
<>
<h2 class="timeline-header">Today</h2>

View file

@ -166,11 +166,9 @@ function StatusPage({ id }) {
<li
key={statusID}
ref={isHero ? heroStatusRef : null}
class={`${isHero ? '' : 'insignificant'} ${
ancestor ? 'ancestor' : ''
} ${descendant ? 'descendant' : ''} ${
descendant && !directReply ? 'indirect' : ''
}`}
class={`${ancestor ? 'ancestor' : ''} ${
descendant ? 'descendant' : ''
} ${descendant && !directReply ? 'indirect' : ''}`}
>
{isHero ? (
<Status statusID={statusID} withinContext size="l" />