1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-07-27 16:50:11 +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 UserCodeMirror from './UserCodeMirror';
import { modes, HtmlModes, CssModes, JsModes } from '../codeModes';
import { log, loadJS } from '../utils';
import { log, loadJS, linearizeFiles } from '../utils';
import { SplitPane } from './SplitPane';
import { trackEvent } from '../analytics';
import CodeMirror from '../CodeMirror';
@@ -58,7 +58,7 @@ export default class ContentWrapFiles extends Component {
}
componentDidUpdate() {
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.
if (
@@ -79,18 +79,7 @@ export default class ContentWrapFiles extends Component {
componentDidMount() {
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 = '') {
let options = {
gutters: [
@@ -172,6 +161,17 @@ export default class ContentWrapFiles extends Component {
}, 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) {
// Track if people have written code.
if (!trackEvent.hasTrackedCode && (html || css || js)) {
@@ -180,12 +180,17 @@ export default class ContentWrapFiles extends Component {
}
var obj = {};
this.props.currentItem.files.forEach(file => {
obj[`/user/${file.name}`] = file.content || '';
const duplicateFiles = JSON.parse(
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
if (file.name === 'index.html') {
obj[`/user/${file.name}`] =
obj[file.path] =
'<script src="' +
(chrome.extension
? chrome.extension.getURL('lib/screenlog.js')
@@ -193,7 +198,7 @@ export default class ContentWrapFiles extends Component {
window.DEBUG ? '' : BASE_PATH
}/lib/screenlog.js`) +
'"></script>' +
obj[`/user/${file.name}`];
obj[file.path];
}
});

View File

@@ -170,7 +170,10 @@ function Folder(props) {
export class SidePane extends Component {
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.
@@ -194,8 +197,8 @@ export class SidePane extends Component {
addFile(e) {
// This gets called twice when enter is pressed, because blur also fires.
// So check `isEditing` before proceeding.
if (!this.state.isEditing) {
// So check `isAddingFile` before proceeding.
if (!this.state.isAddingFile && !this.state.isAddingFolder) {
return;
}
const newFileName = e.target.value;
@@ -203,15 +206,15 @@ export class SidePane extends Component {
return;
}
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) {
if (e.which === ENTER_KEY) {
this.addFile(e);
} else if (e.which === ESCAPE_KEY) {
this.setState({ isEditing: false });
this.setState({ isAddingFile: false, isAddingFolder: false });
}
}
removeFileClickHandler(file, e) {
@@ -262,7 +265,7 @@ export class SidePane extends Component {
<div class="sidebar">
<div class="flex jc-sb" style="padding: 5px 4px">
Files
<div>
<div class="flex flex-v-center">
<button
type="button"
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" />
</svg>
</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>
{this.state.isEditing ? (
{this.state.isAddingFile || this.state.isAddingFolder ? (
<div>
<input
type="text"

View File

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

View File

@@ -465,3 +465,21 @@ if (window.IS_EXTENSION) {
} else {
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);
}