Skip to content

Commit 82811e1

Browse files
committed
tab preview final
1 parent ac0c450 commit 82811e1

File tree

3 files changed

+113
-67
lines changed

3 files changed

+113
-67
lines changed

src/pages/Content/index.jsx

Lines changed: 57 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -369,14 +369,23 @@ let tabPreviewFrameRoot = document.createElement('div');
369369
document.body.appendChild(tabPreviewFrameRoot);
370370
tabPreviewFrameRoot.setAttribute('id', 'tab-preview-frame-root');
371371

372-
tabPreviewFrameRoot.style.zIndex = '-100';
373-
tabPreviewFrameRoot.style.visibility = 'hidden';
374372
tabPreviewFrameRoot.style.transition = 'all ease-in-out 0.1s';
375373
tabPreviewFrameRoot.style.position = 'fixed';
376-
tabPreviewFrameRoot.style.top = null;
377-
tabPreviewFrameRoot.style.left = null;
378-
tabPreviewFrameRoot.style.bottom = null;
379-
tabPreviewFrameRoot.style.right = null;
374+
375+
const hideTabPreviewFramePosition = () => {
376+
tabPreviewFrameRoot.style.zIndex = '-100';
377+
tabPreviewFrameRoot.style.visibility = 'hidden';
378+
};
379+
380+
const resetTabPreviewFramePosition = () => {
381+
tabPreviewFrameRoot.style.top = null;
382+
tabPreviewFrameRoot.style.left = null;
383+
tabPreviewFrameRoot.style.bottom = null;
384+
tabPreviewFrameRoot.style.right = null;
385+
};
386+
387+
hideTabPreviewFramePosition();
388+
resetTabPreviewFramePosition();
380389

381390
let unmountTabPreviewFrameTimeout;
382391

