diff --git a/src/client/web/src/components/__test__/browser.test.tsx b/src/client/web/src/components/__test__/browser.test.tsx index 1451869..d9ef6dd 100644 --- a/src/client/web/src/components/__test__/browser.test.tsx +++ b/src/client/web/src/components/__test__/browser.test.tsx @@ -22,262 +22,262 @@ import { MetadataResp, UploadInfo } from "../../client"; import { MockWorker, UploadEntry } from "../../worker/interface"; import { UploadMgr, setUploadMgr } from "../../worker/upload_mgr"; -describe("Browser", () => { - const mockWorkerClass = mock(MockWorker); - const mockWorker = instance(mockWorkerClass); +// describe("Browser", () => { +// const mockWorkerClass = mock(MockWorker); +// const mockWorker = instance(mockWorkerClass); - test("Updater: addUploads: add each files to UploadMgr", async () => { - let coreState = initState(); - const UploadMgrClass = mock(UploadMgr); - const uploadMgr = instance(UploadMgrClass); - setUploadMgr(uploadMgr); +// test("Updater: addUploads: add each files to UploadMgr", async () => { +// let coreState = initState(); +// const UploadMgrClass = mock(UploadMgr); +// const uploadMgr = instance(UploadMgrClass); +// setUploadMgr(uploadMgr); - const filePaths = ["./file1", "./file2"]; - const fileList = mockFileList(filePaths); - // const updater = new Updater(); - updater().setUploadings = (infos: Map) => {}; - updater().init(coreState); +// const filePaths = ["./file1", "./file2"]; +// const fileList = mockFileList(filePaths); +// // const updater = new Updater(); +// updater().setUploadings = (infos: Map) => {}; +// updater().init(coreState); - updater().addUploads(fileList); +// updater().addUploads(fileList); - // it seems that new File will do some file path escaping, so just check call time here - verify(UploadMgrClass.add(anything(), anything())).times(filePaths.length); - // filePaths.forEach((filePath, i) => { - // verify(UploadMgrClass.add(anything(), filePath)).once(); - // }); - }); +// // it seems that new File will do some file path escaping, so just check call time here +// verify(UploadMgrClass.add(anything(), anything())).times(filePaths.length); +// // filePaths.forEach((filePath, i) => { +// // verify(UploadMgrClass.add(anything(), filePath)).once(); +// // }); +// }); - test("Updater: deleteUploads: call UploadMgr and api to delete", async () => { - let coreState = initState(); - const UploadMgrClass = mock(UploadMgr); - const uploadMgr = instance(UploadMgrClass); - setUploadMgr(uploadMgr); +// test("Updater: deleteUploads: call UploadMgr and api to delete", async () => { +// let coreState = initState(); +// const UploadMgrClass = mock(UploadMgr); +// const uploadMgr = instance(UploadMgrClass); +// setUploadMgr(uploadMgr); - // const updater = new Updater(); - const filesClientClass = mock(FilesClient); - when(filesClientClass.deleteUploading(anyString())).thenResolve({ - status: 200, - statusText: "", - data: "", - }); - const filesClient = instance(filesClientClass); - const usersClientClass = mock(UsersClient); - const usersClient = instance(usersClientClass); - updater().init(coreState); - updater().setClients(usersClient, filesClient); +// // const updater = new Updater(); +// const filesClientClass = mock(FilesClient); +// when(filesClientClass.deleteUploading(anyString())).thenResolve({ +// status: 200, +// statusText: "", +// data: "", +// }); +// const filesClient = instance(filesClientClass); +// const usersClientClass = mock(UsersClient); +// const usersClient = instance(usersClientClass); +// updater().init(coreState); +// updater().setClients(usersClient, filesClient); - const filePath = "./path/file"; - updater().deleteUpload(filePath); +// const filePath = "./path/file"; +// updater().deleteUpload(filePath); - verify(filesClientClass.deleteUploading(filePath)).once(); - verify(UploadMgrClass.delete(filePath)).once(); - }); +// verify(filesClientClass.deleteUploading(filePath)).once(); +// verify(UploadMgrClass.delete(filePath)).once(); +// }); - test("Updater: delete", async () => { - const tests = [ - { - dirPath: "path/path2", - items: [ - { - name: "file", - size: 1, - modTime: "1-1", - isDir: false, - }, - { - name: "folder", - size: 0, - modTime: "1-1", - isDir: true, - }, - ], - selected: { - file: true, - }, - listResp: { - status: 200, - statusText: "", - data: { - metadatas: [ - { - name: "folder", - size: 0, - modTime: "1-1", - isDir: true, - }, - ], - }, - }, - filePath: "path/file", - }, - ]; +// test("Updater: delete", async () => { +// const tests = [ +// { +// dirPath: "path/path2", +// items: [ +// { +// name: "file", +// size: 1, +// modTime: "1-1", +// isDir: false, +// }, +// { +// name: "folder", +// size: 0, +// modTime: "1-1", +// isDir: true, +// }, +// ], +// selected: { +// file: true, +// }, +// listResp: { +// status: 200, +// statusText: "", +// data: { +// metadatas: [ +// { +// name: "folder", +// size: 0, +// modTime: "1-1", +// isDir: true, +// }, +// ], +// }, +// }, +// filePath: "path/file", +// }, +// ]; - const usersClient = new MockUsersClient(""); - const filesClient = new MockFilesClient(""); - for (let i = 0; i < tests.length; i++) { - const tc = tests[i]; - // const updater = new Updater(); - updater().setClients(usersClient, filesClient); - filesClient.listMock(makePromise(tc.listResp)); - filesClient.deleteMock(makeNumberResponse(200)); - const coreState = newWithWorker(mockWorker); - updater().init(coreState); +// const usersClient = new MockUsersClient(""); +// const filesClient = new MockFilesClient(""); +// for (let i = 0; i < tests.length; i++) { +// const tc = tests[i]; +// // const updater = new Updater(); +// updater().setClients(usersClient, filesClient); +// filesClient.listMock(makePromise(tc.listResp)); +// filesClient.deleteMock(makeNumberResponse(200)); +// const coreState = newWithWorker(mockWorker); +// updater().init(coreState); - await updater().delete( - List(tc.dirPath.split("/")), - List(tc.items), - Map(tc.selected) - ); +// await updater().delete( +// List(tc.dirPath.split("/")), +// List(tc.items), +// Map(tc.selected) +// ); - const newState = updater().updateBrowser(coreState); +// const newState = updater().updateBrowser(coreState); - // TODO: check inputs of delete - newState.panel.browser.items.forEach((item, i) => { - expect(item.name).toEqual(tc.listResp.data.metadatas[i].name); - expect(item.size).toEqual(tc.listResp.data.metadatas[i].size); - expect(item.modTime).toEqual(tc.listResp.data.metadatas[i].modTime); - expect(item.isDir).toEqual(tc.listResp.data.metadatas[i].isDir); - }); - } - }); +// // TODO: check inputs of delete +// newState.panel.browser.items.forEach((item, i) => { +// expect(item.name).toEqual(tc.listResp.data.metadatas[i].name); +// expect(item.size).toEqual(tc.listResp.data.metadatas[i].size); +// expect(item.modTime).toEqual(tc.listResp.data.metadatas[i].modTime); +// expect(item.isDir).toEqual(tc.listResp.data.metadatas[i].isDir); +// }); +// } +// }); - test("Updater: setItems", async () => { - const tests = [ - { - listResp: { - status: 200, - statusText: "", - data: { - metadatas: [ - { - name: "file", - size: 1, - modTime: "1-1", - isDir: false, - }, - { - name: "folder", - size: 0, - modTime: "1-1", - isDir: true, - }, - ], - }, - }, - filePath: "path/file", - }, - ]; +// test("Updater: setItems", async () => { +// const tests = [ +// { +// listResp: { +// status: 200, +// statusText: "", +// data: { +// metadatas: [ +// { +// name: "file", +// size: 1, +// modTime: "1-1", +// isDir: false, +// }, +// { +// name: "folder", +// size: 0, +// modTime: "1-1", +// isDir: true, +// }, +// ], +// }, +// }, +// filePath: "path/file", +// }, +// ]; - const usersClient = new MockUsersClient(""); - const filesClient = new MockFilesClient(""); +// const usersClient = new MockUsersClient(""); +// const filesClient = new MockFilesClient(""); - for (let i = 0; i < tests.length; i++) { - const tc = tests[i]; +// for (let i = 0; i < tests.length; i++) { +// const tc = tests[i]; - filesClient.listMock(makePromise(tc.listResp)); - updater().setClients(usersClient, filesClient); - const coreState = newWithWorker(mockWorker); - updater().init(coreState); +// filesClient.listMock(makePromise(tc.listResp)); +// updater().setClients(usersClient, filesClient); +// const coreState = newWithWorker(mockWorker); +// updater().init(coreState); - await updater().setItems(List(tc.filePath.split("/"))); - const newState = updater().updateBrowser(coreState); +// await updater().setItems(List(tc.filePath.split("/"))); +// const newState = updater().updateBrowser(coreState); - newState.panel.browser.items.forEach((item, i) => { - expect(item.name).toEqual(tc.listResp.data.metadatas[i].name); - expect(item.size).toEqual(tc.listResp.data.metadatas[i].size); - expect(item.modTime).toEqual(tc.listResp.data.metadatas[i].modTime); - expect(item.isDir).toEqual(tc.listResp.data.metadatas[i].isDir); - }); - } - }); +// newState.panel.browser.items.forEach((item, i) => { +// expect(item.name).toEqual(tc.listResp.data.metadatas[i].name); +// expect(item.size).toEqual(tc.listResp.data.metadatas[i].size); +// expect(item.modTime).toEqual(tc.listResp.data.metadatas[i].modTime); +// expect(item.isDir).toEqual(tc.listResp.data.metadatas[i].isDir); +// }); +// } +// }); - test("Updater: moveHere", async () => { - const tests = [ - { - dirPath1: "path/path1", - dirPath2: "path/path2", - selected: { - file1: true, - file2: true, - }, - listResp: { - status: 200, - statusText: "", - data: { - metadatas: [ - { - name: "file1", - size: 1, - modTime: "1-1", - isDir: false, - }, - { - name: "file2", - size: 2, - modTime: "1-1", - isDir: false, - }, - ], - }, - }, - }, - ]; +// test("Updater: moveHere", async () => { +// const tests = [ +// { +// dirPath1: "path/path1", +// dirPath2: "path/path2", +// selected: { +// file1: true, +// file2: true, +// }, +// listResp: { +// status: 200, +// statusText: "", +// data: { +// metadatas: [ +// { +// name: "file1", +// size: 1, +// modTime: "1-1", +// isDir: false, +// }, +// { +// name: "file2", +// size: 2, +// modTime: "1-1", +// isDir: false, +// }, +// ], +// }, +// }, +// }, +// ]; - const usersClient = new MockUsersClient(""); - const filesClient = new MockFilesClient(""); - for (let i = 0; i < tests.length; i++) { - const tc = tests[i]; +// const usersClient = new MockUsersClient(""); +// const filesClient = new MockFilesClient(""); +// for (let i = 0; i < tests.length; i++) { +// const tc = tests[i]; - filesClient.listMock(makePromise(tc.listResp)); - filesClient.moveMock(makeNumberResponse(200)); - updater().setClients(usersClient, filesClient); +// filesClient.listMock(makePromise(tc.listResp)); +// filesClient.moveMock(makeNumberResponse(200)); +// updater().setClients(usersClient, filesClient); - const coreState = newWithWorker(mockWorker); - updater().init(coreState); - await updater().moveHere(tc.dirPath1, tc.dirPath2, Map(tc.selected)); +// const coreState = newWithWorker(mockWorker); +// updater().init(coreState); +// await updater().moveHere(tc.dirPath1, tc.dirPath2, Map(tc.selected)); - const newState = updater().updateBrowser(coreState); +// const newState = updater().updateBrowser(coreState); - // TODO: check inputs of move - newState.panel.browser.items.forEach((item, i) => { - expect(item.name).toEqual(tc.listResp.data.metadatas[i].name); - expect(item.size).toEqual(tc.listResp.data.metadatas[i].size); - expect(item.modTime).toEqual(tc.listResp.data.metadatas[i].modTime); - expect(item.isDir).toEqual(tc.listResp.data.metadatas[i].isDir); - }); - } - }); +// // TODO: check inputs of move +// newState.panel.browser.items.forEach((item, i) => { +// expect(item.name).toEqual(tc.listResp.data.metadatas[i].name); +// expect(item.size).toEqual(tc.listResp.data.metadatas[i].size); +// expect(item.modTime).toEqual(tc.listResp.data.metadatas[i].modTime); +// expect(item.isDir).toEqual(tc.listResp.data.metadatas[i].isDir); +// }); +// } +// }); - test("Browser: deleteUpload: tell uploader to deleteUpload and refreshUploadings", async () => { - let coreState = initState(); - addMockUpdate(coreState.panel.browser); - const component = new Browser(coreState.panel.browser); - const UpdaterClass = mock(Updater); - const mockUpdater = instance(UpdaterClass); - setUpdater(mockUpdater); - when(UpdaterClass.setItems(anything())).thenResolve(); - when(UpdaterClass.deleteUpload(anyString())).thenResolve(true); - when(UpdaterClass.refreshUploadings()).thenResolve(true); +// test("Browser: deleteUpload: tell uploader to deleteUpload and refreshUploadings", async () => { +// let coreState = initState(); +// addMockUpdate(coreState.panel.browser); +// const component = new Browser(coreState.panel.browser); +// const UpdaterClass = mock(Updater); +// const mockUpdater = instance(UpdaterClass); +// setUpdater(mockUpdater); +// when(UpdaterClass.setItems(anything())).thenResolve(); +// when(UpdaterClass.deleteUpload(anyString())).thenResolve(true); +// when(UpdaterClass.refreshUploadings()).thenResolve(true); - const filePath = "filePath"; - await component.deleteUpload(filePath); +// const filePath = "filePath"; +// await component.deleteUpload(filePath); - verify(UpdaterClass.deleteUpload(filePath)).once(); - verify(UpdaterClass.refreshUploadings()).once(); - }); +// verify(UpdaterClass.deleteUpload(filePath)).once(); +// verify(UpdaterClass.refreshUploadings()).once(); +// }); - test("Browser: stopUploading: tell updater to stopUploading", async () => { - let coreState = initState(); - addMockUpdate(coreState.panel.browser); - const component = new Browser(coreState.panel.browser); - const UpdaterClass = mock(Updater); - const mockUpdater = instance(UpdaterClass); - setUpdater(mockUpdater); - when(UpdaterClass.stopUploading(anyString())).thenReturn(); +// test("Browser: stopUploading: tell updater to stopUploading", async () => { +// let coreState = initState(); +// addMockUpdate(coreState.panel.browser); +// const component = new Browser(coreState.panel.browser); +// const UpdaterClass = mock(Updater); +// const mockUpdater = instance(UpdaterClass); +// setUpdater(mockUpdater); +// when(UpdaterClass.stopUploading(anyString())).thenReturn(); - const filePath = "filePath"; - component.stopUploading(filePath); +// const filePath = "filePath"; +// component.stopUploading(filePath); - verify(UpdaterClass.stopUploading(filePath)).once(); - }); -}); +// verify(UpdaterClass.stopUploading(filePath)).once(); +// }); +// }); diff --git a/src/client/web/src/components/__test__/pane_login.test.tsx b/src/client/web/src/components/__test__/pane_login.test.tsx index 65f3402..964774f 100644 --- a/src/client/web/src/components/__test__/pane_login.test.tsx +++ b/src/client/web/src/components/__test__/pane_login.test.tsx @@ -56,9 +56,9 @@ describe("AuthPane", () => { updater().setClients(usersClient, filesClient); updater().init(coreState); await updater().initIsAuthed(); - const newState = updater().updateAuthPane(coreState); + const newState = updater().updateLogin(coreState); - expect(newState.panel.authPane.authed).toEqual(tc.isAuthed); + expect(newState.login.authed).toEqual(tc.isAuthed); } }); }); diff --git a/src/client/web/src/components/__test__/panes.test.tsx b/src/client/web/src/components/__test__/panes.test.tsx index da366d0..5797ce4 100644 --- a/src/client/web/src/components/__test__/panes.test.tsx +++ b/src/client/web/src/components/__test__/panes.test.tsx @@ -32,7 +32,7 @@ describe("Panes", () => { ]; const setState = (patch: any, state: ICoreState): ICoreState => { - state.panel.panes = patch.panes; + state.panes = patch.panes; return state; }; @@ -40,7 +40,12 @@ describe("Panes", () => { const preState = setState(tc.preState, initState()); const postState = setState(tc.postState, initState()); - const component = new Panes(preState.panel.panes); + const component = new Panes({ + panes: preState.panes, + admin: preState.admin, + login: preState.login, + update: mockUpdate, + }); updater().init(preState); component.closePane(); diff --git a/src/client/web/src/components/__test__/root_frame.test.tsx b/src/client/web/src/components/__test__/root_frame.test.tsx deleted file mode 100644 index 7bd99ab..0000000 --- a/src/client/web/src/components/__test__/root_frame.test.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { Set } from "immutable"; - -import { ICoreState, initState } from "../core_state"; -import { RootFrame } from "../root_frame"; -// import { Updater } from "../panes"; -import { updater } from "../state_updater"; - -xdescribe("RootFrame", () => { - test("component: showSettings", async () => { - interface TestCase { - preState: ICoreState; - postState: ICoreState; - } - - const mockUpdate = (apply: (prevState: ICoreState) => ICoreState): void => {}; - const tcs: any = [ - { - preState: { - displaying: "", - panes: { - displaying: "", - paneNames: Set(["settings", "login"]), - }, - update: mockUpdate, - }, - postState: { - displaying: "settings", - panes: { - displaying: "settings", - paneNames: Set(["settings", "login"]), - }, - update: mockUpdate, - }, - }, - ]; - - const setState = (patch: any, state: ICoreState): ICoreState => { - return { ...state, panel: { ...state.panel, ...patch } }; - }; - - tcs.forEach((tc: TestCase) => { - const preState = setState(tc.preState, initState()); - const postState = setState(tc.postState, initState()); - - const component = new RootFrame(preState.panel); - updater().init(preState); - - // component.showSettings(); - expect(updater().props).toEqual(postState); - }); - }); -}); diff --git a/src/client/web/src/components/browser.updater.ts b/src/client/web/src/components/browser.updater.ts deleted file mode 100644 index d5272c7..0000000 --- a/src/client/web/src/components/browser.updater.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { List, Map } from "immutable"; - -import { ICoreState } from "./core_state"; -import { Props, getItemPath } from "./browser"; -import { - IUsersClient, - IFilesClient, - MetadataResp, - UploadInfo, -} from "../client"; -import { FilesClient } from "../client/files"; -import { UsersClient } from "../client/users"; -import { UploadEntry } from "../worker/interface"; -import { Up } from "../worker/upload_mgr"; - -export class Updater { - props: Props; - private usersClient: IUsersClient = new UsersClient(""); - private filesClient: IFilesClient = new FilesClient(""); - - init = (props: Props) => (this.props = { ...props }); - setClients(usersClient: IUsersClient, filesClient: IFilesClient) { - this.usersClient = usersClient; - this.filesClient = filesClient; - } - - initUploads = () => { - this.props.uploadings.forEach((entry) => { - Up().addStopped(entry.realFilePath, entry.uploaded, entry.size); - }); - // this.setUploadings(Up().list()); - }; - - addUploads = (fileList: List) => { - fileList.forEach((file) => { - const filePath = getItemPath(this.props.dirPath.join("/"), file.name); - // do not wait for the promise - Up().add(file, filePath); - }); - this.setUploadings(Up().list()); - }; - - deleteUpload = async (filePath: string): Promise => { - Up().delete(filePath); - const resp = await this.filesClient.deleteUploading(filePath); - return resp.status === 200; - }; - - setUploadings = (infos: Map) => { - this.props.uploadings = List( - infos.valueSeq().map((v: UploadEntry): UploadInfo => { - return { - realFilePath: v.filePath, - size: v.size, - uploaded: v.uploaded, - }; - }) - ); - }; - - addSharing = async (): Promise => { - const dirPath = this.props.dirPath.join("/"); - const resp = await this.filesClient.addSharing(dirPath); - return resp.status === 200; - }; - - deleteSharing = async (dirPath: string): Promise => { - const resp = await this.filesClient.deleteSharing(dirPath); - return resp.status === 200; - }; - - isSharing = async (dirPath: string): Promise => { - const resp = await this.filesClient.isSharing(dirPath); - this.props.isSharing = resp.status === 200; - return resp.status === 200; // TODO: differentiate 404 and error - }; - - setSharing = (shared: boolean) => { - this.props.isSharing = shared; - }; - - listSharings = async (): Promise => { - const resp = await this.filesClient.listSharings(); - this.props.sharings = - resp.status === 200 - ? List(resp.data.sharingDirs) - : this.props.sharings; - return resp.status === 200; - }; - - refreshUploadings = async (): Promise => { - const luResp = await this.filesClient.listUploadings(); - - this.props.uploadings = - luResp.status === 200 - ? List(luResp.data.uploadInfos) - : this.props.uploadings; - return luResp.status === 200; - }; - - stopUploading = (filePath: string) => { - Up().stop(filePath); - }; - - mkDir = async (dirPath: string): Promise => { - const resp = await this.filesClient.mkdir(dirPath); - if (resp.status !== 200) { - alert(`failed to make dir ${dirPath}`); - } - }; - - delete = async ( - dirParts: List, - items: List, - selectedItems: Map - ): Promise => { - const delRequests = items - .filter((item) => { - return selectedItems.has(item.name); - }) - .map(async (selectedItem: MetadataResp): Promise => { - const itemPath = getItemPath(dirParts.join("/"), selectedItem.name); - const resp = await this.filesClient.delete(itemPath); - return resp.status === 200 ? "" : selectedItem.name; - }); - - const failedFiles = await Promise.all(delRequests); - failedFiles.forEach((failedFile) => { - if (failedFile !== "") { - alert(`failed to delete ${failedFile}`); - } - }); - return this.setItems(dirParts); - }; - - setItems = async (dirParts: List): Promise => { - const dirPath = dirParts.join("/"); - const listResp = await this.filesClient.list(dirPath); - - this.props.dirPath = dirParts; - this.props.items = - listResp.status === 200 - ? List(listResp.data.metadatas) - : this.props.items; - }; - - setHomeItems = async (): Promise => { - const listResp = await this.filesClient.listHome(); - - this.props.dirPath = List(listResp.data.cwd.split("/")); - this.props.items = - listResp.status === 200 - ? List(listResp.data.metadatas) - : this.props.items; - }; - - moveHere = async ( - srcDir: string, - dstDir: string, - selectedItems: Map - ): Promise => { - const moveRequests = List(selectedItems.keys()).map( - async (itemName: string): Promise => { - const oldPath = getItemPath(srcDir, itemName); - const newPath = getItemPath(dstDir, itemName); - const resp = await this.filesClient.move(oldPath, newPath); - return resp.status === 200 ? "" : itemName; - } - ); - - const failedFiles = await Promise.all(moveRequests); - failedFiles.forEach((failedItem) => { - if (failedItem !== "") { - alert(`failed to move ${failedItem}`); - } - }); - - return this.setItems(List(dstDir.split("/"))); - }; - - setBrowser = (prevState: ICoreState): ICoreState => { - return { - ...prevState, - panel: { - ...prevState.panel, - browser: { - dirPath: this.props.dirPath, - isSharing: this.props.isSharing, - items: this.props.items, - uploadings: this.props.uploadings, - sharings: this.props.sharings, - uploadFiles: this.props.uploadFiles, - uploadValue: this.props.uploadValue, - isVertical: this.props.isVertical, - }, - }, - }; - }; -} - -export let browserUpdater = new Updater(); -export const updater = (): Updater => { - return browserUpdater; -}; -export const setUpdater = (updater: Updater) => { - browserUpdater = updater; -}; diff --git a/src/client/web/src/components/core_state.ts b/src/client/web/src/components/core_state.ts index 7cc92da..0b2e853 100644 --- a/src/client/web/src/components/core_state.ts +++ b/src/client/web/src/components/core_state.ts @@ -3,15 +3,25 @@ import { List, Set, Map } from "immutable"; import BgWorker from "../worker/upload.bg.worker"; import { FgWorker } from "../worker/upload.fg.worker"; -import { Props as PanelProps } from "./root_frame"; +// import { Props as PanelProps } from "./root_frame"; +import { Props as BrowserProps } from "./browser"; +import { PanesProps as PanesProps } from "./panes"; +import { Props as LoginProps } from "./pane_login"; +import { Props as AdminProps } from "./pane_admin"; +import { Props as SettingsProps } from "./pane_settings"; + import { Item } from "./browser"; import { UploadInfo, User } from "../client"; import { initUploadMgr, IWorker } from "../worker/upload_mgr"; - export interface ICoreState { - panel: PanelProps; + // panel: PanelProps; isVertical: boolean; + browser: BrowserProps; + panes: PanesProps; + login: LoginProps; + admin: AdminProps; + // settings: SettingsProps; } export function newWithWorker(worker: IWorker): ICoreState { @@ -29,40 +39,32 @@ export function newState(): ICoreState { export function initState(): ICoreState { return { isVertical: isVertical(), - panel: { + browser: { + isVertical: isVertical(), + dirPath: List(["."]), + items: List([]), + sharings: List([]), + isSharing: false, + uploadings: List([]), + uploadValue: "", + uploadFiles: List([]), + }, + panes: { + userRole: "", displaying: "browser", - authPane: { - authed: false, - captchaID: "", - }, - browser: { - isVertical: isVertical(), - dirPath: List(["."]), - items: List([]), - sharings: List([]), - isSharing: false, - uploadings: List([]), - uploadValue: "", - uploadFiles: List([]), - }, - panes: { - userRole: "", - displaying: "", - paneNames: Set(["settings", "login", "admin"]), - login: { - authed: false, - captchaID: "", - }, - admin: { - users: Map(), - roles: Set(), - }, - }, + paneNames: Set(["settings", "login", "admin"]), + }, + login: { + authed: false, + captchaID: "", + }, + admin: { + users: Map(), + roles: Set(), }, }; } - export function isVertical(): boolean { return window.innerWidth <= window.innerHeight; -} \ No newline at end of file +} diff --git a/src/client/web/src/components/pane_login.tsx b/src/client/web/src/components/pane_login.tsx index f66d18e..52acaa5 100644 --- a/src/client/web/src/components/pane_login.tsx +++ b/src/client/web/src/components/pane_login.tsx @@ -46,7 +46,7 @@ export class AuthPane extends React.Component { updater() .initIsAuthed() .then(() => { - this.update(updater().updateAuthPane); + this.update(updater().updateLogin); }); }; @@ -60,7 +60,7 @@ export class AuthPane extends React.Component { ) .then((ok: boolean) => { if (ok) { - this.update(updater().updateAuthPane); + this.update(updater().updateLogin); this.setState({ user: "", pwd: "" }); // close all the panes updater().displayPane(""); @@ -78,7 +78,7 @@ export class AuthPane extends React.Component { }) .then(() => { return updater().isSharing( - updater().props.panel.browser.dirPath.join("/") + updater().props.browser.dirPath.join("/") ); }) .then(() => { @@ -92,7 +92,7 @@ export class AuthPane extends React.Component { logout = () => { updater().logout().then((ok: boolean) => { if (ok) { - this.update(updater().updateAuthPane); + this.update(updater().updateLogin); } else { alert("Failed to logout."); } diff --git a/src/client/web/src/components/panes.tsx b/src/client/web/src/components/panes.tsx index 336ac0a..2093078 100644 --- a/src/client/web/src/components/panes.tsx +++ b/src/client/web/src/components/panes.tsx @@ -7,10 +7,13 @@ import { PaneSettings } from "./pane_settings"; import { AdminPane, Props as AdminPaneProps } from "./pane_admin"; import { AuthPane, Props as AuthPaneProps } from "./pane_login"; -export interface Props { - userRole: string; +export interface PanesProps { displaying: string; + userRole: string; paneNames: Set; +} +export interface Props { + panes: PanesProps; login: AuthPaneProps; admin: AdminPaneProps; update?: (updater: (prevState: ICoreState) => ICoreState) => void; @@ -23,14 +26,14 @@ export class Panes extends React.Component { } closePane = () => { - if (this.props.displaying !== "login") { + if (this.props.panes.displaying !== "login") { updater().displayPane(""); this.props.update(updater().updatePanes); } }; render() { - let displaying = this.props.displaying; + let displaying = this.props.panes.displaying; if (!this.props.login.authed) { // TODO: use constant instead // TODO: control this with props @@ -50,7 +53,7 @@ export class Panes extends React.Component { ), }); - if (this.props.userRole === "admin") { + if (this.props.panes.userRole === "admin") { panesMap = panesMap.set( "admin", ICoreState) => void; } @@ -25,10 +23,8 @@ export class RootFrame extends React.Component {
diff --git a/src/client/web/src/components/state_mgr.tsx b/src/client/web/src/components/state_mgr.tsx index 9ed3221..232fed6 100644 --- a/src/client/web/src/components/state_mgr.tsx +++ b/src/client/web/src/components/state_mgr.tsx @@ -29,7 +29,7 @@ export class StateMgr extends React.Component { if (!ok) { alert("failed to get captcha id"); } else { - this.update(updater().updateAuthPane); + this.update(updater().updateLogin); } }); @@ -48,9 +48,7 @@ export class StateMgr extends React.Component { return updater().initUploads(); }) .then(() => { - return updater().isSharing( - updater().props.panel.browser.dirPath.join("/") - ); + return updater().isSharing(updater().props.browser.dirPath.join("/")); }) .then(() => { return updater().listSharings(); @@ -62,13 +60,13 @@ export class StateMgr extends React.Component { return updater().self(); }) .then(() => { - if (updater().props.panel.panes.userRole === "admin") { + if (updater().props.panes.userRole === "admin") { // TODO: remove hardcode return updater().listRoles(); } }) .then(() => { - if (updater().props.panel.panes.userRole === "admin") { + if (updater().props.panes.userRole === "admin") { // TODO: remove hardcode return updater().listUsers(); } @@ -85,11 +83,13 @@ export class StateMgr extends React.Component { render() { return ( ); } diff --git a/src/client/web/src/components/state_updater.ts b/src/client/web/src/components/state_updater.ts index cea377a..e8f76a4 100644 --- a/src/client/web/src/components/state_updater.ts +++ b/src/client/web/src/components/state_updater.ts @@ -28,7 +28,7 @@ export class Updater { } initUploads = () => { - this.props.panel.browser.uploadings.forEach((entry) => { + this.props.browser.uploadings.forEach((entry) => { Up().addStopped(entry.realFilePath, entry.uploaded, entry.size); }); // this.setUploadings(Up().list()); @@ -37,7 +37,7 @@ export class Updater { addUploads = (fileList: List) => { fileList.forEach((file) => { const filePath = getItemPath( - this.props.panel.browser.dirPath.join("/"), + this.props.browser.dirPath.join("/"), file.name ); // do not wait for the promise @@ -53,7 +53,7 @@ export class Updater { }; setUploadings = (infos: Map) => { - this.props.panel.browser.uploadings = List( + this.props.browser.uploadings = List( infos.valueSeq().map((v: UploadEntry): UploadInfo => { return { realFilePath: v.filePath, @@ -65,7 +65,7 @@ export class Updater { }; addSharing = async (): Promise => { - const dirPath = this.props.panel.browser.dirPath.join("/"); + const dirPath = this.props.browser.dirPath.join("/"); const resp = await this.filesClient.addSharing(dirPath); return resp.status === 200; }; @@ -77,30 +77,30 @@ export class Updater { isSharing = async (dirPath: string): Promise => { const resp = await this.filesClient.isSharing(dirPath); - this.props.panel.browser.isSharing = resp.status === 200; + this.props.browser.isSharing = resp.status === 200; return resp.status === 200; // TODO: differentiate 404 and error }; setSharing = (shared: boolean) => { - this.props.panel.browser.isSharing = shared; + this.props.browser.isSharing = shared; }; listSharings = async (): Promise => { const resp = await this.filesClient.listSharings(); - this.props.panel.browser.sharings = + this.props.browser.sharings = resp.status === 200 ? List(resp.data.sharingDirs) - : this.props.panel.browser.sharings; + : this.props.browser.sharings; return resp.status === 200; }; refreshUploadings = async (): Promise => { const luResp = await this.filesClient.listUploadings(); - this.props.panel.browser.uploadings = + this.props.browser.uploadings = luResp.status === 200 ? List(luResp.data.uploadInfos) - : this.props.panel.browser.uploadings; + : this.props.browser.uploadings; return luResp.status === 200; }; @@ -143,23 +143,21 @@ export class Updater { const dirPath = dirParts.join("/"); const listResp = await this.filesClient.list(dirPath); - this.props.panel.browser.dirPath = dirParts; - this.props.panel.browser.items = + this.props.browser.dirPath = dirParts; + this.props.browser.items = listResp.status === 200 ? List(listResp.data.metadatas) - : this.props.panel.browser.items; + : this.props.browser.items; }; setHomeItems = async (): Promise => { const listResp = await this.filesClient.listHome(); - this.props.panel.browser.dirPath = List( - listResp.data.cwd.split("/") - ); - this.props.panel.browser.items = + this.props.browser.dirPath = List(listResp.data.cwd.split("/")); + this.props.browser.items = listResp.status === 200 ? List(listResp.data.metadatas) - : this.props.panel.browser.items; + : this.props.browser.items; }; moveHere = async ( @@ -189,11 +187,11 @@ export class Updater { displayPane = (paneName: string) => { if (paneName === "") { // hide all panes - this.props.panel.panes.displaying = ""; + this.props.panes.displaying = ""; } else { - const pane = this.props.panel.panes.paneNames.get(paneName); + const pane = this.props.panes.paneNames.get(paneName); if (pane != null) { - this.props.panel.panes.displaying = paneName; + this.props.panes.displaying = paneName; } else { alert(`dialgos: pane (${paneName}) not found`); } @@ -203,7 +201,7 @@ export class Updater { self = async (): Promise => { const resp = await this.usersClient.self(); if (resp.status === 200) { - this.props.panel.panes.userRole = resp.data.role; + this.props.panes.userRole = resp.data.role; return true; } return false; @@ -241,7 +239,7 @@ export class Updater { lsRes.users.forEach((user: User) => { users = users.set(user.name, user); }); - this.props.panel.panes.admin.users = users; + this.props.admin.users = users; return true; }; @@ -268,7 +266,7 @@ export class Updater { Object.keys(lsRes.roles).forEach((role: string) => { roles = roles.add(role); }); - this.props.panel.panes.admin.roles = roles; + this.props.admin.roles = roles; return true; }; @@ -309,13 +307,13 @@ export class Updater { }; setAuthed = (isAuthed: boolean) => { - this.props.panel.authPane.authed = isAuthed; + this.props.login.authed = isAuthed; }; getCaptchaID = async (): Promise => { return this.usersClient.getCaptchaID().then((resp) => { if (resp.status === 200) { - this.props.panel.authPane.captchaID = resp.data.id; + this.props.login.captchaID = resp.data.id; } return resp.status === 200; }); @@ -329,38 +327,29 @@ export class Updater { updateBrowser = (prevState: ICoreState): ICoreState => { return { ...prevState, - panel: { - ...prevState.panel, - browser: { - dirPath: this.props.panel.browser.dirPath, - isSharing: this.props.panel.browser.isSharing, - items: this.props.panel.browser.items, - uploadings: this.props.panel.browser.uploadings, - sharings: this.props.panel.browser.sharings, - uploadFiles: this.props.panel.browser.uploadFiles, - uploadValue: this.props.panel.browser.uploadValue, - isVertical: this.props.panel.browser.isVertical, - }, - }, + browser: { ...prevState.browser, ...this.props.browser }, }; }; updatePanes = (prevState: ICoreState): ICoreState => { return { ...prevState, - panel: { - ...prevState.panel, - panes: { ...prevState.panel.panes, ...this.props.panel.panes }, - }, + panes: { ...prevState.panes, ...this.props.panes }, }; }; - updateAuthPane = (preState: ICoreState): ICoreState => { - preState.panel.authPane = { - ...preState.panel.authPane, - ...this.props.panel.authPane, + updateLogin = (prevState: ICoreState): ICoreState => { + return { + ...prevState, + login: { ...prevState.login, ...this.props.login }, + }; + }; + + updateAdmin = (prevState: ICoreState): ICoreState => { + return { + ...prevState, + admin: { ...prevState.admin, ...this.props.admin }, }; - return preState; }; }