feat(fe): enable customized language pack
This commit is contained in:
parent
5a44d9f125
commit
17f68ccdec
9 changed files with 209 additions and 22 deletions
|
@ -209,4 +209,11 @@ export class FilesClient extends BaseClient {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
download = (url: string): Promise<Response> => {
|
||||||
|
return this.do({
|
||||||
|
method: "get",
|
||||||
|
url,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ export interface FilesClientResps {
|
||||||
listSharingsMockResp?: Response<ListSharingsResp>;
|
listSharingsMockResp?: Response<ListSharingsResp>;
|
||||||
isSharingMockResp?: Response;
|
isSharingMockResp?: Response;
|
||||||
generateHashMockResp?: Response;
|
generateHashMockResp?: Response;
|
||||||
|
downloadMockResp: Response;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const resps = {
|
export const resps = {
|
||||||
|
@ -132,6 +133,11 @@ export const resps = {
|
||||||
},
|
},
|
||||||
isSharingMockResp: { status: 200, statusText: "", data: {} },
|
isSharingMockResp: { status: 200, statusText: "", data: {} },
|
||||||
generateHashMockResp: { status: 200, statusText: "", data: {} },
|
generateHashMockResp: { status: 200, statusText: "", data: {} },
|
||||||
|
downloadMockResp: {
|
||||||
|
status: 200,
|
||||||
|
statusText: "",
|
||||||
|
data: {},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export class MockFilesClient {
|
export class MockFilesClient {
|
||||||
|
@ -220,4 +226,8 @@ export class MockFilesClient {
|
||||||
generateHash = (filePath: string): Promise<Response> => {
|
generateHash = (filePath: string): Promise<Response> => {
|
||||||
return this.wrapPromise(this.resps.generateHashMockResp);
|
return this.wrapPromise(this.resps.generateHashMockResp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
download = (url: string): Promise<Response> => {
|
||||||
|
return this.wrapPromise(this.resps.downloadMockResp);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ export interface Preferences {
|
||||||
bg: BgConfig;
|
bg: BgConfig;
|
||||||
cssURL: string;
|
cssURL: string;
|
||||||
lanPackURL: string;
|
lanPackURL: string;
|
||||||
|
lan: string;
|
||||||
}
|
}
|
||||||
export interface User {
|
export interface User {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -131,6 +132,7 @@ export interface IFilesClient {
|
||||||
isSharing: (dirPath: string) => Promise<Response>;
|
isSharing: (dirPath: string) => Promise<Response>;
|
||||||
listSharings: () => Promise<Response<ListSharingsResp>>;
|
listSharings: () => Promise<Response<ListSharingsResp>>;
|
||||||
generateHash: (filePath: string) => Promise<Response>;
|
generateHash: (filePath: string) => Promise<Response>;
|
||||||
|
download: (url: string) => Promise<Response>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISettingsClient {
|
export interface ISettingsClient {
|
||||||
|
|
|
@ -80,8 +80,6 @@ export class AuthPane extends React.Component<Props, State, {}> {
|
||||||
this.update(updater().updatePanes);
|
this.update(updater().updatePanes);
|
||||||
this.update(updater().updateAdmin);
|
this.update(updater().updateAdmin);
|
||||||
this.update(updater().updateUI);
|
this.update(updater().updateUI);
|
||||||
|
|
||||||
updater().initLan();
|
|
||||||
this.update(updater().updateMsg);
|
this.update(updater().updateMsg);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -125,7 +125,16 @@ export class PaneSettings extends React.Component<Props, State, {}> {
|
||||||
|
|
||||||
setLan = (lan: string) => {
|
setLan = (lan: string) => {
|
||||||
updater().setLan(lan);
|
updater().setLan(lan);
|
||||||
this.props.update(updater().updateMsg);
|
updater()
|
||||||
|
.syncPreferences()
|
||||||
|
.then((status: number) => {
|
||||||
|
if (status === 200) {
|
||||||
|
alertMsg(this.props.msg.pkg.get("update.ok"));
|
||||||
|
} else {
|
||||||
|
alertMsg(this.props.msg.pkg.get("update.fail"));
|
||||||
|
}
|
||||||
|
this.props.update(updater().updateMsg);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -416,7 +425,6 @@ export class PaneSettings extends React.Component<Props, State, {}> {
|
||||||
])}
|
])}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -65,8 +65,6 @@ export class StateMgr extends React.Component<Props, State, {}> {
|
||||||
this.update(updater().updatePanes);
|
this.update(updater().updatePanes);
|
||||||
this.update(updater().updateAdmin);
|
this.update(updater().updateAdmin);
|
||||||
this.update(updater().updateUI);
|
this.update(updater().updateUI);
|
||||||
|
|
||||||
updater().initLan();
|
|
||||||
this.update(updater().updateMsg);
|
this.update(updater().updateMsg);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,7 +27,7 @@ import { Up } from "../worker/upload_mgr";
|
||||||
import { alertMsg } from "../common/env";
|
import { alertMsg } from "../common/env";
|
||||||
import { LocalStorage } from "../common/localstorage";
|
import { LocalStorage } from "../common/localstorage";
|
||||||
|
|
||||||
import { MsgPackage } from "../i18n/msger";
|
import { MsgPackage, isValidLanPack } from "../i18n/msger";
|
||||||
|
|
||||||
function getCookieLanKey(user: string) {
|
function getCookieLanKey(user: string) {
|
||||||
return `qs_${user}_lan`;
|
return `qs_${user}_lan`;
|
||||||
|
@ -359,6 +359,11 @@ export class Updater {
|
||||||
// init panes
|
// init panes
|
||||||
return this.initPanes();
|
return this.initPanes();
|
||||||
})
|
})
|
||||||
|
.then(() => {
|
||||||
|
// init i18n
|
||||||
|
// TOOD: status is ignored, should return alert
|
||||||
|
return this.fetchLanPack();
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// init admin content
|
// init admin content
|
||||||
if (this.props.login.userRole === roleAdmin) {
|
if (this.props.login.userRole === roleAdmin) {
|
||||||
|
@ -520,25 +525,19 @@ export class Updater {
|
||||||
return resp.status === 200;
|
return resp.status === 200;
|
||||||
};
|
};
|
||||||
|
|
||||||
initLan = () => {
|
|
||||||
const lanKey = getCookieLanKey(this.props.login.userName);
|
|
||||||
const lanSaved = LocalStorage.get(lanKey);
|
|
||||||
this.setLan(lanSaved === "" ? "en_US" : lanSaved);
|
|
||||||
};
|
|
||||||
|
|
||||||
setLan = (lan: string) => {
|
setLan = (lan: string) => {
|
||||||
const lanKey = getCookieLanKey(this.props.login.userName);
|
|
||||||
|
|
||||||
switch (lan) {
|
switch (lan) {
|
||||||
case "en_US":
|
case "en_US":
|
||||||
this.props.msg.lan = "en_US";
|
this.props.msg.lan = "en_US";
|
||||||
this.props.msg.pkg = MsgPackage.get(lan);
|
this.props.msg.pkg = MsgPackage.get(lan);
|
||||||
LocalStorage.set(lanKey, "en_US");
|
this.props.login.preferences.lan = "en_US";
|
||||||
|
this.props.login.preferences.lanPackURL = "";
|
||||||
break;
|
break;
|
||||||
case "zh_CN":
|
case "zh_CN":
|
||||||
this.props.msg.lan = "zh_CN";
|
this.props.msg.lan = "zh_CN";
|
||||||
this.props.msg.pkg = MsgPackage.get(lan);
|
this.props.msg.pkg = MsgPackage.get(lan);
|
||||||
LocalStorage.set(lanKey, "zh_CN");
|
this.props.login.preferences.lan = "zh_CN";
|
||||||
|
this.props.login.preferences.lanPackURL = "";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
alertMsg("language package not found");
|
alertMsg("language package not found");
|
||||||
|
@ -585,8 +584,10 @@ export class Updater {
|
||||||
this.props.login.preferences = { ...prefer };
|
this.props.login.preferences = { ...prefer };
|
||||||
};
|
};
|
||||||
|
|
||||||
syncPreferences = async ():Promise<number> => {
|
syncPreferences = async (): Promise<number> => {
|
||||||
const resp = await this.usersClient.setPreferences(this.props.login.preferences);
|
const resp = await this.usersClient.setPreferences(
|
||||||
|
this.props.login.preferences
|
||||||
|
);
|
||||||
return resp.status;
|
return resp.status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -602,6 +603,47 @@ export class Updater {
|
||||||
return resp.status;
|
return resp.status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// initLan = () => {
|
||||||
|
// const lanKey = getCookieLanKey(this.props.login.userName);
|
||||||
|
// const lanSaved = LocalStorage.get(lanKey);
|
||||||
|
// this.setLan(lanSaved === "" ? "en_US" : lanSaved);
|
||||||
|
// };
|
||||||
|
|
||||||
|
fetchLanPack = async (): Promise<number> => {
|
||||||
|
const url = this.props.login.preferences.lanPackURL;
|
||||||
|
if (url === "") {
|
||||||
|
const lan = this.props.login.preferences.lan;
|
||||||
|
if (lan == "en_US" || lan == "zh_CN") {
|
||||||
|
// fallback to build-in language pack
|
||||||
|
this.props.msg.lan = lan;
|
||||||
|
this.props.msg.pkg = MsgPackage.get(lan);
|
||||||
|
} else {
|
||||||
|
// fallback to english
|
||||||
|
this.props.msg.lan = "en_US";
|
||||||
|
this.props.msg.pkg = MsgPackage.get("en_US");
|
||||||
|
}
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await this.filesClient.download(url);
|
||||||
|
let isValid = true;
|
||||||
|
if (resp == null || resp.data == null) {
|
||||||
|
isValid = false;
|
||||||
|
} else if (!isValidLanPack(resp.data)) {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
this.props.msg.lan = "en_US";
|
||||||
|
this.props.msg.pkg = MsgPackage.get("en_US");
|
||||||
|
this.props.login.preferences.lanPackURL = "";
|
||||||
|
return 400;
|
||||||
|
}
|
||||||
|
this.props.msg.lan = resp.data.lan;
|
||||||
|
this.props.msg.pkg = Map<string, string>(resp.data);
|
||||||
|
return resp.status;
|
||||||
|
};
|
||||||
|
|
||||||
updateBrowser = (prevState: ICoreState): ICoreState => {
|
updateBrowser = (prevState: ICoreState): ICoreState => {
|
||||||
return {
|
return {
|
||||||
...prevState,
|
...prevState,
|
||||||
|
|
|
@ -68,8 +68,6 @@ export class TopBar extends React.Component<Props, State, {}> {
|
||||||
this.props.update(updater().updatePanes);
|
this.props.update(updater().updatePanes);
|
||||||
this.props.update(updater().updateAdmin);
|
this.props.update(updater().updateAdmin);
|
||||||
this.props.update(updater().updateUI);
|
this.props.update(updater().updateUI);
|
||||||
|
|
||||||
updater().initLan();
|
|
||||||
this.props.update(updater().updateMsg);
|
this.props.update(updater().updateMsg);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Map } from "immutable";
|
import { Map, Set } from "immutable";
|
||||||
|
|
||||||
import { msgs as enMsgs } from "./en_US";
|
import { msgs as enMsgs } from "./en_US";
|
||||||
import { msgs as cnMsgs } from "./zh_CN";
|
import { msgs as cnMsgs } from "./zh_CN";
|
||||||
|
@ -25,3 +25,127 @@ export class MsgPackage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isValidLanPack(lanPackObject: any): boolean {
|
||||||
|
const topLevelkeys = Set(Object.keys(lanPackObject));
|
||||||
|
if (!topLevelkeys.has("lan") && !topLevelkeys.has("pkg")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gotKeys = Set(Object.keys(lanPackObject.pkg));
|
||||||
|
let missingKeys = Set<string>();
|
||||||
|
lanPackKeys.forEach((key: string) => {
|
||||||
|
if (!gotKeys.has(key)) {
|
||||||
|
missingKeys = missingKeys.add(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: provide better error report?
|
||||||
|
if (missingKeys.size > 0) {
|
||||||
|
console.error(missingKeys);
|
||||||
|
}
|
||||||
|
return missingKeys.size > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const lanPackKeys = Set<string>([
|
||||||
|
"stateMgr.cap.fail",
|
||||||
|
"browser.upload.del.fail",
|
||||||
|
"browser.folder.add.fail",
|
||||||
|
"browser.del.fail",
|
||||||
|
"browser.move.fail",
|
||||||
|
"browser.share.add.fail",
|
||||||
|
"browser.share.del.fail",
|
||||||
|
"browser.share.del",
|
||||||
|
"browser.share.add",
|
||||||
|
"browser.share.title",
|
||||||
|
"browser.share.desc",
|
||||||
|
"browser.upload.title",
|
||||||
|
"browser.upload.desc",
|
||||||
|
"browser.folder.name",
|
||||||
|
"browser.folder.add",
|
||||||
|
"browser.upload",
|
||||||
|
"browser.delete",
|
||||||
|
"browser.paste",
|
||||||
|
"browser.select",
|
||||||
|
"browser.deselect",
|
||||||
|
"browser.selectAll",
|
||||||
|
"browser.stop",
|
||||||
|
"browser.location",
|
||||||
|
"browser.item.title",
|
||||||
|
"browser.used",
|
||||||
|
"panes.close",
|
||||||
|
"login.logout.fail",
|
||||||
|
"login.username",
|
||||||
|
"login.captcha",
|
||||||
|
"login.pwd",
|
||||||
|
"login.login",
|
||||||
|
"login.logout",
|
||||||
|
"settings.pwd.notSame",
|
||||||
|
"settings.pwd.empty",
|
||||||
|
"settings.pwd.notChanged",
|
||||||
|
"update",
|
||||||
|
"settings.pwd.old",
|
||||||
|
"settings.pwd.new1",
|
||||||
|
"settings.pwd.new2",
|
||||||
|
"settings",
|
||||||
|
"settings.chooseLan",
|
||||||
|
"settings.pwd.update",
|
||||||
|
"admin",
|
||||||
|
"update.ok",
|
||||||
|
"update.fail",
|
||||||
|
"delete.fail",
|
||||||
|
"delete.ok",
|
||||||
|
"delete",
|
||||||
|
"spaceLimit",
|
||||||
|
"uploadLimit",
|
||||||
|
"downloadLimit",
|
||||||
|
"add.fail",
|
||||||
|
"add.ok",
|
||||||
|
"role.delete.warning",
|
||||||
|
"user.id",
|
||||||
|
"user.add",
|
||||||
|
"user.name",
|
||||||
|
"user.role",
|
||||||
|
"user.password",
|
||||||
|
"add",
|
||||||
|
"admin.users",
|
||||||
|
"role.add",
|
||||||
|
"role.name",
|
||||||
|
"admin.roles",
|
||||||
|
"zhCN",
|
||||||
|
"enUS",
|
||||||
|
"move.fail",
|
||||||
|
"share.404.title",
|
||||||
|
"share.404.desc",
|
||||||
|
"upload.404.title",
|
||||||
|
"upload.404.desc",
|
||||||
|
"detail",
|
||||||
|
"refresh",
|
||||||
|
"refresh-hint",
|
||||||
|
"pane.login",
|
||||||
|
"pane.admin",
|
||||||
|
"pane.settings",
|
||||||
|
"logout.confirm",
|
||||||
|
"unauthed",
|
||||||
|
"err.tooManyUploads",
|
||||||
|
"login.role",
|
||||||
|
"user.profile",
|
||||||
|
"user.downLimit",
|
||||||
|
"user.upLimit",
|
||||||
|
"user.spaceLimit",
|
||||||
|
"cfg.siteName",
|
||||||
|
"cfg.siteDesc",
|
||||||
|
"cfg.bg",
|
||||||
|
"cfg.bg.url",
|
||||||
|
"cfg.bg.repeat",
|
||||||
|
"cfg.bg.pos",
|
||||||
|
"cfg.bg.align",
|
||||||
|
"reset",
|
||||||
|
"bg.url.alert",
|
||||||
|
"bg.pos.alert",
|
||||||
|
"bg.align.alert",
|
||||||
|
"prefer.theme",
|
||||||
|
"prefer.theme.url",
|
||||||
|
"settings.customLan",
|
||||||
|
"settings.lanPackURL",
|
||||||
|
]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue