1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-07-27 08:40:10 +02:00

add folders!

This commit is contained in:
Kushagra Gour
2018-10-11 16:30:09 +05:30
parent 57c5e07ee5
commit 006a37f8ef
4 changed files with 79 additions and 34 deletions

View File

@@ -1,7 +1,7 @@
import { h, Component } from 'preact'; import { h, Component } from 'preact';
import UserCodeMirror from './UserCodeMirror'; import UserCodeMirror from './UserCodeMirror';
import { modes, HtmlModes, CssModes, JsModes } from '../codeModes'; import { modes, HtmlModes, CssModes, JsModes } from '../codeModes';
import { log, loadJS } from '../utils'; import { log, loadJS, linearizeFiles } from '../utils';
import { SplitPane } from './SplitPane'; import { SplitPane } from './SplitPane';
import { trackEvent } from '../analytics'; import { trackEvent } from '../analytics';
import CodeMirror from '../CodeMirror'; import CodeMirror from '../CodeMirror';
@@ -58,7 +58,7 @@ export default class ContentWrapFiles extends Component {
} }
componentDidUpdate() { componentDidUpdate() {
const { currentItem } = this.props; const { currentItem } = this.props;
const linearFiles = this.linearizeFiles(currentItem.files); const linearFiles = linearizeFiles(currentItem.files);
// Select a new file if nothing is selected already or the selected file exists no more. // Select a new file if nothing is selected already or the selected file exists no more.
if ( if (
@@ -79,18 +79,7 @@ export default class ContentWrapFiles extends Component {
componentDidMount() { componentDidMount() {
this.props.onRef(this); this.props.onRef(this);
} }
linearizeFiles(files) {
function reduceToLinearFiles(files) {
return files.reduce((list, currentFile) => {
if (currentFile.isFolder) {
return [...list, ...reduceToLinearFiles(currentFile.children)];
} else {
return [...list, currentFile];
}
}, []);
}
return reduceToLinearFiles(files);
}
getEditorOptions(fileName = '') { getEditorOptions(fileName = '') {
let options = { let options = {
gutters: [ gutters: [
@@ -172,6 +161,17 @@ export default class ContentWrapFiles extends Component {
}, this.updateDelay); }, this.updateDelay);
} }
constructFilePaths(files, parentPath = '/user') {
files.forEach(file => {
if (file.isFolder) {
this.constructFilePaths(file.children, `${parentPath}/${file.name}`);
} else {
file.path = `${parentPath}/${file.name}`;
}
});
return files;
}
createPreviewFile(html, css, js) { createPreviewFile(html, css, js) {
// Track if people have written code. // Track if people have written code.
if (!trackEvent.hasTrackedCode && (html || css || js)) { if (!trackEvent.hasTrackedCode && (html || css || js)) {
@@ -180,12 +180,17 @@ export default class ContentWrapFiles extends Component {
} }
var obj = {}; var obj = {};
this.props.currentItem.files.forEach(file => { const duplicateFiles = JSON.parse(
obj[`/user/${file.name}`] = file.content || ''; JSON.stringify(this.props.currentItem.files)
);
const files = linearizeFiles(this.constructFilePaths(duplicateFiles));
files.forEach(file => {
obj[file.path] = file.content || '';
// Add screenlog to index.html // Add screenlog to index.html
if (file.name === 'index.html') { if (file.name === 'index.html') {
obj[`/user/${file.name}`] = obj[file.path] =
'<script src="' + '<script src="' +
(chrome.extension (chrome.extension
? chrome.extension.getURL('lib/screenlog.js') ? chrome.extension.getURL('lib/screenlog.js')
@@ -193,7 +198,7 @@ export default class ContentWrapFiles extends Component {
window.DEBUG ? '' : BASE_PATH window.DEBUG ? '' : BASE_PATH
}/lib/screenlog.js`) + }/lib/screenlog.js`) +
'"></script>' + '"></script>' +
obj[`/user/${file.name}`]; obj[file.path];
} }
}); });

View File

@@ -170,7 +170,10 @@ function Folder(props) {
export class SidePane extends Component { export class SidePane extends Component {
addFileButtonClickHandler() { addFileButtonClickHandler() {
this.setState({ isEditing: true }); this.setState({ isAddingFile: true });
}
addFolderButtonClickHandler() {
this.setState({ isAddingFolder: true });
} }
/** /**
* Checks if the passed filename already exists and if so, warns the user. * Checks if the passed filename already exists and if so, warns the user.
@@ -194,8 +197,8 @@ export class SidePane extends Component {
addFile(e) { addFile(e) {
// This gets called twice when enter is pressed, because blur also fires. // This gets called twice when enter is pressed, because blur also fires.
// So check `isEditing` before proceeding. // So check `isAddingFile` before proceeding.
if (!this.state.isEditing) { if (!this.state.isAddingFile && !this.state.isAddingFolder) {
return; return;
} }
const newFileName = e.target.value; const newFileName = e.target.value;
@@ -203,15 +206,15 @@ export class SidePane extends Component {
return; return;
} }
if (newFileName) { if (newFileName) {
this.props.onAddFile(newFileName); this.props.onAddFile(newFileName, this.state.isAddingFolder);
} }
this.setState({ isEditing: false }); this.setState({ isAddingFile: false, isAddingFolder: false });
} }
newFileNameInputKeyDownHandler(e) { newFileNameInputKeyDownHandler(e) {
if (e.which === ENTER_KEY) { if (e.which === ENTER_KEY) {
this.addFile(e); this.addFile(e);
} else if (e.which === ESCAPE_KEY) { } else if (e.which === ESCAPE_KEY) {
this.setState({ isEditing: false }); this.setState({ isAddingFile: false, isAddingFolder: false });
} }
} }
removeFileClickHandler(file, e) { removeFileClickHandler(file, e) {
@@ -262,7 +265,7 @@ export class SidePane extends Component {
<div class="sidebar"> <div class="sidebar">
<div class="flex jc-sb" style="padding: 5px 4px"> <div class="flex jc-sb" style="padding: 5px 4px">
Files Files
<div> <div class="flex flex-v-center">
<button <button
type="button" type="button"
class="btn--dark" class="btn--dark"
@@ -275,9 +278,21 @@ export class SidePane extends Component {
<path d="M13,9H18.5L13,3.5V9M6,2H14L20,8V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V4C4,2.89 4.89,2 6,2M11,15V12H9V15H6V17H9V20H11V17H14V15H11Z" /> <path d="M13,9H18.5L13,3.5V9M6,2H14L20,8V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V4C4,2.89 4.89,2 6,2M11,15V12H9V15H6V17H9V20H11V17H14V15H11Z" />
</svg> </svg>
</button> </button>
<button
type="button"
class="btn--dark"
onClick={this.addFolderButtonClickHandler.bind(this)}
>
<svg
viewBox="0 0 24 24"
style="vertical-align:middle;width:14px;height:14px"
>
<path d="M10,4L12,6H20A2,2 0 0,1 22,8V18A2,2 0 0,1 20,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10M15,9V12H12V14H15V17H17V14H20V12H17V9H15Z" />
</svg>
</button>
</div> </div>
</div> </div>
{this.state.isEditing ? ( {this.state.isAddingFile || this.state.isAddingFolder ? (
<div> <div>
<input <input
type="text" type="text"

View File

@@ -20,7 +20,8 @@ import {
handleDownloadsPermission, handleDownloadsPermission,
downloadFile, downloadFile,
getCompleteHtml, getCompleteHtml,
getFilenameFromUrl getFilenameFromUrl,
linearizeFiles
} from '../utils'; } from '../utils';
import { itemService } from '../itemService'; import { itemService } from '../itemService';
import '../db'; import '../db';
@@ -711,7 +712,7 @@ export default class App extends Component {
} }
onCodeChange(type, code, isUserChange) { onCodeChange(type, code, isUserChange) {
if (this.state.currentItem.files) { if (this.state.currentItem.files) {
this.state.currentItem.files.map(file => { linearizeFiles(this.state.currentItem.files).map(file => {
if (file.name === type.name) { if (file.name === type.name) {
file.content = code; file.content = code;
} }
@@ -1187,17 +1188,23 @@ export default class App extends Component {
}); });
this.setState({ isCreateNewModalOpen: false }); this.setState({ isCreateNewModalOpen: false });
} }
addFileHandler(fileName) { addFileHandler(fileName, isFolder) {
let newEntry = { name: fileName, content: '' };
if (isFolder) {
newEntry = {
...newEntry,
isFolder: true,
children: [],
isCollapsed: true
};
}
this.setState({ this.setState({
currentItem: { currentItem: {
...this.state.currentItem, ...this.state.currentItem,
files: [ files: [...this.state.currentItem.files, newEntry]
...this.state.currentItem.files,
{ name: fileName, content: '' }
]
} }
}); });
console.log(11, this.state.currentItem);
} }
removeFileHandler(fileToRemove) { removeFileHandler(fileToRemove) {
this.setState({ this.setState({

View File

@@ -465,3 +465,21 @@ if (window.IS_EXTENSION) {
} else { } else {
document.body.classList.add('is-app'); document.body.classList.add('is-app');
} }
/**
* Returns a linear file list from a nested file strcuture.
* It excludes the folders from the returned list.
* @param {array} files Nested file structure
*/
export function linearizeFiles(files) {
function reduceToLinearFiles(files) {
return files.reduce((list, currentFile) => {
if (currentFile.isFolder) {
return [...list, ...reduceToLinearFiles(currentFile.children)];
} else {
return [...list, currentFile];
}
}, []);
}
return reduceToLinearFiles(files);
}