mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-02 06:06:41 +01:00
Truncate long posts on timeline, show "Read more"
10-line clamping for now
This commit is contained in:
parent
734a9b2b76
commit
400bc6f696
4 changed files with 137 additions and 3 deletions
74
package-lock.json
generated
74
package-lock.json
generated
|
@ -19,6 +19,7 @@
|
||||||
"preact-router": "~4.1.0",
|
"preact-router": "~4.1.0",
|
||||||
"react-intersection-observer": "~9.4.1",
|
"react-intersection-observer": "~9.4.1",
|
||||||
"string-length": "~5.0.1",
|
"string-length": "~5.0.1",
|
||||||
|
"use-resize-observer": "~9.1.0",
|
||||||
"valtio": "~1.7.6"
|
"valtio": "~1.7.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -27,7 +28,7 @@
|
||||||
"autoprefixer": "~10.4.13",
|
"autoprefixer": "~10.4.13",
|
||||||
"postcss": "~8.4.20",
|
"postcss": "~8.4.20",
|
||||||
"postcss-dark-theme-class": "~0.7.3",
|
"postcss-dark-theme-class": "~0.7.3",
|
||||||
"vite": "4.0.1"
|
"vite": "~4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
|
@ -848,6 +849,11 @@
|
||||||
"@jridgewell/sourcemap-codec": "1.4.14"
|
"@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": {
|
"node_modules/@preact/preset-vite": {
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.5.0.tgz",
|
||||||
|
@ -1996,6 +2002,19 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/react-intersection-observer": {
|
||||||
"version": "9.4.1",
|
"version": "9.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz",
|
||||||
|
@ -2042,6 +2061,15 @@
|
||||||
"fsevents": "~2.3.2"
|
"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": {
|
"node_modules/semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
@ -2205,6 +2233,18 @@
|
||||||
"tslib": "^2.0.3"
|
"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": {
|
"node_modules/use-sync-external-store": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
"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"
|
"@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": {
|
"@preact/preset-vite": {
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@preact/preset-vite/-/preset-vite-2.5.0.tgz",
|
||||||
|
@ -3702,6 +3747,16 @@
|
||||||
"loose-envify": "^1.1.0"
|
"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": {
|
"react-intersection-observer": {
|
||||||
"version": "9.4.1",
|
"version": "9.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz",
|
||||||
|
@ -3733,6 +3788,15 @@
|
||||||
"fsevents": "~2.3.2"
|
"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": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
@ -3847,6 +3911,14 @@
|
||||||
"tslib": "^2.0.3"
|
"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": {
|
"use-sync-external-store": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
"preact-router": "~4.1.0",
|
"preact-router": "~4.1.0",
|
||||||
"react-intersection-observer": "~9.4.1",
|
"react-intersection-observer": "~9.4.1",
|
||||||
"string-length": "~5.0.1",
|
"string-length": "~5.0.1",
|
||||||
|
"use-resize-observer": "~9.1.0",
|
||||||
"valtio": "~1.7.6"
|
"valtio": "~1.7.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -28,7 +29,7 @@
|
||||||
"autoprefixer": "~10.4.13",
|
"autoprefixer": "~10.4.13",
|
||||||
"postcss": "~8.4.20",
|
"postcss": "~8.4.20",
|
||||||
"postcss-dark-theme-class": "~0.7.3",
|
"postcss-dark-theme-class": "~0.7.3",
|
||||||
"vite": "4.0.1"
|
"vite": "~4.0.1"
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"plugins": {
|
"plugins": {
|
||||||
|
|
|
@ -174,6 +174,30 @@
|
||||||
.status .content {
|
.status .content {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
.timeline-deck .status .content {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 10;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.timeline-deck .status .content.truncated:after {
|
||||||
|
content: attr(data-read-more);
|
||||||
|
line-height: 1;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
inset-block-end: 0;
|
||||||
|
inset-inline-end: 0;
|
||||||
|
color: var(--link-color);
|
||||||
|
background-color: var(--link-faded-color);
|
||||||
|
backdrop-filter: blur(4px) brightness(2);
|
||||||
|
padding: 0.5em 0.5em 0.5em 2em;
|
||||||
|
border-radius: 0 1em 1em 0;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
mask-image: linear-gradient(to right, transparent, black 2em);
|
||||||
|
}
|
||||||
.status .content p {
|
.status .content p {
|
||||||
margin-block: 0.75em;
|
margin-block: 0.75em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { getBlurHashAverageColor } from 'fast-blurhash';
|
||||||
import mem from 'mem';
|
import mem from 'mem';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
|
||||||
import { InView } from 'react-intersection-observer';
|
import { InView } from 'react-intersection-observer';
|
||||||
|
import useResizeObserver from 'use-resize-observer';
|
||||||
import { useSnapshot } from 'valtio';
|
import { useSnapshot } from 'valtio';
|
||||||
|
|
||||||
import Loader from '../components/loader';
|
import Loader from '../components/loader';
|
||||||
|
@ -619,6 +620,34 @@ function Status({
|
||||||
const carouselRef = useRef(null);
|
const carouselRef = useRef(null);
|
||||||
const currentYear = new Date().getFullYear();
|
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 (
|
return (
|
||||||
<div
|
<div
|
||||||
class={`status ${
|
class={`status ${
|
||||||
|
@ -714,7 +743,12 @@ function Status({
|
||||||
>
|
>
|
||||||
{!!spoilerText && sensitive && (
|
{!!spoilerText && sensitive && (
|
||||||
<>
|
<>
|
||||||
<div class="content">
|
<div
|
||||||
|
class="content"
|
||||||
|
lang={language}
|
||||||
|
ref={spoilerContentRef}
|
||||||
|
data-read-more={readMoreText}
|
||||||
|
>
|
||||||
<p>{spoilerText}</p>
|
<p>{spoilerText}</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
@ -733,6 +767,9 @@ function Status({
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
class="content"
|
class="content"
|
||||||
|
lang={language}
|
||||||
|
ref={contentRef}
|
||||||
|
data-read-more={readMoreText}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
let { target } = e;
|
let { target } = e;
|
||||||
if (target.parentNode.tagName.toLowerCase() === 'a') {
|
if (target.parentNode.tagName.toLowerCase() === 'a') {
|
||||||
|
|
Loading…
Reference in a new issue