Rework TOTPView.tsx.
This commit is contained in:
parent
23cc9b60c9
commit
8f2e91bf6b
|
@ -4,38 +4,37 @@ import { Page } from "../../../types/Page";
|
|||
import { SecretTitleElement } from "../SecretTitleElement";
|
||||
import { getTOTPCode } from "../../../api/totp/getTOTPCode";
|
||||
import { getTOTPKeys } from "../../../api/totp/getTOTPKeys";
|
||||
import { makeElement } from "z-makeelement";
|
||||
import { objectToMap } from "../../../utils";
|
||||
import { setErrorText } from "../../../pageUtils";
|
||||
import i18next from "i18next";
|
||||
import { render, JSX } from "preact";
|
||||
|
||||
export interface TOTPListElement extends HTMLElement {
|
||||
setCode(code: string): void;
|
||||
}
|
||||
|
||||
function quickHash(str: string): string {
|
||||
var hash = 0;
|
||||
if (str.length == 0) {
|
||||
return String(hash).toString();
|
||||
}
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
var char = str.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + char;
|
||||
hash = hash & hash;
|
||||
}
|
||||
return String(hash).toString();
|
||||
}
|
||||
import { render, JSX, Component } from "preact";
|
||||
|
||||
|
||||
export function TOTPGridItem(props: { item_key: string, item_value: string }): JSX.Element {
|
||||
|
||||
export class RefreshingTOTPGridItem extends Component<{ baseMount: string; totpKey: string }, { totpValue: string }> {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { totpValue: "" };
|
||||
}
|
||||
timer: unknown;
|
||||
|
||||
componentDidMount(): void {
|
||||
this.timer = setInterval(() => {
|
||||
getTOTPCode(this.props.baseMount, this.props.totpKey).then((code) => {
|
||||
this.setState({ totpValue: code });
|
||||
})
|
||||
this.setState({});
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<div class="uk-grid uk-grid-small uk-text-left" uk-grid>
|
||||
<CopyableInputBox text={props.item_key} copyable />
|
||||
<CopyableInputBox text={props.item_value} copyable />
|
||||
<CopyableInputBox text={this.props.totpKey} copyable />
|
||||
<CopyableInputBox text={this.state.totpValue} copyable />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class TOTPViewPage extends Page {
|
||||
constructor() {
|
||||
|
@ -50,8 +49,6 @@ export class TOTPViewPage extends Page {
|
|||
}
|
||||
|
||||
async render(): Promise<void> {
|
||||
console.log(quickHash("abc"));
|
||||
|
||||
render((
|
||||
<div>
|
||||
<button
|
||||
|
@ -61,62 +58,36 @@ export class TOTPViewPage extends Page {
|
|||
}}>
|
||||
{i18next.t("totp_view_new_btn")}
|
||||
</button>
|
||||
<p id="loadingText">{i18next.t("totp_view_loading")}</p>
|
||||
<br />
|
||||
<br />
|
||||
<div id="totpList"></div>
|
||||
</div>
|
||||
), this.router.pageContentElement)
|
||||
<div id="totpList">
|
||||
{await (async () => {
|
||||
|
||||
|
||||
try {
|
||||
await this.updateTOTPElements();
|
||||
document.getElementById("loadingText").remove();
|
||||
const elem = await Promise.all(Array.from(await getTOTPKeys(this.state.baseMount)).map(async (key) =>
|
||||
<RefreshingTOTPGridItem
|
||||
baseMount={this.state.baseMount}
|
||||
totpKey={key}
|
||||
/>
|
||||
))
|
||||
return elem;
|
||||
} catch (e: unknown) {
|
||||
const error = e as Error;
|
||||
if (error == DoesNotExistError) {
|
||||
const loadingText = document.getElementById("loadingText");
|
||||
loadingText.innerText = i18next.t("totp_view_empty");
|
||||
return <p>{i18next.t("totp_view_empty")}</p>
|
||||
} else {
|
||||
setErrorText(error.message);
|
||||
}
|
||||
}
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
), this.router.pageContentElement)
|
||||
|
||||
const totpRefresher = async () => {
|
||||
await this.updateTOTPElements();
|
||||
};
|
||||
|
||||
this.refresher = setInterval(async () => {
|
||||
await totpRefresher();
|
||||
}, 3000) as unknown as number;
|
||||
}
|
||||
|
||||
async cleanup(): Promise<void> {
|
||||
clearInterval(this.refresher);
|
||||
}
|
||||
|
||||
async updateTOTPElements(): Promise<void> {
|
||||
render((
|
||||
<>
|
||||
{await Promise.all(Array.from(await getTOTPKeys(this.state.baseMount)).map(async (key) =>
|
||||
<TOTPGridItem
|
||||
item_key={String(key).toString()}
|
||||
item_value={await getTOTPCode(this.state.baseMount, key)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
), document.querySelector("#totpList"))
|
||||
}
|
||||
|
||||
makeTOTPListElement(totpKeyName: string): TOTPListElement {
|
||||
|
||||
const gridElement = makeElement({
|
||||
tag: "div",
|
||||
class: ["uk-grid", "uk-grid-small", "uk-text-expand"],
|
||||
}) as TOTPListElement;
|
||||
|
||||
|
||||
return gridElement;
|
||||
}
|
||||
|
||||
async getPageTitle(): Promise<Element | string> {
|
||||
return await SecretTitleElement(this.router);
|
||||
|
|
Loading…
Reference in a new issue