mirror of
https://github.com/chinchang/web-maker.git
synced 2025-08-03 20:07:35 +02:00
add support for templates
This commit is contained in:
@@ -934,6 +934,7 @@ export default class ContentWrap extends Component {
|
||||
<use xlinkHref="#chevron-icon" />
|
||||
</svg>
|
||||
<input
|
||||
tabIndex={this.state.isConsoleOpen ? 0 : -1}
|
||||
onKeyUp={this.evalConsoleExpr.bind(this)}
|
||||
class="console-exec-input"
|
||||
/>
|
||||
|
32
src/components/CreateNewModal.jsx
Normal file
32
src/components/CreateNewModal.jsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { h } from 'preact';
|
||||
import Modal from './Modal';
|
||||
import { ItemTile } from './ItemTile';
|
||||
import templates from '../templateList';
|
||||
|
||||
export function CreateNewModal({
|
||||
show,
|
||||
closeHandler,
|
||||
onBlankTemplateSelect,
|
||||
onTemplateSelect
|
||||
}) {
|
||||
return (
|
||||
<Modal show={show} closeHandler={closeHandler} smll>
|
||||
<div class="tac">
|
||||
<button className="btn" onClick={onBlankTemplateSelect}>
|
||||
Start a blank creation
|
||||
</button>
|
||||
</div>
|
||||
<hr />
|
||||
Or choose from a template:
|
||||
<div class="saved-items-pane__container">
|
||||
{templates.map(template => (
|
||||
<ItemTile
|
||||
item={template}
|
||||
focusable
|
||||
onClick={onTemplateSelect.bind(null, template)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
60
src/components/ItemTile.jsx
Normal file
60
src/components/ItemTile.jsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import { h } from 'preact';
|
||||
import { getHumanDate } from '../utils';
|
||||
import Modal from './Modal';
|
||||
|
||||
export function ItemTile({
|
||||
item,
|
||||
onClick,
|
||||
itemForkBtnClick,
|
||||
itemRemoveBtnClick,
|
||||
focusable
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
role={focusable ? 'button' : null}
|
||||
tabindex={focusable ? 0 : null}
|
||||
class="js-saved-item-tile saved-item-tile"
|
||||
data-item-id={item.id}
|
||||
onClick={onClick}
|
||||
>
|
||||
<div class="saved-item-tile__btns">
|
||||
{itemForkBtnClick ? (
|
||||
<a
|
||||
class="js-saved-item-tile__fork-btn saved-item-tile__btn hint--left hint--medium"
|
||||
aria-label="Creates a duplicate of this creation (Ctrl/⌘ + F)"
|
||||
onClick={itemForkBtnClick}
|
||||
>
|
||||
Fork<span class="show-when-selected">(Ctrl/⌘ + F)</span>
|
||||
</a>
|
||||
) : null}
|
||||
{itemRemoveBtnClick ? (
|
||||
<a
|
||||
class="js-saved-item-tile__remove-btn saved-item-tile__btn hint--left"
|
||||
aria-label="Remove"
|
||||
onClick={itemRemoveBtnClick}
|
||||
>
|
||||
X
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex flex-v-center">
|
||||
{item.img ? (
|
||||
<div>
|
||||
<img
|
||||
class="saved-item-tile__img"
|
||||
height="40"
|
||||
src={item.img}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<h3 class="saved-item-tile__title">{item.title}</h3>
|
||||
</div>
|
||||
{item.updatedOn ? (
|
||||
<span class="saved-item-tile__meta">
|
||||
Last updated: {getHumanDate(item.updatedOn)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
@@ -1,9 +1,10 @@
|
||||
import { h, Component } from 'preact';
|
||||
import { log, getHumanDate } from '../utils';
|
||||
import { log } from '../utils';
|
||||
import { trackEvent } from '../analytics';
|
||||
import { itemService } from '../itemService';
|
||||
import { alertsService } from '../notifications';
|
||||
import { deferred } from '../deferred';
|
||||
import { ItemTile } from './ItemTile';
|
||||
|
||||
export default class SavedItemPane extends Component {
|
||||
constructor(props) {
|
||||
@@ -230,32 +231,12 @@ export default class SavedItemPane extends Component {
|
||||
<div class="mt-1">No match found.</div>
|
||||
) : null}
|
||||
{this.state.filteredItems.map(item => (
|
||||
<div
|
||||
class="js-saved-item-tile saved-item-tile"
|
||||
data-item-id={item.id}
|
||||
<ItemTile
|
||||
item={item}
|
||||
onClick={this.itemClickHandler.bind(this, item)}
|
||||
>
|
||||
<div class="saved-item-tile__btns">
|
||||
<a
|
||||
class="js-saved-item-tile__fork-btn saved-item-tile__btn hint--left hint--medium"
|
||||
aria-label="Creates a duplicate of this creation (Ctrl/⌘ + F)"
|
||||
onClick={this.itemForkBtnClickHandler.bind(this, item)}
|
||||
>
|
||||
Fork<span class="show-when-selected">(Ctrl/⌘ + F)</span>
|
||||
</a>
|
||||
<a
|
||||
class="js-saved-item-tile__remove-btn saved-item-tile__btn hint--left"
|
||||
aria-label="Remove"
|
||||
onClick={this.itemRemoveBtnClickHandler.bind(this, item)}
|
||||
>
|
||||
X
|
||||
</a>
|
||||
</div>
|
||||
<h3 class="saved-item-tile__title">{item.title}</h3>
|
||||
<span class="saved-item-tile__meta">
|
||||
Last updated: {getHumanDate(item.updatedOn)}
|
||||
</span>
|
||||
</div>
|
||||
onForkBtnClick={this.itemForkBtnClickHandler.bind(this, item)}
|
||||
onRemoveBtnClick={this.itemRemoveBtnClickHandler.bind(this, item)}
|
||||
/>
|
||||
))}
|
||||
{!this.items.length ? (
|
||||
<h2 class="opacity--30">Nothing saved here.</h2>
|
||||
|
@@ -41,6 +41,7 @@ import Portal from 'preact-portal';
|
||||
import { HelpModal } from './HelpModal';
|
||||
import { OnboardingModal } from './OnboardingModal';
|
||||
import { Js13KModal } from './Js13KModal';
|
||||
import { CreateNewModal } from './CreateNewModal';
|
||||
import { Icons } from './Icons';
|
||||
import JSZip from 'jszip';
|
||||
|
||||
@@ -59,8 +60,7 @@ export default class App extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.AUTO_SAVE_INTERVAL = 15000; // 15 seconds
|
||||
this.state = {
|
||||
isSavedItemPaneOpen: false,
|
||||
this.modalDefaultStates = {
|
||||
isModalOpen: false,
|
||||
isAddLibraryModalOpen: false,
|
||||
isSettingsModalOpen: false,
|
||||
@@ -73,6 +73,11 @@ export default class App extends Component {
|
||||
isAskToImportModalOpen: false,
|
||||
isOnboardModalOpen: false,
|
||||
isJs13KModalOpen: false,
|
||||
isCreateNewModalOpen: false
|
||||
};
|
||||
this.state = {
|
||||
isSavedItemPaneOpen: false,
|
||||
...this.modalDefaultStates,
|
||||
prefs: {},
|
||||
currentItem: {
|
||||
title: '',
|
||||
@@ -490,17 +495,7 @@ export default class App extends Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isAddLibraryModalOpen: false,
|
||||
isSettingsModalOpen: false,
|
||||
isHelpModalOpen: false,
|
||||
isNotificationsModalOpen: false,
|
||||
isLoginModalOpen: false,
|
||||
isProfileModalOpen: false,
|
||||
isSupportDeveloperModalOpen: false,
|
||||
isKeyboardShortcutsModalOpen: false,
|
||||
isAskToImportModalOpen: false,
|
||||
isOnboardModalOpen: false,
|
||||
isJs13KModalOpen: false
|
||||
...this.modalDefaultStates
|
||||
});
|
||||
}
|
||||
onExternalLibChange(newValues) {
|
||||
@@ -704,7 +699,9 @@ export default class App extends Component {
|
||||
});
|
||||
}
|
||||
}
|
||||
this.calculateCodeSize();
|
||||
if (this.state.prefs.isJs13kModeOn) {
|
||||
this.calculateCodeSize();
|
||||
}
|
||||
}
|
||||
onCodeSettingsChange(type, settings) {
|
||||
this.state.currentItem[`${type}Settings`] = {
|
||||
@@ -832,10 +829,14 @@ export default class App extends Component {
|
||||
'You have unsaved changes. Do you still want to create something new?'
|
||||
);
|
||||
if (shouldDiscard) {
|
||||
this.createNewItem();
|
||||
this.setState({
|
||||
isCreateNewModalOpen: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.createNewItem();
|
||||
this.setState({
|
||||
isCreateNewModalOpen: true
|
||||
});
|
||||
}
|
||||
}
|
||||
openBtnClickHandler() {
|
||||
@@ -1112,6 +1113,19 @@ export default class App extends Component {
|
||||
isJs13KModalOpen: true
|
||||
});
|
||||
}
|
||||
blankTemplateSelectHandler() {
|
||||
this.createNewItem();
|
||||
this.setState({ isCreateNewModalOpen: false });
|
||||
}
|
||||
|
||||
templateSelectHandler(template) {
|
||||
fetch(`templates/template-${template.id}.json`)
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
this.forkItem(json);
|
||||
});
|
||||
this.setState({ isCreateNewModalOpen: false });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
@@ -1293,6 +1307,13 @@ export default class App extends Component {
|
||||
closeHandler={() => this.setState({ isJs13KModalOpen: false })}
|
||||
/>
|
||||
|
||||
<CreateNewModal
|
||||
show={this.state.isCreateNewModalOpen}
|
||||
closeHandler={() => this.setState({ isCreateNewModalOpen: false })}
|
||||
onBlankTemplateSelect={this.blankTemplateSelectHandler.bind(this)}
|
||||
onTemplateSelect={this.templateSelectHandler.bind(this)}
|
||||
/>
|
||||
|
||||
<Portal into="body">
|
||||
<div
|
||||
class="modal-overlay"
|
||||
|
Reference in New Issue
Block a user