@@ -385,59 +394,58 @@ window.addEventListener('message', (event) => {
385394
if (msg === 'COPY_URL') {
386395
copy(payload.url);
387396
} else if (msg === 'PREVIEW_TAB_ON') {
388-
const { id, title, url, faviconUrl, tabItemY, isDark } = payload;
389-
// console.log(id, title, url, faviconUrl, tabItemY,isDark);
397+
const { title, url, faviconUrl, tabItemY, isDark } = payload;
398+
// console.log(title, url, faviconUrl, tabItemY, isDark);
390399

391400
if (unmountTabPreviewFrameTimeout) {
392401
clearTimeout(unmountTabPreviewFrameTimeout);
393402
}
394403

395-
ReactDOM.render(
396-
<TabPreviewFrame
397-
id={id}
398-
title={title}
399-
url={url}
400-
faviconUrl={faviconUrl}
401-
isDark={isDark}
402-
/>,
403-
tabPreviewFrameRoot
404-
);
405-
tabPreviewFrameRoot.style.zIndex = '999999999';
406-
tabPreviewFrameRoot.style.visibility = 'visible';
407-
408-
const sidebarIframe = sidebarRoot.querySelector('iframe');
409-
const {
410-
left: iframeLeft,
411-
width: iframeWidth,
412-
right: iframeRight,
413-
} = sidebarIframe.getBoundingClientRect();
414-
415-
let top = tabItemY;
416-
let previewFrameHeight = tabPreviewFrameRoot
417-
.querySelector('.TabPreviewContainer')
418-
.getBoundingClientRect().height;
419-
if (top + previewFrameHeight >= window.innerHeight) {
420-
top = window.innerHeight - previewFrameHeight - 5;
421-
}
422-
423-
tabPreviewFrameRoot.style.top = `${Math.floor(top)}px`;
404+
try {
405+
ReactDOM.render(
406+
<TabPreviewFrame
407+
title={title}
408+
url={url}
409+
faviconUrl={faviconUrl}
410+
isDark={isDark}
411+
/>,
412+
tabPreviewFrameRoot
413+
);
414+
tabPreviewFrameRoot.style.zIndex = '999999999';
415+
tabPreviewFrameRoot.style.visibility = 'visible';
416+
417+
const sidebarIframe = sidebarRoot.querySelector('iframe');
418+
const {
419+
left: iframeLeft,
420+
width: iframeWidth,
421+
right: iframeRight,
422+
} = sidebarIframe.getBoundingClientRect();
423+
424+
let top = tabItemY;
425+
let previewFrameHeight = tabPreviewFrameRoot
426+
.querySelector('.TabPreviewContainer')
427+
.getBoundingClientRect().height;
428+
if (top + previewFrameHeight >= window.innerHeight) {
429+
top = window.innerHeight - previewFrameHeight - 5;
430+
}
431+
tabPreviewFrameRoot.style.top = `${Math.floor(top)}px`;
424432

425-
const isIframeOnLeft = iframeLeft === 0;
426-
if (isIframeOnLeft) {
427-
tabPreviewFrameRoot.style.left = `${Math.floor(iframeRight) + 3}px`;
428-
} else {
429-
tabPreviewFrameRoot.style.right = `${Math.floor(iframeWidth) + 3}px`;
433+
const isIframeOnLeft = iframeLeft === 0;
434+
if (isIframeOnLeft) {
435+
tabPreviewFrameRoot.style.left = `${Math.floor(iframeRight) + 3}px`;
436+
} else {
437+
tabPreviewFrameRoot.style.right = `${Math.floor(iframeWidth) + 3}px`;
438+
}
439+
} catch (err) {
440+
hideTabPreviewFramePosition();
441+
ReactDOM.unmountComponentAtNode(tabPreviewFrameRoot);
442+
resetTabPreviewFramePosition();
430443
}
431444
} else if (msg === 'PREVIEW_TAB_OFF') {
432-
tabPreviewFrameRoot.style.zIndex = '-100';
433-
tabPreviewFrameRoot.style.visibility = 'hidden';
434-
445+
hideTabPreviewFramePosition();
435446
unmountTabPreviewFrameTimeout = setTimeout(() => {
436447
ReactDOM.unmountComponentAtNode(tabPreviewFrameRoot);
437-
tabPreviewFrameRoot.style.top = null;
438-
tabPreviewFrameRoot.style.left = null;
439-
tabPreviewFrameRoot.style.bottom = null;
440-
tabPreviewFrameRoot.style.right = null;
448+
resetTabPreviewFramePosition();
441449
}, 500);
442450
}
443451
});

src/pages/Content/modules/tabPreviewFrame/tabPreviewFrame.jsx

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
2+
import { AiFillWarning as WarningIcon } from 'react-icons/ai';
23
import { detect } from 'detect-browser';
34
import styled from 'styled-components';
45

56
const Container = styled.div`
67
width: 220px;
7-
max-height: 200px;
88
font-family: sans-serif;
99
font-size: 14px !important;
1010
box-shadow: 0 2px 5px 0 rgb(0 0 0 / 16%), 0 2px 10px 0 rgb(0 0 0 / 12%);
@@ -19,13 +19,11 @@ const Title = styled.div`
1919
2020
border-top-left-radius: 3px;
2121
border-top-right-radius: 3px;
22+
23+
word-wrap: break-word;
2224
`;
2325

2426
const Domain = styled.div`
25-
display: flex;
26-
align-items: center;
27-
justify-content: flex-start;
28-
2927
padding: 8px 10px;
3028
background: ${(props) => (props.isDark ? '#35363A' : 'rgb(222, 225, 230)')};
3129
color: ${(props) => (props.isDark ? 'rgb(167, 167, 167)' : '#444')};
@@ -34,34 +32,74 @@ const Domain = styled.div`
3432
border-bottom-right-radius: 3px;
3533
`;
3634

35+
const DomainNameDisplay = styled.div`
36+
display: flex;
37+
align-items: center;
38+
justify-content: flex-start;
39+
`;
40+
3741
const Favicon = styled.img`
3842
width: 18px;
3943
height: 18px;
4044
margin-right: 6px;
45+
46+
flex-shrink: 0;
4147
`;
4248

43-
const DomainName = styled.div``;
49+
const DomainName = styled.div`
50+
flex: 1;
51+
flex-wrap: nowrap;
52+
overflow-x: hidden;
53+
`;
54+
55+
const NotSecureBadgeContainer = styled.div`
56+
margin-top: 8px;
57+
`;
58+
59+
const NotSecureBadge = styled.div`
60+
display: inline-flex;
61+
align-items: center;
62+
justify-content: flex-start;
63+
64+
padding: 2px 6px;
65+
66+
border-radius: 50rem !important;
67+
font-size: 12px;
68+
background: #dc3545;
69+
color: #fff;
70+
font-weight: 500;
71+
`;
4472

4573
const browserInfo = detect();
4674

47-
const TabPreviewFrame = ({ id, title, url, faviconUrl, isDark }) => {
75+
const TabPreviewFrame = ({ title, url, faviconUrl, isDark }) => {
4876
let domain = new URL(url).hostname;
4977

50-
if (domain.toLocaleLowerCase() === 'newtab') {
51-
domain = browserInfo.name + '://newtab';
52-
} else if (domain.trim().length === 0) {
53-
if (url.startsWith('file:')) {
54-
domain = 'local or shared file';
55-
}
78+
if (url.startsWith(browserInfo.name + '://') && !domain.includes('://')) {
79+
domain = browserInfo.name + '://' + domain;
80+
} else if (url.startsWith('file:') && domain.trim().length === 0) {
81+
domain = 'local or shared file';
5682
}
5783

84+
const isNotSecure = url.startsWith('http://');
85+
5886
return (
5987
<Container className="TabPreviewContainer">
6088
<Title isDark={isDark}>{title}</Title>
6189

6290
<Domain isDark={isDark}>
63-
<Favicon src={faviconUrl} />
64-
<DomainName>{domain}</DomainName>
91+
<DomainNameDisplay>
92+
<Favicon src={faviconUrl} />
93+
<DomainName>{domain}</DomainName>
94+
</DomainNameDisplay>
95+
{isNotSecure && (
96+
<NotSecureBadgeContainer>
97+
<NotSecureBadge>
98+
<WarningIcon style={{ fontSize: '14px', marginRight: '5px' }} />
99+
Not Secure
100+
</NotSecureBadge>
101+
</NotSecureBadgeContainer>
102+
)}
65103
</Domain>
66104
</Container>
67105
);

src/pages/Sidebar/containers/TabsList/Tab/Tab.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,21 +170,20 @@ const Tab = ({
170170
};
171171
/* End of --> Utility functions */
172172

173+
/* Start of tab preview support */
173174
const showTabPreview = async () => {
174175
if (!displayTabPreviewFrame) {
175176
return;
176177
}
177178
try {
178179
const tabItemBB = tabItemRef.current.getBoundingClientRect();
179180
const { y: tabItemY } = tabItemBB;
180-
// console.log(tabItemY, url, title);
181-
// console.log(faviconUrl);
181+
// console.log(tabItemY, url, title, faviconUrl);
182182
let faviconDataUrl = await fetchFavicon(faviconUrl);
183183
window.parent.postMessage(
184184
{
185185
msg: 'PREVIEW_TAB_ON',
186186
payload: {
187-
id,
188187
title,
189188
url,
190189
faviconUrl: faviconDataUrl,
@@ -210,6 +209,7 @@ const Tab = ({
210209
'*'
211210
);
212211
};
212+
/* End of tab preview support */
213213

214214
return (
215215
<ReactHoverObserver>

0 commit comments

Comments
 (0)