Resize modal to show content appropriately

Change-type: patch
Changelog-entry: Resize modal to show content appropriately
Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzothunder.ambrosi@gmail.com>
This commit is contained in:
Lorenzo Alberto Maria Ambrosi 2020-07-02 17:03:26 +02:00
parent 5c5273bd6c
commit 630f6c691c
5 changed files with 78 additions and 75 deletions

View File

@ -120,10 +120,6 @@ export function SettingsModal({ toggleModal }: SettingsModalProps) {
</Txt>
}
done={() => toggleModal(false)}
style={{
width: 780,
height: 420,
}}
>
<Flex flexDirection="column">
{_.map(settingsList, (setting: Setting, i: number) => {

View File

@ -52,6 +52,7 @@ import {
Modal,
StepButton,
StepNameButton,
ScrollableFlex,
} from '../../styled-components';
import { colors } from '../../theme';
import { middleEllipsis } from '../../utils/middle-ellipsis';
@ -61,19 +62,24 @@ import ImageSvg from '../../../assets/image.svg';
const recentUrlImagesKey = 'recentUrlImages';
function normalizeRecentUrlImages(urls: any): string[] {
function normalizeRecentUrlImages(urls: any[]): URL[] {
if (!Array.isArray(urls)) {
urls = [];
}
return _.chain(urls)
.filter(_.isString)
.reject(_.isEmpty)
.uniq()
.takeRight(5)
.value();
urls = urls
.map((url) => {
try {
return new URL(url);
} catch (error) {
// Invalid URL, skip
}
})
.filter((url) => url !== undefined);
urls = _.uniqBy(urls, (url) => url.href);
return urls.slice(urls.length - 5);
}
function getRecentUrlImages(): string[] {
function getRecentUrlImages(): URL[] {
let urls = [];
try {
urls = JSON.parse(localStorage.getItem(recentUrlImagesKey) || '[]');
@ -83,11 +89,9 @@ function getRecentUrlImages(): string[] {
return normalizeRecentUrlImages(urls);
}
function setRecentUrlImages(urls: string[]) {
localStorage.setItem(
recentUrlImagesKey,
JSON.stringify(normalizeRecentUrlImages(urls)),
);
function setRecentUrlImages(urls: URL[]) {
const normalized = normalizeRecentUrlImages(urls.map((url: URL) => url.href));
localStorage.setItem(recentUrlImagesKey, JSON.stringify(normalized));
}
const Card = styled(BaseCard)`
@ -124,13 +128,13 @@ const URLSelector = ({
}) => {
const [imageURL, setImageURL] = React.useState('');
const [recentImages, setRecentImages]: [
string[],
(value: React.SetStateAction<string[]>) => void,
URL[],
(value: React.SetStateAction<URL[]>) => void,
] = React.useState([]);
const [loading, setLoading] = React.useState(false);
React.useEffect(() => {
const fetchRecentUrlImages = async () => {
const recentUrlImages: string[] = await getRecentUrlImages();
const recentUrlImages: URL[] = await getRecentUrlImages();
setRecentImages(recentUrlImages);
};
fetchRecentUrlImages();
@ -139,15 +143,16 @@ const URLSelector = ({
<Modal
cancel={cancel}
primaryButtonProps={{
disabled: loading || !imageURL,
className: loading || !imageURL ? 'disabled' : '',
}}
done={async () => {
setLoading(true);
const sanitizedRecentUrls = normalizeRecentUrlImages([
...recentImages,
const urlStrings = recentImages.map((url: URL) => url.href);
const normalizedRecentUrls = normalizeRecentUrlImages([
...urlStrings,
imageURL,
]);
setRecentUrlImages(sanitizedRecentUrls);
setRecentUrlImages(normalizedRecentUrls);
await done(imageURL);
}}
>
@ -164,24 +169,29 @@ const URLSelector = ({
}
/>
</Flex>
{!_.isEmpty(recentImages) && (
<Flex flexDirection="column">
{recentImages.length > 0 && (
<Flex flexDirection="column" height="78.6%">
<Txt fontSize={18}>Recent</Txt>
<Card
style={{ padding: '10px 15px' }}
rows={_.map(recentImages, (recent) => (
<Txt
key={recent}
onClick={() => {
setImageURL(recent);
}}
>
<span>
{_.last(_.split(recent, '/'))} - {recent}
</span>
</Txt>
))}
/>
<ScrollableFlex flexDirection="column">
<Card
p="10px 15px"
rows={recentImages
.map((recent) => (
<Txt
key={recent.href}
onClick={() => {
setImageURL(recent.href);
}}
style={{
overflowWrap: 'break-word',
}}
>
{recent.pathname.split('/').pop()} - {recent.href}
</Txt>
))
.reverse()}
/>
</ScrollableFlex>
</Flex>
)}
</Modal>
@ -280,7 +290,7 @@ export class SourceSelector extends React.Component<
private async onSelectImage(_event: IpcRendererEvent, imagePath: string) {
const isURL =
_.startsWith(imagePath, 'https://') || _.startsWith(imagePath, 'http://');
imagePath.startsWith('https://') || imagePath.startsWith('http://');
await this.selectImageByPath({
imagePath,
SourceType: isURL ? sourceDestination.Http : sourceDestination.File,
@ -354,8 +364,8 @@ export class SourceSelector extends React.Component<
});
} else {
if (
!_.startsWith(imagePath, 'https://') &&
!_.startsWith(imagePath, 'http://')
!imagePath.startsWith('https://') &&
!imagePath.startsWith('http://')
) {
const invalidImageError = errors.createUserError({
title: 'Unsupported protocol',

View File

@ -50,7 +50,7 @@ import {
import { store } from '../../models/store';
import { logEvent, logException } from '../../modules/analytics';
import { open as openExternal } from '../../os/open-external/services/open-external';
import { Modal } from '../../styled-components';
import { Modal, ScrollableFlex } from '../../styled-components';
import TargetSVGIcon from '../../../assets/tgt.svg';
@ -83,19 +83,6 @@ function isDrivelistDrive(
return typeof (drive as scanner.adapters.DrivelistDrive).size === 'number';
}
const ScrollableFlex = styled(Flex)`
overflow: auto;
::-webkit-scrollbar {
display: none;
}
> div > div {
/* This is required for the sticky table header in TargetsTable */
overflow-x: visible;
}
`;
const TargetsTable = styled(({ refFn, ...props }) => {
return (
<div>
@ -376,10 +363,6 @@ export class TargetSelectorModal extends React.Component<
cancel={cancel}
done={() => done(selectedList)}
action={`Select (${selectedList.length})`}
style={{
width: '780px',
height: '420px',
}}
primaryButtonProps={{
primary: !hasStatus,
warning: hasStatus,
@ -387,7 +370,7 @@ export class TargetSelectorModal extends React.Component<
}}
{...props}
>
<Flex width="100%" height="100%">
<Flex width="100%" height="90%">
{!hasAvailableDrives() ? (
<Flex
flexDirection="column"
@ -399,11 +382,7 @@ export class TargetSelectorModal extends React.Component<
<b>Plug a target drive</b>
</Flex>
) : (
<ScrollableFlex
flexDirection="column"
width="100%"
height="calc(100% - 15px)"
>
<ScrollableFlex flexDirection="column" width="100%">
<TargetsTable
refFn={(t: Table<Target>) => {
if (t !== null) {

View File

@ -63,5 +63,5 @@ button:focus,
}
.disabled {
opacity: 0.2;
opacity: 0.4;
}

View File

@ -121,8 +121,7 @@ export const DetailsText = (props: FlexProps) => (
/>
);
export const Modal = styled((props) => {
const { style = { height: 420 } } = props;
export const Modal = styled(({ style, ...props }) => {
return (
<Provider
theme={{
@ -143,23 +142,29 @@ export const Modal = styled((props) => {
>
<ModalBase
position="top"
width={780}
width="96vw"
cancelButtonProps={{
style: {
marginRight: '20px',
border: 'solid 1px #2a506f',
},
}}
style={style}
style={{
height: '86.5vh',
...style,
}}
{...props}
/>
</Provider>
);
})`
> div {
padding: 30px;
padding: 24px 30px;
height: calc(100% - 80px);
overflow-y: auto;
::-webkit-scrollbar {
display: none;
}
> h3 {
margin: 0;
@ -178,3 +183,16 @@ export const Modal = styled((props) => {
}
}
`;
export const ScrollableFlex = styled(Flex)`
overflow: auto;
::-webkit-scrollbar {
display: none;
}
> div > div {
/* This is required for the sticky table header in TargetsTable */
overflow-x: visible;
}
`;