stacker.news/components/comment.module.css
soxa 0e842e9915
live comments: auto show new comments (#2355)
* enhance: FaviconProvider, keep track of new comment IDs to change favicon, remove new comment IDs per outline removal

* don't track oneself comments

* enhance: auto-show new comments, idempotency by ignoring already injected comments, preserveScroll utility

* fadeIn animation on comment injection; cleanup: remove unused counts and thread handling; non-critical fix: always give rootLastCommentAt a value

* reliably preserve scroll position by tracking a reference found at the center of the viewport; cleanup: add more comments, add cleanup function

* mitigate fractional scrolling subtle layout shifts by rounding the new reference element position

* enhanced outlining system, favicon context keeps track of new comments presence

- de-outlining now happens only for outlined comments
- enhanced outlining: add outline only if isNewComment
- de-outlining will remove the new comments favicon
- on unmount remove the new comments favicon

* remove the new comments favicon on new comments injection

* track only deduplicated new comments

* fix typo

* clearer unsetOutline conditions, fix typo in live comments hook

* backport: remove the injectedComment class from injected comments after animation ends

* set the new comments favicon on any new outlined comment

* enhance: directly inject new comments; cleanup: dismantle ShowNewComments, remove newComments field

* tweaks: slower injection animation, clear favicon on Comment section unmount

* change nDirectComments bug strategy to avoiding updates on comment edit

* cleanup: better naming, re-instate injected comments outline

* injection: major cache utilities refactor, don't preserve scroll if no comments have been injected

- don't preserve scroll if after deduplication we don't inject any comments

- use manual read/write cache updates to control the flow
-- allows to check if we are really injecting or not

- reduce polling to 5 seconds instead of 10

- light cleanup
-- removed update cache functions
-- added 'injected' to typeDefs (gql consistency)

* cleanup: detailed comments, refactor, remove clutter

Refactor:
+ clearer variables
+ depth calculation utility function
+ use destructured Apollo cache
+ extract item object from item query
+ skip ignored comment instead of ending the loop

CSS:
+ from-to fadeIn animation keyframes
- floatingComments unused class

Favicon:
+ provider exported by default

* fix wrong merge

* split: remove favicon context

* split: remove favicon pngs

* regression: revert to updateQuery for multiple comment fragments handling

* reverse multiple reads for deduplication on comment injection

* fix regression on apollo manipulations via fn; cleanup: remove wrong deps from outlining
2025-08-08 10:04:54 -05:00

171 lines
2.5 KiB
CSS

.item {
align-items: flex-start;
margin-bottom: 0 !important;
padding-top: 0 !important;
}
.upvote {
margin-top: 9px;
padding-right: 0.2rem;
}
.pin {
fill: #a5a5a5;
margin-left: .2rem;
margin-right: .3rem;
flex-shrink: 0;
}
.dontLike {
fill: #a5a5a5;
margin-right: .35rem;
padding: 2px;
margin-left: 1px;
margin-top: 9px;
cursor: pointer;
}
.text {
margin-top: .1rem;
padding-right: 15px;
}
.edit {
display: inline-block;
cursor: pointer;
}
.op {
margin-top: -1px;
vertical-align: text-top;
}
.collapsed .hunk {
margin-bottom: .5rem;
}
.collapsed .text,
.collapsed .children {
display: none;
}
.collapsed .upvote, .collapsed .dontLike {
visibility: hidden;
height: 0;
}
.collapser {
cursor: pointer;
fill: var(--theme-grey);
width: 45px;
margin-left: auto;
user-select: none;
}
.children {
margin-top: 0;
margin-left: 27px;
}
.comments {
margin-left: -.75rem;
}
@media screen and (min-width: 768px) {
.comments {
margin-left: .75rem;
}
}
.skeleton .hunk {
width: 100%;
}
.skeleton .text {
height: 80px;
border-radius: .4rem;
margin-right: 15px;
}
.skeleton .reply {
width: 45px;
height: 10px;
border-radius: .2rem;
}
.replyPadder {
padding: .25rem 0;
padding-bottom: .5rem;
}
.replyContainer {
display: flex;
justify-content: flex-start;
align-items: center;
}
.comment {
border-radius: .4rem;
padding-top: .5rem;
padding-left: .7rem;
background-color: var(--theme-commentBg);
}
.bountyIcon {
margin-left: 5px;
margin-right: 5px;
}
.hunk {
margin-bottom: 0;
margin-top: 0.15rem;
}
.comment:not(:last-of-type) {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.comment:not(:first-of-type) {
padding-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.comment:has(.comment) + .comment{
padding-top: .5rem;
}
.newCommentDot {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: var(--bs-primary);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
background-color: #80d3ff;
opacity: 0.7;
}
50% {
background-color: #007cbe;
opacity: 1;
}
100% {
background-color: #80d3ff;
opacity: 0.7;
}
}
.injectedComment {
animation: fadeIn 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}