Skip to content

Commit e9e2c30

Browse files
committed
Replace Context with shared functions
1 parent d1337d2 commit e9e2c30

File tree

2 files changed

+81
-89
lines changed

2 files changed

+81
-89
lines changed

src/client/lazy-app/Compress/index.tsx

Lines changed: 46 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ import WorkerBridge from '../worker-bridge';
3232
import { resize } from 'features/processors/resize/client';
3333
import type SnackBarElement from 'shared/custom-els/snack-bar';
3434
import { drawableToImageData } from '../util/canvas';
35-
import Modal, { ModalMessage } from '../Modal';
36-
import ModalContext from '../Modal/modal-context';
37-
import { linkRef } from 'shared/prerendered-app/util';
35+
import Modal from '../Modal';
3836

3937
export type OutputType = EncoderType | 'identity';
4038

@@ -327,8 +325,6 @@ export default class Compress extends Component<Props, State> {
327325
/** For debouncing calls to updateImage for each side. */
328326
private updateImageTimeout?: number;
329327

330-
private modal?: Modal;
331-
332328
constructor(props: Props) {
333329
super(props);
334330
this.widthQuery.addListener(this.onMobileWidthChange);
@@ -920,12 +916,6 @@ export default class Compress extends Component<Props, State> {
920916
});
921917
}
922918

