();
+
+ useEffect(() => {
+ setInterval(() => {
+ syncFilesJupyterLite()
+ }, 1000)
+ }, [])
+
+ useEffect(() => {
+ (async () => {
+ const folders = Object.values(files).filter(file => file.type === "directory")
+ folders.forEach(folder => {
+ const filesInFolder = Object.values(files).filter(file => file.type !== "directory" && file.path.startsWith(folder.name))
+ let image: AtomifyFile
+ filesInFolder.forEach(file => {
+ if (file.mimetype === "image/png") {
+ image = file
+ }
+ })
+ })
+
+
+ })()
+ }, [files])
+
+ const renderCard = (simulation: AtomifyFile) => {
+ return (
+ ,
+ ,
+ ]}
+ >
+
+
+ )}
+
+ const chunkIt = (array: Simulation[], chunkSize: number) => {
+ const chunks: Simulation[][] = []
+
+ for (let i = 0; i < array.length; i += chunkSize) {
+ const chunk = array.slice(i, i + chunkSize);
+ chunks.push(chunk)
+ }
+ return chunks
+ }
+
+
+
+ return (
+ <>
+
+
+
Your simulations
+
+ {folders.map(renderCard)}
+
+ >)
+}
+export default Simulations
\ No newline at end of file
diff --git a/src/hooks/files.ts b/src/hooks/files.ts
new file mode 100644
index 00000000..f88f75c5
--- /dev/null
+++ b/src/hooks/files.ts
@@ -0,0 +1,29 @@
+import {useState, useEffect} from 'react'
+import localforage from 'localforage'
+
+localforage.config({
+ driver : localforage.INDEXEDDB,
+ name : 'JupyterLite Storage',
+ storeName : 'files', // Should be alphanumeric, with underscores.
+ description : 'some description'
+});
+
+export const useListSimulations = async () => {
+ const [loading, setLoading] = useState(true)
+ const [error, setError] = useState(false)
+
+ useEffect(() => {
+ (async () => {
+ const keys = await localforage.keys()
+ const simulations = []
+
+ for (let key of keys) {
+ const file = await localforage.getItem(key) as any
+ if (file.type === 'directory') {
+
+ }
+ }
+ })()
+
+ })
+}
\ No newline at end of file
diff --git a/src/store/app.ts b/src/store/app.ts
index d58cc28e..1acb5e84 100644
--- a/src/store/app.ts
+++ b/src/store/app.ts
@@ -25,7 +25,7 @@ export interface AppModel {
}
export const appModel: AppModel = {
- selectedMenu: 'examples',
+ selectedMenu: 'simulations',
setSelectedMenu: action((state, selectedMenu: string) => {
state.selectedMenu = selectedMenu
}),
diff --git a/src/store/files.ts b/src/store/files.ts
new file mode 100644
index 00000000..ecb408c9
--- /dev/null
+++ b/src/store/files.ts
@@ -0,0 +1,90 @@
+import { action, Action, thunk, Thunk } from 'easy-peasy';
+import localforage from 'localforage'
+
+localforage.config({
+ driver : localforage.INDEXEDDB,
+ name : 'JupyterLite Storage',
+ storeName : 'files', // Should be alphanumeric, with underscores.
+ description : 'some description'
+});
+
+export interface AtomifyFile {
+ created: Date
+ format: string
+ last_modified: Date
+ mimetype: string
+ name: string
+ path: string
+ type: string
+ writeable: boolean
+ text: () => Promise
+ writeText: (content: string) => Promise
+}
+
+export interface FilesModel {
+ files: {[key: string]: AtomifyFile}
+ setFiles: Action
+ syncFilesJupyterLite: Thunk
+}
+
+export const filesModel: FilesModel = {
+ files: {},
+ setFiles: action((state, render: {[key: string]: AtomifyFile}) => {
+ state.files = render
+ }),
+ syncFilesJupyterLite: thunk(async (actions, dummy: undefined, {getStoreState}) => {
+ // @ts-ignore
+ const state = getStoreState().files as FilesModel
+
+ const newFiles = {...state.files}
+ let anyChanges = false
+
+ // First find all files from JupyterLite and sync them in
+ const keys = await localforage.keys()
+ for (let key of keys) {
+ const file = await localforage.getItem(key) as any
+ if (!state.files[key]) {
+ const dateModified = new Date(file.date_modified)
+ // Create AtomifyFile object
+ const newFile: AtomifyFile = {
+ created: new Date(file.created),
+ format: file.format,
+ last_modified: new Date(file.last_modified),
+ mimetype: file.mimetype,
+ name: file.name,
+ path: file.path,
+ type: file.type,
+ writeable: file.writeable,
+ text: async () => {
+ const file = await localforage.getItem(key) as any
+ return file.content
+ },
+ writeText: async (content: string) => {
+ const file = await localforage.getItem(key) as any
+
+ await localforage.setItem(key, {
+ ...file,
+ content
+ })
+ }
+ }
+
+ newFiles[key] = newFile
+ anyChanges = true
+ }
+ }
+
+ // Then remove any files that no longer are there
+ Object.keys(state.files).forEach(key => {
+ if (keys.indexOf(key) === -1) {
+ // This file no longer exists in JupyterLite
+ delete newFiles[key]
+ anyChanges = true
+ }
+ })
+
+ if (anyChanges) {
+ actions.setFiles(newFiles)
+ }
+ })
+};
diff --git a/src/store/model.ts b/src/store/model.ts
index 5f74c1c0..95ddabaf 100644
--- a/src/store/model.ts
+++ b/src/store/model.ts
@@ -3,6 +3,7 @@ import { SettingsModel, settingsModel } from './settings'
import { SimulationStatusModel, simulationStatusModel } from './simulationstatus'
import { ProcessingModel, processingModel } from './processing'
import { RenderModel, renderModel } from './render'
+import { FilesModel, filesModel } from './files'
import { AppModel, appModel } from './app'
import { persist } from 'easy-peasy';
@@ -13,6 +14,7 @@ export interface StoreModel {
processing: ProcessingModel,
app: AppModel,
render: RenderModel
+ files: FilesModel
}
export const storeModel: StoreModel = {
@@ -21,5 +23,6 @@ export const storeModel: StoreModel = {
simulationStatus: simulationStatusModel,
processing: processingModel,
app: appModel,
- render: renderModel
+ render: renderModel,
+ files: filesModel
};