Skip to content

Commit 4e9c349

Browse files
authored
Feat - Separate embed settings and add multiple embeds (#667)
<!-- Please read https://github.com/SableClient/Sable/blob/dev/CONTRIBUTING.md before submitting your pull request --> ### Description <!-- Please include a summary of the change. Please also include relevant motivation and context. List any dependencies that are required for this change. --> This PR proposes the moving of embed settings to their own category under General: <img width="810" height="694" alt="image" src="https://github.com/user-attachments/assets/972eec7b-1517-4c76-991c-c652cea6a3ab" /> Additionally it adds multiple embeds in one message: <img width="1321" height="480" alt="image" src="https://github.com/user-attachments/assets/59a6da99-e7a1-4740-a9d8-29b37a2ef8dc" /> Showing them all is however just a setting that may be turned off (it is on by default) since the embeds respect the aspect ratio of the thumbnail so a list of embeds may be uneven which might appear unaesthetic to some, as per this example: <img width="1294" height="751" alt="image" src="https://github.com/user-attachments/assets/6b0b47ad-c6e7-427f-baea-0ecd4ba84527" /> Fixes # #### Type of change - [x] Bug fix (non-breaking change which fixes an issue) ### Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### AI disclosure: - [ ] Partially AI assisted (clarify which code was AI assisted and briefly explain what it does). - [ ] Fully AI generated (explain what all the generated code does in moderate detail). <!-- Write any explanation required here, but do not generate the explanation using AI!! You must prove you understand what the code in this PR does. --> My pathological avoiding anxiety has empowered me to create this instead of doing a more important task.
2 parents d85c940 + 2361dd5 commit 4e9c349

7 files changed

Lines changed: 168 additions & 119 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
default: minor
3+
---
4+
5+
Reorganize Embed settings and reintroduce multiple embeds

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ build.sh
2323

2424
# the following line was added with the "git ignore" tool by itsrye.dev, version 0.1.0
2525
.lh
26+
27+
# the following line was added with nvim by Shea because its annoying to clear every so often
28+
.vscode/bookmarks.json

src/app/components/RenderMessageContent.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ function RenderMessageContentInternal({
8484

8585
const [autoplayGifs] = useSetting(settingsAtom, 'autoplayGifs');
8686
const [captionPosition] = useSetting(settingsAtom, 'captionPosition');
87+
const [multiplePreviews] = useSetting(settingsAtom, 'multiplePreviews');
8788
const settingsLinkBaseUrl = useSettingsLinkBaseUrl();
8889
const captionPositionMap = {
8990
[CaptionPosition.Above]: 'column-reverse',
@@ -117,8 +118,7 @@ function RenderMessageContentInternal({
117118
type: getMediaType(url),
118119
}));
119120

120-
const mediaLinks = analyzed.filter((item) => item.type !== null);
121-
const toRender = mediaLinks.length > 0 ? mediaLinks : [analyzed[0]];
121+
const toRender = multiplePreviews ? analyzed : [analyzed[0]];
122122
return (
123123
<UrlPreviewHolder>
124124
{toRender.map(({ url, type }) => {
@@ -136,7 +136,7 @@ function RenderMessageContentInternal({
136136
</UrlPreviewHolder>
137137
);
138138
},
139-
[ts, clientUrlPreview, settingsLinkBaseUrl, urlPreview]
139+
[multiplePreviews, settingsLinkBaseUrl, clientUrlPreview, urlPreview, ts]
140140
);
141141
const renderBundledPreviews = useCallback(
142142
(bundles: IPreviewUrlResponse[]) => (

src/app/components/message/content/ImageContent.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ export const ImageContent = as<'div', ImageContentProps>(
197197
hasDimensions ? css.AbsoluteContainer : undefined,
198198
blurred && css.Blur
199199
)}
200+
style={{ width: '100%' }}
200201
>
201202
{renderImage({
202203
alt: body,

src/app/components/url-preview/UrlPreviewCard.tsx

Lines changed: 72 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ export const UrlPreviewCard = as<
108108
}
109109
};
110110

111+
const ogW = ((prev['og:video'] && prev['og:video:width']) ||
112+
(prev['og:image'] && prev['og:image:width']) ||
113+
1) as number;
114+
const ogH = ((prev['og:video'] && prev['og:video:height']) ||
115+
(prev['og:image'] && prev['og:image:height']) ||
116+
1) as number;
117+
118+
const aspectRatio = ogW && ogH ? `${ogW} / ${ogH}` : undefined;
119+
111120
return (
112121
<Box
113122
grow="Yes"
@@ -153,9 +162,7 @@ export const UrlPreviewCard = as<
153162
<VideoContent
154163
style={{
155164
width: '100%',
156-
aspectRatio:
157-
((prev['og:video:width'] as number) ?? 1) /
158-
((prev['og:video:height'] as number) ?? 1),
165+
aspectRatio: aspectRatio ?? '10 / 9',
159166
}}
160167
body={prev['og:title']}
161168
info={{}}
@@ -167,43 +174,44 @@ export const UrlPreviewCard = as<
167174
)}
168175
{!prev['og:video'] &&
169176
prev['og:image'] &&
170-
(() => {
171-
const ogW = prev['og:image:width'];
172-
const ogH = prev['og:image:height'];
173-
const aspectRatio = ogW && ogH ? `${ogW} / ${ogH}` : undefined;
174-
return (
175-
<Box
177+
(() => (
178+
<Box
179+
style={{
180+
width: '100%',
181+
maxHeight: '320px',
182+
aspectRatio: aspectRatio ?? '16 / 9',
183+
flexShrink: 1,
184+
overflow: 'hidden',
185+
position: 'relative',
186+
}}
187+
>
188+
<ImageContent
176189
style={{
177190
width: '100%',
178-
maxHeight: '400px',
179-
aspectRatio: aspectRatio ?? '16 / 9',
180-
flexShrink: 0,
181-
overflow: 'hidden',
182-
position: 'relative',
191+
height: '100%',
192+
position: 'absolute',
193+
inset: 0,
194+
minHeight: 0,
183195
}}
184-
>
185-
<ImageContent
186-
style={{ width: '100%', height: '100%', position: 'absolute', inset: 0 }}
187-
autoPlay
188-
onAuxClick={handleAuxClick}
189-
body={prev['og:title']}
190-
url={prev['og:image']}
191-
renderViewer={(p) => <ImageViewer {...p} />}
192-
renderImage={(p) => (
193-
<Image
194-
{...p}
195-
style={{
196-
width: '100%',
197-
height: '100%',
198-
objectFit: 'contain',
199-
objectPosition: 'center',
200-
}}
201-
/>
202-
)}
203-
/>
204-
</Box>
205-
);
206-
})()}
196+
autoPlay
197+
onAuxClick={handleAuxClick}
198+
body={prev['og:title']}
199+
url={prev['og:image']}
200+
renderViewer={(p) => <ImageViewer {...p} />}
201+
renderImage={(p) => (
202+
<Image
203+
{...p}
204+
style={{
205+
width: '100%',
206+
height: '100%',
207+
objectFit: 'contain',
208+
objectPosition: 'center',
209+
}}
210+
/>
211+
)}
212+
/>
213+
</Box>
214+
))()}
207215
{!prev['og:video'] && !prev['og:image'] && prev['og:audio'] && (
208216
<Box className={css.UrlPreviewAudio} style={{ flexShrink: 0 }}>
209217
<AudioContent
@@ -262,8 +270,11 @@ export const UrlPreviewCard = as<
262270
minWidth: 0,
263271
maxWidth: '100%',
264272
margin: 0,
273+
alignSelf: 'start',
274+
}
275+
: {
276+
alignSelf: 'start',
265277
}
266-
: undefined
267278
}
268279
>
269280
{previewContent}
@@ -345,24 +356,31 @@ export const UrlPreviewHolder = as<'div'>(({ children, ...props }, ref) => {
345356
</IconButton>
346357
</>
347358
)}
348-
<Box ref={innerBoxRef} alignItems="Inherit" gap="200">
359+
<Box
360+
ref={innerBoxRef}
361+
alignItems="Inherit"
362+
gap="200"
363+
style={{
364+
alignItems: 'baseline',
365+
}}
366+
>
349367
{children}
350-
{canScrollRight && (
351-
<>
352-
<div className={css.UrlPreviewHolderGradient({ position: 'Right' })} />
353-
<IconButton
354-
className={css.UrlPreviewHolderBtn({ position: 'Right' })}
355-
variant="Primary"
356-
radii="Pill"
357-
size="300"
358-
outlined
359-
onClick={handleScrollFront}
360-
>
361-
<Icon size="300" src={Icons.ArrowRight} />
362-
</IconButton>
363-
</>
364-
)}
365368
</Box>
369+
{canScrollRight && (
370+
<>
371+
<div className={css.UrlPreviewHolderGradient({ position: 'Right' })} />
372+
<IconButton
373+
className={css.UrlPreviewHolderBtn({ position: 'Right' })}
374+
variant="Primary"
375+
radii="Pill"
376+
size="300"
377+
outlined
378+
onClick={handleScrollFront}
379+
>
380+
<Icon size="300" src={Icons.ArrowRight} />
381+
</IconButton>
382+
</>
383+
)}
366384
</Box>
367385
</Scroll>
368386
</Box>

0 commit comments

Comments
 (0)