Skip to content

Commit b359d70

Browse files
[web][photos] Comments fixes (#8630)
2 parents 6adfc69 + 42d34c5 commit b359d70

File tree

13 files changed

+318
-62
lines changed

13 files changed

+318
-62
lines changed

web/apps/embed/src/components/EmbedFileListWithViewer.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ export const EmbedFileListWithViewer: React.FC<
128128
files={files}
129129
disableDownload={true}
130130
showFullscreenButton={true}
131+
enableComment={false}
131132
onTriggerRemotePull={handleTriggerRemotePull}
132133
onVisualFeedback={() => {
133134
// Visual feedback requested

web/apps/embed/src/styles/photoswipe.css

Lines changed: 232 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,33 @@
1111
top: calc(env(titlebar-area-height, 0px) * 0.4);
1212
}
1313

14+
@media (width >= 450px) {
15+
.pswp-ente .pswp__top-bar {
16+
padding-top: 24px;
17+
}
18+
}
19+
20+
/* Black gradient overlay at the top */
21+
.pswp-ente .pswp__top-bar::before {
22+
content: "";
23+
position: absolute;
24+
top: 0;
25+
left: 0;
26+
right: 0;
27+
height: 125px;
28+
background: linear-gradient(
29+
to top,
30+
transparent 0%,
31+
rgb(0 0 0 / 0.05) 20%,
32+
rgb(0 0 0 / 0.15) 40%,
33+
rgb(0 0 0 / 0.3) 60%,
34+
rgb(0 0 0 / 0.45) 80%,
35+
rgb(0 0 0 / 0.6) 100%
36+
);
37+
pointer-events: none;
38+
z-index: -1;
39+
}
40+
1441
/* The PhotoSwipe CSS already disables and re-enables pointer-events for hidden
1542
UI elements, but for a reason that I didn't investigate more, that isn't
1643
working, and the hidden buttons still remain clickable.
@@ -81,11 +108,29 @@
81108
line-height: 20px;
82109
}
83110

111+
@media (width >= 450px) {
112+
.pswp-ente .pswp__counter {
113+
margin-top: 22px;
114+
margin-inline-start: 44px;
115+
}
116+
}
117+
84118
.pswp-ente .pswp__button--zoom .pswp__icn {
85119
top: 16px;
86120
transform: scale(0.85);
87121
}
88122

123+
/* When counter is hidden (single photo), give zoom button the left margin */
124+
.pswp-ente.pswp--one-slide .pswp__top-bar .pswp__button--zoom {
125+
margin-left: 4px;
126+
}
127+
128+
@media (width >= 450px) {
129+
.pswp-ente.pswp--one-slide .pswp__top-bar .pswp__button--zoom {
130+
margin-left: 28px;
131+
}
132+
}
133+
89134
.pswp-ente .pswp__preloader {
90135
transform: translate(-2px, 2px);
91136
}
@@ -102,6 +147,21 @@
102147
margin-right: 2px;
103148
}
104149

150+
/* Remove black strokes from top bar icons */
151+
.pswp-ente .pswp__top-bar .pswp__icn-shadow {
152+
stroke-width: 0;
153+
}
154+
155+
@media (width >= 450px) {
156+
.pswp-ente .pswp__top-bar .pswp__button {
157+
margin-left: 8px;
158+
}
159+
160+
.pswp-ente .pswp__button--close {
161+
margin-right: 20px;
162+
}
163+
}
164+
105165
.pswp-ente .pswp__button--arrow--prev .pswp__icn {
106166
transform: scale(0.8);
107167
}
@@ -148,18 +208,12 @@
148208
}
149209
}
150210

151-
/* 4 line caption */
211+
/* Caption styling */
152212

153213
.pswp-ente .pswp__caption {
154-
position: absolute;
155-
bottom: 0px;
156-
right: 0;
157-
margin: 20px 24px;
158214
border-radius: 3px;
159215
/* Same opacity as the other controls. */
160216
color: rgb(255 255 255 / 0.85);
161-
background-color: rgb(0 0 0 / 0.2);
162-
backdrop-filter: blur(10px);
163217
max-width: 375px;
164218
max-height: 200px;
165219
p {
@@ -175,21 +229,18 @@
175229
}
176230
}
177231

