Skip to content

Commit

Permalink
Convert components to JSX
Browse files Browse the repository at this point in the history
  • Loading branch information
caleb531 committed Aug 22, 2024
1 parent 66bad4f commit e7c53ce
Show file tree
Hide file tree
Showing 39 changed files with 991 additions and 915 deletions.
11 changes: 11 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.DS_Store
node_modules
/dist
.env
.env.*
!.env.example

# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock
5 changes: 5 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100
}
28 changes: 11 additions & 17 deletions scripts/components/app-header.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import m from 'mithril';

class AppHeaderComponent {

view() {
return m('.app-header', [
m('h1', 'Flip Book'),
m('.app-header-mentions', [
m('span.app-header-mention', [
'By ',
m('a[href="https://calebevans.me/"]', 'Caleb Evans'),
'.'
]),
m('span.app-header-mention', [
'For my friend and brother, Bill.'
])
])
]);
return (
<div className="app-header">
<h1>Flip Book</h1>
<div className="app-header-mentions">
<span className="app-header-mention">
By <a href="https://calebevans.me/">Caleb Evans</a>.
</span>
<span className="app-header-mention">For my friend and brother, Bill.</span>
</div>
</div>
);
}

}

export default AppHeaderComponent;
36 changes: 16 additions & 20 deletions scripts/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import StoryComponent from './story.jsx';
import StorageUpgraderComponent from './storage-upgrader.jsx';

