Skip to content

Commit

Permalink
implement useFile via useStore
Browse files Browse the repository at this point in the history
  • Loading branch information
SillyFreak committed May 20, 2020
1 parent 0107774 commit d2500d9
Showing 1 changed file with 10 additions and 45 deletions.
55 changes: 10 additions & 45 deletions src/components/ide/useFile.js
@@ -1,62 +1,27 @@
// @flow

import * as React from 'react';

import { fs } from 'filer';

import { Project } from '../../core/store/projects';
import { useStore } from '../misc/hooks';

export { Project };

type Content = string;
type MaybeContent = Content | null;
type ContentSetter = (content: Content) => void | Promise<void>;

function useFile(
project: Project,
path: string,
): [MaybeContent, ContentSetter] {
const [content, setContentImpl] = React.useState<MaybeContent>(null);

// reload file contents when the project or file changes
React.useEffect(() => {
// load the file's contents
(async () => {
const absolutePath = project.resolve(path);

const newContent = await fs.promises.readFile(absolutePath, 'utf8');
setContentImpl(newContent);
})();

// after changing the file, set the content to null to prevent further use
// of the old content
return () => {
setContentImpl(null);
};
}, [project, path]);

// save the file when content changed
// TODO test that the setContentImpl(null) when changing file is dispatched
// before this effect, so that content can not be erroneously written to the
// wrong file
React.useEffect(() => {
(async () => {
// if the content was not loaded yet for whatever reason, don't delete
// existing file contents.
if (content === null) return;

const absolutePath = project.resolve(path);
await fs.promises.writeFile(absolutePath, content, 'utf8');
})();
}, [project, path, content]);
): [string | null, (string) => void] {
async function load() {
const absolutePath = project.resolve(path);
return /* await */ fs.promises.readFile(absolutePath, 'utf8');
}

function setContent(newContent: Content) {
// only set content if the current content is not null,
// i.e. the original file contents were loaded successfully
if (content !== null) setContentImpl(newContent);
async function store(content) {
const absolutePath = project.resolve(path);
await fs.promises.writeFile(absolutePath, content, 'utf8');
}

return [content, setContent];
return useStore<string>(load, store, [project, path]);
}

export default useFile;

0 comments on commit d2500d9

Please sign in to comment.