232+
/* Desktop caption: max 40% width */
233+
@media (width >= 450px) {
234+
.pswp-ente .pswp__caption {
235+
max-width: 40%;
236+
}
237+
}
238+
178239
.pswp-ente .pswp__caption.ente-video {
179-
/* Add extra offset for video captions so that they do not overlap with the
180-
video controls. The constant was picked such that it lay above the media
181-
controls. */
182-
bottom: 48px;
183-
/* Adding a caption with a blur backdrop filter above the video element
184-
contained in a media-controller causes a subtle tint to be overlaid on
185-
the entire video. This is visible on both Chrome and Firefox as of
186-
writing.
187-
188-
We'll hide the caption anyways when hovering on the controls or when the
189-
video is playing, so remove the backdrop filter and rely on the
190-
translucent background. Note that usually the video might not even extent
191-
to this part of the screen on desktop sized screens. */
192-
backdrop-filter: none;
240+
/* Add blur box background for videos since we hide the gradient overlay */
241+
background-color: rgb(0 0 0 / 0.2);
242+
backdrop-filter: blur(10px);
243+
border-radius: 16px;
193244
/* Since there is too much going on in this part of the screen now, also
194245
reduce the maximum number of lines for the caption. */
195246
p {
@@ -205,7 +256,7 @@
205256
}
206257

207258
/*
208-
Make the controllable video elements we render as custom PhotoSwipe content
259+
Make the controllable video elements we render as custom PhotoSwipe content
209260
take .pswp-ente up the entire container.
210261
*/
211262
.pswp-ente video[controls] {
@@ -351,14 +402,13 @@ media-settings-menu {
351402
z-index: 1;
352403
}
353404

354-
/* Hide the caption when hovering over the video controls (and when the settings
355-
menu is open) since they occupy similar real estate as the caption. */
405+
/* Hide the bottom right controls when hovering over the video controls or
406+
when the settings menu is open. */
356407
body:has(
357408
media-time-range[mediapreviewtime],
358-
media-controller:not([mediapaused]),
359409
media-settings-menu:not([hidden])
360410
) {
361-
& .pswp-ente .pswp__caption {
411+
& .pswp-ente .pswp__bottom-right-controls {
362412
display: none;
363413
}
364414
}
@@ -395,7 +445,161 @@ body:has(
395445
opacity: 1;
396446
}
397447

398-
/* Also hide the caption in video fullscreen mode */
399-
.pswp-ente.pswp--video-fullscreen .pswp__caption {
448+
/* Also hide the bottom right controls in video fullscreen mode */
449+
.pswp-ente.pswp--video-fullscreen .pswp__bottom-right-controls {
450+
display: none;
451+
}
452+
453+
/* Bottom controls container (caption on left, action buttons on right on desktop) */
454+
.pswp-ente .pswp__bottom-right-controls {
455+
position: absolute;
456+
bottom: 20px;
457+
right: 24px;
458+
display: flex;
459+
/* column-reverse to show buttons on top, caption below (matching original HTML order) */
460+
flex-direction: column-reverse;
461+
align-items: flex-end;
462+
gap: 12px;
463+
}
464+
465+
/* Black gradient overlay at the bottom */
466+
.pswp-ente .pswp__bottom-right-controls::before {
467+
content: "";
468+
position: absolute;
469+
bottom: -20px;
470+
left: -24px;
471+
right: -24px;
472+
height: 225px;
473+
background: linear-gradient(
474+
to bottom,
475+
transparent 0%,
476+
rgb(0 0 0 / 0.05) 20%,
477+
rgb(0 0 0 / 0.15) 40%,
478+
rgb(0 0 0 / 0.3) 60%,
479+
rgb(0 0 0 / 0.45) 80%,
480+
rgb(0 0 0 / 0.6) 100%
481+
);
482+
pointer-events: none;
483+
z-index: -1;
484+
}
485+
486+
/* Row layout on desktop: caption on left, buttons on right */
487+
@media (width >= 450px) {
488+
.pswp-ente .pswp__bottom-right-controls {
489+
bottom: 40px;
490+
left: 28px;
491+
right: 44px;
492+
flex-direction: row;
493+
align-items: flex-end;
494+
gap: 24px;
495+
}
496+
497+
.pswp-ente .pswp__bottom-right-controls::before {
498+
bottom: -40px;
499+
left: -28px;
500+
right: -44px;
501+
}
502+
}
503+
504+
/* Extra offset for video to clear video controls */
505+
.pswp-ente .pswp__bottom-right-controls:has(.pswp__caption.ente-video) {
506+
bottom: 100px;
507+
}
508+
509+
/* Hide gradient overlay for videos since they have their own controls gradient */
510+
.pswp-ente .pswp__bottom-right-controls:has(.pswp__caption.ente-video)::before {
511+
display: none;
512+
}
513+
514+
/* Hide gradient overlay when description is not present */
515+
.pswp-ente
516+
.pswp__bottom-right-controls:has(
517+
.pswp__caption[style*="display: none"]
518+
)::before {
519+
display: none;
520+
}
521+
522+
/* Action buttons row - margin-left: auto keeps them on the right when no caption */
523+
.pswp-ente .pswp__action-buttons {
524+
display: flex;
525+
flex-direction: row;
526+
gap: 20px;
527+
margin-left: auto;
528+
}
529+
530+
.pswp-ente .pswp__action-button {
531+
width: 56px;
532+
height: 56px;
533+
border-radius: 50%;
534+
background-color: rgb(0 0 0 / 0.6);
535+
border: 1px solid rgb(255 255 255 / 0.2);
536+
cursor: pointer;
537+
display: flex;
538+
align-items: center;
539+
justify-content: center;
540+
transition: background-color 0.2s ease;
541+
}
542+
543+
.pswp-ente .pswp__action-button:hover {
544+
background-color: rgb(0 0 0 / 0.8);
545+
}
546+
547+
.pswp-ente .pswp__action-button svg {
548+
width: 28px;
549+
height: 28px;
550+
fill: white;
551+
}
552+
553+
/* Comment button with count indicator */
554+
.pswp-ente .pswp__action-button--comment {
555+
position: relative;
556+
}
557+
558+
.pswp-ente .pswp__comment-count {
559+
position: absolute;
560+
top: -6px;
561+
right: -6px;
562+
width: 24px;
563+
height: 24px;
564+
border-radius: 50%;
565+
background-color: #fff;
566+
color: #000;
567+
font-family: "Inter Variable", sans-serif;
568+
font-size: 12px;
569+
font-weight: 600;
570+
line-height: 24px;
571+
text-align: center;
572+
display: none;
573+
}
574+
575+
.pswp-ente .pswp__comment-count:not(:empty) {
576+
display: block;
577+
}
578+
579+
/* Reduce padding on mobile */
580+
@media (width < 450px) {
581+
.pswp-ente .pswp__bottom-right-controls {
582+
bottom: 12px;
583+
left: 12px;
584+
right: 12px;
585+
}
586+
587+
.pswp-ente .pswp__bottom-right-controls::before {
588+
bottom: -12px;
589+
left: -12px;
590+
right: -12px;
591+
}
592+
}
593+
594+
/* Heart (like) button icons - uses pswp__hidden class toggled by showIf() */
595+
#pswp__icn-heart-fill {
596+
display: none;
597+
}
598+
599+
#pswp__icn-heart-fill:not(.pswp__hidden) {
600+
display: inline;
601+
}
602+
603+
#pswp__icn-heart.pswp__hidden {
400604
display: none;
401605
}

web/apps/photos/src/components/FileListWithViewer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export type FileListWithViewerProps = {
129129
| "collectionKey"
130130
| "onJoinAlbum"
131131
| "enableComment"
132+
| "enableJoin"
132133
>;
133134

134135
/**
@@ -184,6 +185,7 @@ export const FileListWithViewer: React.FC<FileListWithViewerProps> = ({
184185
collectionKey,
185186
onJoinAlbum,
186187
enableComment,
188+
enableJoin,
187189
}) => {
188190
const [openFileViewer, setOpenFileViewer] = useState(false);
189191
const [currentIndex, setCurrentIndex] = useState(0);
@@ -384,6 +386,7 @@ export const FileListWithViewer: React.FC<FileListWithViewerProps> = ({
384386
collectionKey,
385387
onJoinAlbum,
386388
enableComment,
389+
enableJoin,
387390
}}
388391
isCommentsFeatureEnabled={isCommentsEnabled}
389392
onTriggerRemotePull={handleTriggerRemotePull}

web/apps/photos/src/components/TripLayout/index.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ interface TripLayoutProps {
5858
* When `false`, the feed button will be hidden.
5959
*/
6060
enableComment?: boolean;
61+
/**
62+
* `true` if the "Join album" option is enabled for this public link.
63+
* When `false`, the "Join album and like/comment" buttons will be hidden.
64+
*/
65+
enableJoin?: boolean;
6166
}
6267

6368
export const TripLayout: React.FC<TripLayoutProps> = ({
@@ -73,6 +78,7 @@ export const TripLayout: React.FC<TripLayoutProps> = ({
7378
collectionKey,
7479
credentials,
7580
enableComment = true,
81+
enableJoin = true,
7682
}) => {
7783
// Extract collection info if available
7884
const collectionTitle = collection?.name || albumTitle || "Trip";
@@ -595,6 +601,7 @@ export const TripLayout: React.FC<TripLayoutProps> = ({
595601
collectionKey={collectionKey}
596602
onJoinAlbum={handleJoinAlbum}
597603
enableComment={enableComment}
604+
enableJoin={enableJoin}
598605
/>
599606

600607
{/* Download progress notifications */}

0 commit comments

Comments
 (0)