class AppComponent {

oninit() {
App.restore().then((app) => {
this.app = app;
m.redraw();
});
}

oncreate({dom}) {
oncreate({ dom }) {
dom.focus();
}

Expand All @@ -39,25 +38,22 @@ class AppComponent {
}

view() {
return m('div.app[tabindex=-1]', {
onkeydown: (event) => this.navigateFramesViaKeyboard(event)
}, [

// The UpdateNotificationComponent manages its own visibility
m(UpdateNotificationComponent),

m(StorageUpgraderComponent),

m(AppHeaderComponent),

this.app?.selectedStory ? m(StoryComponent, {
app: this.app,
story: this.app.selectedStory
}) : null

]);
return (
<div
className="app"
tabIndex="-1"
onkeydown={(event) => this.navigateFramesViaKeyboard(event)}
>
{/* The UpdateNotificationComponent manages its own visibility */}
<UpdateNotificationComponent />
<StorageUpgraderComponent />
<AppHeaderComponent />
{this.app?.selectedStory ? (
<StoryComponent app={this.app} story={this.app.selectedStory} />
) : null}
</div>
);
}

}

export default AppComponent;
66 changes: 41 additions & 25 deletions scripts/components/control.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
import m from 'mithril';
import clsx from 'clsx';
import PanelComponent from './panel.jsx';

class ControlComponent {

view({attrs: {id, title, icon = null, label = null, action = null, panel = null, panelPosition = 'top'}}) {
return m(`div`, {
class: clsx('control', `control-${id}`, {'control-has-label': label})
}, [
panel ? m(PanelComponent, {id, position: panelPosition}, panel) : null,
m('button.control-button', {
title,
onclick: ({target}) => {
if (panel) {
PanelComponent.togglePanel(id);
} else if (action) {
// Do not close the panel where the clicked control resides
if (!target.closest('.panel')) {
PanelComponent.closeAllPanels();
view({
attrs: {
id,
title,
icon = null,
label = null,
action = null,
panel = null,
panelPosition = 'top'
}
}) {
return (
<div
className={clsx('control', `control-${id}`, {
'control-has-label': label
})}
>
{panel ? (
<PanelComponent id={id} position={panelPosition}>
{panel}
</PanelComponent>
) : null}
<button
className="control-button"
title={title}
onclick={({ target }) => {
if (panel) {
PanelComponent.togglePanel(id);
} else if (action) {
// Do not close the panel where the clicked control resides
if (!target.closest('.panel')) {
PanelComponent.closeAllPanels();
}
action();
}
action();
}
}
}, [
icon ? m('img.control-icon', {src: `icons/${icon}.svg`, alt: title}) : null,
label ? m('span.control-label', label) : null
])
]);
}}
>
{icon ? <img className="control-icon" src={`icons/${icon}.svg`} alt={title} /> : null}
{label ? <span className="control-label">{label}</span> : null}
</button>
</div>
);
}

}

export default ControlComponent;
44 changes: 22 additions & 22 deletions scripts/components/drawing-area.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import m from 'mithril';
import FrameComponent from './frame.jsx';

class DrawingAreaComponent extends FrameComponent {

oninit({attrs: {story, frame, drawingEnabled = true}}) {
oninit({ attrs: { story, frame, drawingEnabled = true } }) {
this.story = story;
super.oninit({attrs: {frame}});
super.oninit({ attrs: { frame } });
this.drawingEnabled = drawingEnabled;
}

oncreate({dom}) {
super.oncreate({dom});
oncreate({ dom }) {
super.oncreate({ dom });
}

onupdate({attrs: {story, frame, drawingEnabled = true}}) {
onupdate({ attrs: { story, frame, drawingEnabled = true } }) {
this.story = story;
this.drawingEnabled = drawingEnabled;
super.onupdate({attrs: {frame}});
super.onupdate({ attrs: { frame } });
}

handleDrawStart(event, pageX, pageY) {
Expand Down Expand Up @@ -109,20 +107,22 @@ class DrawingAreaComponent extends FrameComponent {
}

view() {
return m('canvas.selected-frame', {
width: FrameComponent.width,
height: FrameComponent.height,
// Touch events
ontouchstart: (event) => this.handleTouchStart(event),
ontouchmove: (event) => this.handleTouchMove(event),
ontouchend: (event) => this.handleTouchEnd(event),
// Mouse events
onmousedown: (event) => this.handleMouseDown(event),
onmousemove: (event) => this.handleMouseMove(event),
onmouseup: (event) => this.handleMouseUp(event),
onmouseout: (event) => this.handleMouseUp(event)
});
return (
<canvas
className="selected-frame"
width={FrameComponent.width}
height={FrameComponent.height}
// Touch events
ontouchstart={(event) => this.handleTouchStart(event)}
ontouchmove={(event) => this.handleTouchMove(event)}
ontouchend={(event) => this.handleTouchEnd(event)}
// Mouse events
onmousedown={(event) => this.handleMouseDown(event)}
onmousemove={(event) => this.handleMouseMove(event)}
onmouseup={(event) => this.handleMouseUp(event)}
onmouseout={(event) => this.handleMouseUp(event)}
/>
);
}

}
export default DrawingAreaComponent;
58 changes: 31 additions & 27 deletions scripts/components/export-gif.jsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
import m from 'mithril';
import clsx from 'clsx';
import ControlComponent from './control.jsx';
import ProgressBarComponent from './progress-bar.jsx';

class ExportGifComponent {

view({attrs: {isExportingGif, exportProgress, isGifExportFinished, exportedImageUrl, abort}}) {
return m('div', {
class: clsx('export-gif-screen', {'visible': isExportingGif || isGifExportFinished})
}, [
m(ControlComponent, {
id: 'close-export-gif-overlay',
title: isGifExportFinished ? 'Close overlay' : 'Abort GIF export',
icon: 'close',
action: () => abort()
}),
m('div.export-gif-overlay'),
m('div.export-gif-heading', exportedImageUrl ?
'GIF Generated!' :
'Generating GIF...'),
m('p.export-gif-message', exportedImageUrl ?
'Right-click the image and choose "Save Image As..." to download.' :
''),
exportedImageUrl ? m('img.exported-image', {
src: exportedImageUrl,
alt: 'Exported GIF'
}) : m(ProgressBarComponent, {
progress: exportProgress
})
]);
view({
attrs: { isExportingGif, exportProgress, isGifExportFinished, exportedImageUrl, abort }
}) {
return (
<div
className={clsx('export-gif-screen', {
visible: isExportingGif || isGifExportFinished
})}
>
<ControlComponent
id="close-export-gif-overlay"
title={isGifExportFinished ? 'Close overlay' : 'Abort GIF export'}
icon="close"
action={() => abort()}
/>
<div className="export-gif-overlay" />
<div className="export-gif-heading">
{exportedImageUrl ? 'GIF Generated!' : 'Generating GIF...'}
</div>
<p className="export-gif-message">
{exportedImageUrl
? 'Right-click the image and choose "Save Image As..." to download.'
: ''}
</p>
{exportedImageUrl ? (
<img className="exported-image" src={exportedImageUrl} alt="Exported GIF" />
) : (
<ProgressBarComponent progress={exportProgress} />
)}
</div>
);
}

}

export default ExportGifComponent;
Loading

0 comments on commit e7c53ce

Please sign in to comment.