fix(fe/core_state): refactor init process and add initUITree step

This commit is contained in:
hexxa 2021-12-10 21:51:18 +08:00 committed by Hexxa
parent a2f8b2263c
commit cc86c83066
5 changed files with 167 additions and 50 deletions

View file

@ -3,7 +3,13 @@ import { List, Set, Map } from "immutable";
import { initMockWorker } from "../../test/helpers";
import { User, UploadInfo } from "../../client";
import { AuthPane } from "../pane_login";
import { ICoreState, newState } from "../core_state";
import {
ICoreState,
newState,
sharingCtrl,
ctrlOn,
ctrlOff,
} from "../core_state";
import { updater } from "../state_updater";
import { UploadState, UploadEntry } from "../../worker/interface";
import { MockUsersClient, resps as usersResps } from "../../client/users_mock";
@ -16,7 +22,7 @@ import { settingsTabsCtrl } from "../dialog_settings";
describe("Login", () => {
initMockWorker();
test("login", async () => {
test("login as admin without sharing", async () => {
const coreState = newState();
const pane = new AuthPane({
login: coreState.login,
@ -113,8 +119,9 @@ describe("Login", () => {
control: {
controls: Map<string, string>({
[panelTabs]: "filesPanel",
[settingsDialogCtrl]: "off",
[settingsDialogCtrl]: ctrlOff,
[settingsTabsCtrl]: "preferencePane",
[sharingCtrl]: ctrlOff,
}),
options: Map<string, Set<string>>({
[panelTabs]: Set<string>([
@ -122,8 +129,9 @@ describe("Login", () => {
"uploadingsPanel",
"sharingsPanel",
]),
[settingsDialogCtrl]: Set<string>(["on", "off"]),
[settingsDialogCtrl]: Set<string>([ctrlOn, ctrlOff]),
[settingsTabsCtrl]: Set<string>(["preferencePane", "managementPane"]),
[sharingCtrl]: Set<string>([ctrlOn, ctrlOff]),
}),
},
});

View file

@ -16,6 +16,7 @@ import { MsgPackage } from "../../i18n/msger";
describe("State Manager", () => {
initMockWorker();
const emptyQuery = new URLSearchParams("");
test("initUpdater for admin", async () => {
const usersCl = new MockUsersClient("");
@ -33,7 +34,7 @@ describe("State Manager", () => {
};
const coreState = newState();
await mgr.initUpdater(coreState);
await mgr.initUpdater(coreState, emptyQuery);
// browser
expect(coreState.filesInfo.dirPath.join("/")).toEqual("mock_home/files");
@ -161,11 +162,14 @@ describe("State Manager", () => {
mgr.update = (apply: (prevState: ICoreState) => ICoreState): void => {
// no op
};
await mgr.initUpdater(coreState);
const sharingPath = "sharingPath/files";
const query = new URLSearchParams(`?dir=${sharingPath}`);
await mgr.initUpdater(coreState, query);
// browser
// TODO: mock query to get dir parm
expect(coreState.filesInfo.dirPath.join("/")).toEqual("mock_home/files");
expect(coreState.filesInfo.dirPath.join("/")).toEqual(sharingPath);
expect(coreState.filesInfo.isSharing).toEqual(true);
expect(coreState.filesInfo.items).toEqual(
List(filesResps.listHomeMockResp.data.metadatas)

View file

@ -1,7 +1,8 @@
import { List, Set, Map } from "immutable";
import { UploadEntry } from "../worker/interface";
import { MsgPackage } from "../i18n/msger";
import { User, MetadataResp } from "../client";
import { settingsDialogCtrl } from "./layers";
import { FilesProps } from "./panel_files";
import { UploadingsProps } from "./panel_uploadings";
@ -10,9 +11,11 @@ import { controlName as panelTabs } from "./root_frame";
import { settingsTabsCtrl } from "./dialog_settings";
import { LoginProps } from "./pane_login";
import { AdminProps } from "./pane_admin";
import { MsgPackage } from "../i18n/msger";
import { User, MetadataResp } from "../client";
export const ctrlHidden = "hidden";
export const ctrlOn = "on";
export const ctrlOff = "off";
export const sharingCtrl = "sharingCtrl";
export interface MsgProps {
lan: string;
pkg: Map<string, string>;
@ -108,6 +111,7 @@ export function initState(): ICoreState {
[panelTabs]: "filesPanel",
[settingsDialogCtrl]: "off",
[settingsTabsCtrl]: "preferencePane",
[sharingCtrl]: "off",
}),
options: Map<string, Set<string>>({
[panelTabs]: Set<string>([
@ -117,6 +121,7 @@ export function initState(): ICoreState {
]),
[settingsDialogCtrl]: Set<string>(["on", "off"]),
[settingsTabsCtrl]: Set<string>(["preferencePane", "managementPane"]),
[sharingCtrl]: Set<string>(["on", "off"]),
}),
},
},

View file

@ -25,7 +25,9 @@ export class StateMgr extends React.Component<Props, State, {}> {
const worker = window.Worker == null ? new FgWorker() : new BgWorker();
initUploadMgr(worker);
this.state = newState();
this.initUpdater(this.state); // don't await
const query = new URLSearchParams(document.location.search.substring(1));
this.initUpdater(this.state, query); // don't await
}
setUsersClient = (client: IUsersClient) => {
@ -40,7 +42,10 @@ export class StateMgr extends React.Component<Props, State, {}> {
this.settingsClient = client;
};
initUpdater = async (state: ICoreState): Promise<void> => {
initUpdater = async (
state: ICoreState,
query: URLSearchParams
): Promise<void> => {
updater().init(state);
if (
this.usersClient == null ||
@ -56,9 +61,8 @@ export class StateMgr extends React.Component<Props, State, {}> {
this.settingsClient
);
const params = new URLSearchParams(document.location.search.substring(1));
return updater()
.initAll(params)
.initAll(query)
.then(() => {
this.update(updater().updateFilesInfo);
this.update(updater().updateUploadingsInfo);

View file

@ -1,6 +1,12 @@
import { List, Map, Set } from "immutable";
import { ICoreState } from "./core_state";
import {
ICoreState,
sharingCtrl,
ctrlOn,
ctrlOff,
ctrlHidden,
} from "./core_state";
import { getItemPath } from "./browser";
import {
User,
@ -26,6 +32,9 @@ import { UploadEntry, UploadState } from "../worker/interface";
import { Up } from "../worker/upload_mgr";
import { alertMsg } from "../common/env";
import { LocalStorage } from "../common/localstorage";
import { controlName as panelTabs } from "./root_frame";
import { settingsTabsCtrl } from "./dialog_settings";
import { settingsDialogCtrl } from "./layers";
import { MsgPackage, isValidLanPack } from "../i18n/msger";
@ -286,48 +295,135 @@ export class Updater {
return this.setItems(List<string>(dstDir.split("/")));
};
initAll = async (params: URLSearchParams): Promise<any> => {
return this.initIsAuthed()
.then(() => {
return this.self();
})
.then(() => {
const dir = params.get("dir");
if (dir != null && dir !== "") {
const dirPath = List(dir.split("/"));
return this.setItems(dirPath);
} else {
return this.setHomeItems();
initUITree = () => {
const isAuthed = this.props.login.authed;
const isSharing =
this.props.ui.control.controls.get(sharingCtrl) === ctrlOn;
if (isAuthed) {
this.props.ui.control.controls = Map<string, string>({
[panelTabs]: "filesPanel",
[settingsDialogCtrl]: ctrlOff,
[settingsTabsCtrl]: "preferencePane",
[sharingCtrl]: isSharing ? ctrlOn : ctrlOff,
});
this.props.ui.control.options = Map<string, Set<string>>({
[panelTabs]: Set<string>([
"filesPanel",
"uploadingsPanel",
"sharingsPanel",
]),
[settingsDialogCtrl]: Set<string>([ctrlOn, ctrlOff]),
[settingsTabsCtrl]: Set<string>(["preferencePane"]),
[sharingCtrl]: Set<string>([ctrlOn, ctrlOff]),
});
if (this.props.login.userRole == roleAdmin) {
this.props.ui.control.options = this.props.ui.control.options.set(
settingsTabsCtrl,
Set<string>(["preferencePane", "managementPane"])
);
}
})
.then(() => {
return this.isSharing(this.props.filesInfo.dirPath.join("/"));
})
.then(() => {
if (this.props.login.userRole !== roleVisitor) {
// init panels for authned users
} else {
if (isSharing) {
this.props.ui.control.controls = Map<string, string>({
[panelTabs]: "filesPanel",
[settingsDialogCtrl]: ctrlHidden,
[settingsTabsCtrl]: ctrlHidden,
[sharingCtrl]: ctrlOn,
});
this.props.ui.control.options = Map<string, Set<string>>({
[panelTabs]: Set<string>(["filesPanel"]),
[settingsDialogCtrl]: Set<string>([ctrlHidden]),
[settingsTabsCtrl]: Set<string>([ctrlHidden]),
[sharingCtrl]: Set<string>([ctrlOn]),
});
} else {
this.props.ui.control.controls = Map<string, string>({
[panelTabs]: ctrlHidden,
[settingsDialogCtrl]: ctrlHidden,
[settingsTabsCtrl]: ctrlHidden,
[sharingCtrl]: ctrlOff,
});
this.props.ui.control.options = Map<string, Set<string>>({
[panelTabs]: Set<string>([ctrlHidden]),
[settingsDialogCtrl]: Set<string>([ctrlHidden]),
[settingsTabsCtrl]: Set<string>([ctrlHidden]),
[sharingCtrl]: Set<string>([ctrlOff]),
});
}
}
};
initStateForVisitor = async (): Promise<any> => {
// TOOD: status is ignored, should return alert
return Promise.all([
this.getClientCfg(),
this.syncLan(),
this.isSharing(this.props.filesInfo.dirPath.join("/")),
]);
};
initStateForAuthedUser = async (): Promise<any> => {
// TOOD: status is ignored, should return alert
return Promise.all([
this.refreshUploadings(),
this.initUploads(),
this.listSharings(),
]);
}
};
initStateForAdmin = async (): Promise<any> => {
return this.initStateForVisitor()
.then(() => {
return this.initStateForAuthedUser();
})
.then(() => {
// init settings
return this.getClientCfg();
})
.then(() => {
// init i18n
// TOOD: status is ignored, should return alert
return this.fetchLanPack();
})
.then(() => {
// init admin content
if (this.props.login.userRole === roleAdmin) {
return Promise.all([this.listRoles(), this.listUsers()]);
});
};
syncCwd = async () => {
if (this.props.filesInfo.dirPath.size !== 0) {
return this.setItems(this.props.filesInfo.dirPath);
}
return;
return this.setHomeItems();
};
initCwd = async (params: URLSearchParams): Promise<any> => {
const dir = params.get("dir");
if (dir != null && dir !== "") {
const dirPath = List(dir.split("/"));
this.props.ui.control.controls = this.props.ui.control.controls.set(
sharingCtrl,
ctrlOn
);
this.props.filesInfo.dirPath = dirPath;
} else {
this.props.ui.control.controls = this.props.ui.control.controls.set(
sharingCtrl,
ctrlOff
);
this.props.filesInfo.dirPath = List([]);
}
};
initAll = async (params: URLSearchParams): Promise<any> => {
return Promise.all([this.self(), this.initIsAuthed(), this.initCwd(params)])
.then(() => {
this.initUITree();
})
.then(() => {
return this.syncCwd();
})
.then(() => {
if (this.props.login.userRole === roleAdmin) {
return this.initStateForAdmin();
} else if (this.props.login.userRole === roleVisitor) {
return this.initStateForVisitor();
}
return this.initStateForAuthedUser();
});
};
@ -572,7 +668,7 @@ export class Updater {
return resp.status;
};
fetchLanPack = async (): Promise<number> => {
syncLan = async (): Promise<number> => {
const url = this.props.login.preferences.lanPackURL;
if (url === "") {
const lan = this.props.login.preferences.lan;