923-
private showModal(modalMessage: ModalMessage) {
924-
if (!this.modal) return;
925-
926-
this.modal.showModal(modalMessage);
927-
}
928-
929919
render(
930920
{ onBack }: Props,
931921
{ loading, sides, source, mobileView, preprocessorState }: State,
@@ -979,55 +969,51 @@ export default class Compress extends Component<Props, State> {
979969

980970
return (
981971
<div class={style.compress}>
982-
<ModalContext.Provider
983-
value={(message: ModalMessage) => this.showModal(message)}
984-
>
985-
<Output
986-
source={source}
987-
mobileView={mobileView}
988-
leftCompressed={leftImageData}
989-
rightCompressed={rightImageData}
990-
leftImgContain={leftImgContain}
991-
rightImgContain={rightImgContain}
992-
preprocessorState={preprocessorState}
993-
onPreprocessorChange={this.onPreprocessorChange}
994-
/>
995-
<button class={style.back} onClick={onBack}>
996-
<svg viewBox="0 0 61 53.3">
997-
<title>Back</title>
998-
<path
999-
class={style.backBlob}
1000-
d="M0 25.6c-.5-7.1 4.1-14.5 10-19.1S23.4.1 32.2 0c8.8 0 19 1.6 24.4 8s5.6 17.8 1.7 27a29.7 29.7 0 01-20.5 18c-8.4 1.5-17.3-2.6-24.5-8S.5 32.6.1 25.6z"
1001-
/>
1002-
<path
1003-
class={style.backX}
1004-
d="M41.6 17.1l-2-2.1-8.3 8.2-8.2-8.2-2 2 8.2 8.3-8.3 8.2 2.1 2 8.2-8.1 8.3 8.2 2-2-8.2-8.3z"
1005-
/>
1006-
</svg>
1007-
</button>
1008-
{mobileView ? (
1009-
<div class={style.options}>
1010-
<multi-panel class={style.multiPanel} open-one-only>
1011-
<div class={style.options1Theme}>{results[0]}</div>
1012-
<div class={style.options1Theme}>{options[0]}</div>
1013-
<div class={style.options2Theme}>{results[1]}</div>
1014-
<div class={style.options2Theme}>{options[1]}</div>
1015-
</multi-panel>
1016-
</div>
1017-
) : (
1018-
[
1019-
<div class={style.options1} key="options1">
1020-
{options[0]}
1021-
{results[0]}
1022-
</div>,
1023-
<div class={style.options2} key="options2">
1024-
{options[1]}
1025-
{results[1]}
1026-
</div>,
1027-
]
1028-
)}
1029-
</ModalContext.Provider>
1030-
<Modal ref={linkRef(this, 'modal')}></Modal>
972+
<Output
973+
source={source}
974+
mobileView={mobileView}
975+
leftCompressed={leftImageData}
976+
rightCompressed={rightImageData}
977+
leftImgContain={leftImgContain}
978+
rightImgContain={rightImgContain}
979+
preprocessorState={preprocessorState}
980+
onPreprocessorChange={this.onPreprocessorChange}
981+
/>
982+
<button class={style.back} onClick={onBack}>
983+
<svg viewBox="0 0 61 53.3">
984+
<title>Back</title>
985+
<path
986+
class={style.backBlob}
987+
d="M0 25.6c-.5-7.1 4.1-14.5 10-19.1S23.4.1 32.2 0c8.8 0 19 1.6 24.4 8s5.6 17.8 1.7 27a29.7 29.7 0 01-20.5 18c-8.4 1.5-17.3-2.6-24.5-8S.5 32.6.1 25.6z"
988+
/>
989+
<path
990+
class={style.backX}
991+
d="M41.6 17.1l-2-2.1-8.3 8.2-8.2-8.2-2 2 8.2 8.3-8.3 8.2 2.1 2 8.2-8.1 8.3 8.2 2-2-8.2-8.3z"
992+
/>
993+
</svg>
994+
</button>
995+
{mobileView ? (
996+
<div class={style.options}>
997+
<multi-panel class={style.multiPanel} open-one-only>
998+
<div class={style.options1Theme}>{results[0]}</div>
999+
<div class={style.options1Theme}>{options[0]}</div>
1000+
<div class={style.options2Theme}>{results[1]}</div>
1001+
<div class={style.options2Theme}>{options[1]}</div>
1002+
</multi-panel>
1003+
</div>
1004+
) : (
1005+
[
1006+
<div class={style.options1} key="options1">
1007+
{options[0]}
1008+
{results[0]}
1009+
</div>,
1010+
<div class={style.options2} key="options2">
1011+
{options[1]}
1012+
{results[1]}
1013+
</div>,
1014+
]
1015+
)}
1016+
<Modal></Modal>
10311017
</div>
10321018
);
10331019
}

src/client/lazy-app/Modal/index.tsx

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { h, Component, VNode, Fragment } from 'preact';
22
import * as style from './style.css';
33
import 'add-css:./style.css';
44
import { linkRef } from 'shared/prerendered-app/util';
5+
import { cleanSet } from '../util/clean-modify';
56

67
interface Props {}
78

@@ -26,66 +27,71 @@ export default class Modal extends Component<Props, State> {
2627
shown: false,
2728
};
2829

29-
private modal?: HTMLDialogElement;
30+
private dialogElement!: HTMLDialogElement;
31+
static modalInstance?: Modal | undefined;
3032

3133
componentDidMount() {
3234
// Once a transition ends, check if the modal should be closed (not just hidden)
3335
// dialog.close() instantly hides the modal, so we call it AFTER fading it out i.e. on transition end
34-
this.modal?.addEventListener(
36+
this.dialogElement.addEventListener(
3537
'transitionend',
3638
this._closeOnTransitionEnd.bind(this),
3739
);
38-
this.modal?.setAttribute('inert', 'enabled');
40+
this.dialogElement.setAttribute('inert', 'enabled');
41+
42+
Modal.modalInstance = this;
3943
}
4044

4145
private _closeOnTransitionEnd() {
4246
// If modal does not exist
4347
// Or if it's not being closed at the moment
44-
if (!this.modal || !this.modal.classList.contains(style.modalClosing))
48+
if (
49+
!this.dialogElement ||
50+
!this.dialogElement.classList.contains(style.modalClosing)
51+
)
4552
return;
4653

47-
this.modal.close();
48-
this.modal.classList.remove(style.modalClosing);
49-
this.modal.setAttribute('inert', 'enabled');
54+
this.dialogElement.close();
55+
this.dialogElement.classList.remove(style.modalClosing);
56+
this.dialogElement.setAttribute('inert', 'enabled');
57+
}
58+
59+
static showModal(message: ModalMessage) {
60+
Modal.modalInstance?._showModal(message);
5061
}
5162

52-
/**
53-
* Function to set up the modal and show it
54-
*/
55-
showModal(message: ModalMessage) {
56-
if (!this.modal) return;
63+
static hideModal() {
64+
Modal.modalInstance?._hideModal();
65+
}
66+
67+
private _showModal(message: ModalMessage) {
68+
if (!this.dialogElement) throw Error('Modal missing');
5769

5870
this.setState({
5971
message: message,
6072
shown: true,
6173
});
6274

6375
// Actually show the modal
64-
this.modal.removeAttribute('inert');
65-
this.modal.showModal();
76+
this.dialogElement.removeAttribute('inert');
77+
this.dialogElement.showModal();
6678
}
6779

68-
/**
69-
* Function to hide the modal with a fade-out transition
70-
* Adds the `modal--closing` class which is removed on transition end
71-
*/
72-
hideModal() {
73-
if (!this.modal || !this.modal.open) return;
80+
private _hideModal() {
81+
if (!this.dialogElement || !this.dialogElement.open)
82+
throw Error('Modal missing / hidden');
7483

7584
// Make the modal fade out
76-
this.modal.classList.add(style.modalClosing);
85+
this.dialogElement.classList.add(style.modalClosing);
7786

78-
this.setState({
79-
message: { ...this.state.message },
80-
shown: false,
81-
});
87+
this.setState(cleanSet(this.state, 'shown', false));
8288
}
8389

8490
private _onKeyDown(e: KeyboardEvent) {
8591
// Default behaviour of <dialog> closes it instantly when you press Esc
8692
// So we hijack it to smoothly hide the modal
87-
if (e.key === 'Escape' || e.keyCode == 27) {
88-
this.hideModal();
93+
if (e.key === 'Escape') {
94+
this._hideModal();
8995
e.preventDefault();
9096
e.stopImmediatePropagation();
9197
}
@@ -94,13 +100,13 @@ export default class Modal extends Component<Props, State> {
94100
render({}: Props, { message, shown }: State) {
95101
return (
96102
<dialog
97-
ref={linkRef(this, 'modal')}
103+
ref={linkRef(this, 'dialogElement')}
98104
onKeyDown={(e) => this._onKeyDown(e)}
99105
>
100106
<header class={style.header}>
101107
<span class={style.modalIcon}>{message.icon}</span>
102108
<span class={style.modalTitle}>{message.title}</span>
103-
<button class={style.closeButton} onClick={() => this.hideModal()}>
109+
<button class={style.closeButton} onClick={() => this._hideModal()}>
104110
<svg viewBox="0 0 480 480" fill="currentColor">
105111
<path
106112
d="M119.356 120L361 361M360.644 120L119 361"

0 commit comments

Comments
 (0)