Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9178ac4

Browse files
authoredFeb 12, 2025··
Merge pull request #477 from nyaruka/thumbnail-zooms
Respect aspect ratio on thumbnails
2 parents f914892 + 6d54f7e commit 9178ac4

File tree

6 files changed

+87
-30
lines changed

6 files changed

+87
-30
lines changed
 

Diff for: ‎demo/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
</head>
128128

129129
<body>
130-
<temba-webchat channel="5ea6f54b-96b0-4e0f-aa00-c6cccc588a55"></temba-webchat>
130+
<temba-webchat channel="967cd415-8616-4b11-b38f-60f70e0999f4"></temba-webchat>
131131
<temba-store completion="/static/api/completion.json" functions="/static/api/functions.json"
132132
fields="/static/api/fields.json" globals="/static/api/globals.json" groups="/static/api/groups.json"></temba-store>
133133

1.47 KB
Loading

Diff for: ‎screenshots/truth/lightbox/img-zoomed.png

96 Bytes
Loading

Diff for: ‎src/lightbox/Lightbox.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ export class Lightbox extends RapidElement {
4141
overflow: hidden;
4242
box-shadow: 0 0 12px 3px rgba(0, 0, 0, 0.15);
4343
}
44+
45+
.download {
46+
background: rgba(0, 0, 0, 0.5);
47+
position: absolute;
48+
display:flex;
49+
align-items:center;
50+
color:#fff;
51+
padding:0.5em;
52+
border-radius:var(--curvature);
53+
background:rgba(0,0,0,0.5);
54+
}
55+
56+
}
4457
`;
4558
}
4659

@@ -62,8 +75,8 @@ export class Lightbox extends RapidElement {
6275
private height: number;
6376
private width: number;
6477
private scale = 1;
65-
private xTrans = '0px';
66-
private yTrans = '0px';
78+
private xTrans = 0;
79+
private yTrans = 0;
6780

6881
protected updated(
6982
changed: PropertyValueMap<any> | Map<PropertyKey, unknown>
@@ -92,8 +105,8 @@ export class Lightbox extends RapidElement {
92105
this.width = bounds.width;
93106
this.height = bounds.height;
94107

95-
this.xTrans = '0px';
96-
this.yTrans = '0px';
108+
this.xTrans = 0;
109+
this.yTrans = 0;
97110
this.scale = 1;
98111

99112
let desiredWidth = this.width;
@@ -116,11 +129,11 @@ export class Lightbox extends RapidElement {
116129

117130
const xGrowth = (desiredWidth - this.width) / 2;
118131
const xDest = (window.innerWidth - desiredWidth) / 2;
119-
this.xTrans = xDest - this.left + xGrowth + 'px';
132+
this.xTrans = xDest - this.left + xGrowth;
120133

121134
const yGrowth = (desiredHeight - this.height) / 2;
122135
const yDest = (window.innerHeight - desiredHeight) / 2;
123-
this.yTrans = yDest - this.top + yGrowth + 'px';
136+
this.yTrans = yDest - this.top + yGrowth;
124137

125138
this.scale = desiredScale;
126139
this.show = true;
@@ -139,13 +152,12 @@ export class Lightbox extends RapidElement {
139152
styles['left'] = this.left + 'px';
140153
styles['top'] = this.top + 'px';
141154
styles['width'] = this.width + 'px';
142-
styles['height'] = this.height + 'px';
143155
}
144156

145157
if (this.zoom) {
146158
styles[
147159
'transform'
148-
] = `translate(${this.xTrans}, ${this.yTrans}) scale(${this.scale}, ${this.scale})`;
160+
] = `translate(${this.xTrans}px, ${this.yTrans}px) scale(${this.scale}, ${this.scale})`;
149161
}
150162

151163
return html`
@@ -162,7 +174,7 @@ export class Lightbox extends RapidElement {
162174
style="transition: all ${this.animationTime}ms; ease"
163175
></div>
164176
<div class=${getClasses({ matte: true })} style=${styleMap(styles)}>
165-
${this.show ? this.ele : null}
177+
${this.show ? html`${this.ele}` : null}
166178
</div>
167179
</div>
168180
`;

Diff for: ‎src/mediapicker/MediaPicker.ts

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export class MediaPicker extends RapidElement {
4747
flex-direction: row;
4848
flex-wrap: wrap;
4949
padding: 0.2em;
50+
align-items: center;
5051
}
5152
5253
.attachment-item {

Diff for: ‎src/thumbnail/Thumbnail.ts

+64-20
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { RapidElement } from '../RapidElement';
33
import { property } from 'lit/decorators.js';
44
import { getClasses } from '../utils';
55
import { Lightbox } from '../lightbox/Lightbox';
6-
import { styleMap } from 'lit-html/directives/style-map.js';
76
import { WebChatIcon } from '../webchat';
87

98
enum ThumbnailContentType {
@@ -48,17 +47,15 @@ export class Thumbnail extends RapidElement {
4847
.zoom .thumb {
4948
border-radius: 0px !important;
5049
width: calc(var(--thumb-size, 4em) + 0.8em);
51-
height: calc(var(--thumb-size, 4em) + 0.8em);
52-
max-height: calc(var(--thumb-size, 4em) + 0.8em);
50+
max-height: calc(90vh - 10em);
5351
}
5452
5553
.thumb {
5654
background-size: cover;
5755
background-position: center;
5856
background-repeat: no-repeat;
5957
border-radius: var(--curvature);
60-
max-height: var(--thumb-size, 4em);
61-
height: var(--thumb-size, 4em);
58+
max-height: calc(var(--thumb-size, 4em) * 2);
6259
width: var(--thumb-size, 4em);
6360
display: flex;
6461
align-items: center;
@@ -84,8 +81,24 @@ export class Thumbnail extends RapidElement {
8481
display: block;
8582
}
8683
87-
.zoom temba-icon {
84+
.download {
8885
display: none;
86+
position: absolute;
87+
right: 0em;
88+
bottom: 0em;
89+
border-radius: var(--curvature);
90+
transform: scale(0.2) translate(3em, 3em);
91+
padding: 0.4em;
92+
}
93+
94+
.zoom .download {
95+
display: block;
96+
background: rgba(0, 0, 0, 0.5);
97+
}
98+
99+
.zoom .download:hover {
100+
background: rgba(0, 0, 0, 0.6);
101+
cursor: pointer;
89102
}
90103
`;
91104
}
@@ -96,6 +109,12 @@ export class Thumbnail extends RapidElement {
96109
@property({ type: String })
97110
attachment: string;
98111

112+
@property({ type: Number })
113+
ratio: number = 0;
114+
115+
@property({ type: Boolean })
116+
preview: boolean = true;
117+
99118
@property({ type: Boolean, attribute: false })
100119
zoom: boolean;
101120

@@ -107,6 +126,23 @@ export class Thumbnail extends RapidElement {
107126
): void {
108127
super.updated(changes);
109128

129+
if (
130+
changes.has('contentType') &&
131+
this.contentType === ThumbnailContentType.IMAGE
132+
) {
133+
const toObserve = this.shadowRoot.querySelector('.observe');
134+
if (toObserve) {
135+
new ResizeObserver((e, observer) => {
136+
if (toObserve.clientHeight > 0 && toObserve.clientWidth > 0) {
137+
this.ratio = toObserve.clientHeight / toObserve.clientWidth;
138+
this.preview =
139+
this.ratio === 0 || (this.ratio > 0.25 && this.ratio <= 1.5);
140+
observer.disconnect();
141+
}
142+
}).observe(toObserve);
143+
}
144+
}
145+
110146
// convert our attachment to a url and label
111147
if (changes.has('attachment')) {
112148
if (this.attachment) {
@@ -134,7 +170,7 @@ export class Thumbnail extends RapidElement {
134170
}
135171

136172
public handleThumbnailClicked() {
137-
if (this.contentType === ThumbnailContentType.IMAGE) {
173+
if (this.contentType === ThumbnailContentType.IMAGE && this.preview) {
138174
window.setTimeout(() => {
139175
const lightbox = document.querySelector('temba-lightbox') as Lightbox;
140176
lightbox.showElement(this);
@@ -144,28 +180,36 @@ export class Thumbnail extends RapidElement {
144180
}
145181
}
146182

183+
public handleDownload(e: Event) {
184+
e.stopPropagation();
185+
e.preventDefault();
186+
187+
// open this.url in another tab
188+
window.open(this.url, '_blank');
189+
}
190+
147191
public render() {
148192
return html`
149193
<div
150194
@click=${this.handleThumbnailClicked.bind(this)}
151195
class="${getClasses({ wrapper: true, zoom: this.zoom })}"
152196
url=${this.url}
153197
>
154-
<div
155-
class="thumb ${this.contentType} "
156-
style="${this.url
157-
? styleMap({
158-
backgroundImage: `url(${this.url})`
159-
})
160-
: ''}"
161-
>
162-
${this.contentType !== ThumbnailContentType.IMAGE
163-
? html`<temba-icon
198+
${this.contentType === ThumbnailContentType.IMAGE && this.preview
199+
? html`<div class=""><div class="download" @click=${this.handleDownload.bind(
200+
this
201+
)}><temba-icon size="1" style="color:#fff;" name="download"></temba-icon></div><img
202+
class="observe thumb ${this.contentType}"
203+
src="${this.url}"
204+
></img></div>`
205+
: html`<div
206+
style="padding:1em; background:rgba(0,0,0,.05);border-radius:var(--curvature);"
207+
>
208+
<temba-icon
164209
size="1.5"
165210
name="${ThumbnailIcons[this.contentType]}"
166-
></temba-icon>`
167-
: null}
168-
</div>
211+
></temba-icon>
212+
</div>`}
169213
</div>
170214
`;
171215
}

0 commit comments

Comments
 (0)
Please sign in to comment.