Git
7 files changed +280 −88
Review
Insert▾
react-native/components/code/CodePage.jsx (+37 −1) modified
3


      
3


      
4
import {CodeEditor} from '../CodeEditor';
4
import {CodeEditor} from '../CodeEditor';
5
import {FileTree} from './FileTree';
5
import {FileTree} from './FileTree';


  
6
import {NativeModules} from 'react-native';
6
import {fileSystem} from '../fileSystem';
7
import {fileSystem} from '../fileSystem';
7
import {useThemedStyles} from '../theme';
8
import {useThemedStyles} from '../theme';
8


      
9


      
13
  const styles = useThemedStyles(createStyles);
14
  const styles = useThemedStyles(createStyles);
14
  const [source, setSource] = useState('// some comment\n');
15
  const [source, setSource] = useState('// some comment\n');
15
  const [currentFile, setCurrentFile] = useState(null);
16
  const [currentFile, setCurrentFile] = useState(null);


  
17
  const [root, setRoot] = useState(null);


  
18


      


  
19
  // Which folder the server is serving is its state, not this component's —


  
20
  // it survives a reload of the app, so it is read rather than assumed.


  
21
  useEffect(() => {


  
22
    fileSystem.getRoot().then(response => setRoot(response.root));


  
23
  }, []);
16


      
24


      
17
  const save = useCallback(
25
  const save = useCallback(
18
    async (contents = source) => {
26
    async (contents = source) => {
40
    [save],
48
    [save],
41
  );
49
  );
42


      
50


      


  
51
  const openFolder = useCallback(async () => {


  
52
    const chosen = await NativeModules.FolderPicker.pick();


  
53


      


  
54
    if (!chosen || chosen === root) {


  
55
      return;


  
56
    }


  
57


      


  
58
    // Every path in flight is relative to the folder being left behind, so the


  
59
    // buffer is written and released before the server moves. A debounced save


  
60
    // landing after the swap would put the old file's contents at the same


  
61
    // relative path inside the new folder.


  
62
    await save();


  
63
    setCurrentFile(null);


  
64
    setSource('');


  
65


      


  
66
    const response = await fileSystem.setRoot(chosen);


  
67
    setRoot(response.root);


  
68
  }, [root, save]);


  
69


      
43
  // The buffer is written once it stops moving. Clearing the timer on every
70
  // The buffer is written once it stops moving. Clearing the timer on every
44
  // change is also what makes switching files safe: a write scheduled against
71
  // change is also what makes switching files safe: a write scheduled against
45
  // one path can never land on the next one.
72
  // one path can never land on the next one.
56
  return (
83
  return (
57
    <View style={styles.editor}>
84
    <View style={styles.editor}>
58
      <View style={styles.fileTree}>
85
      <View style={styles.fileTree}>
59
        <FileTree currentFile={currentFile} onOpenFile={openFile} onSave={save} />


  


  
86
        {/* Keyed on the root so switching folders remounts the tree: every


  
87
            FileNode holds its expanded children locally, and those point at


  
88
            paths that no longer exist. */}


  
89
        <FileTree


  
90
          key={root}


  
91
          root={root}


  
92
          currentFile={currentFile}


  
93
          onOpenFile={openFile}


  
94
          onOpenFolder={openFolder}


  
95
        />
60
      </View>
96
      </View>
61


      
97


      
62
      <View style={styles.codeEditorContainer}>
98
      <View style={styles.codeEditorContainer}>