1
0
Fork 0

Initial work on copy state URL button.

This commit is contained in:
ChaotiCryptidz - 2021-11-21 11:54:25 +00:00
parent 5d98b64730
commit 69b53fb56b
4 changed files with 77 additions and 2 deletions

View file

@ -70,11 +70,11 @@ export class PageRouter {
this.currentPageID = pageID;
this.currentPage = await this.pageList.getPage(pageID);
await this.currentPage.setRouterAndState(this, this.state);
// Dispatch an event saying the page has been changed.
this.onPageChange();
await this.currentPage.setRouterAndState(this, this.state);
// Render the page.
await this.renderPage();
}

View file

@ -4,6 +4,11 @@ export class PageState {
constructor() {
const params = new URLSearchParams(window.location.search);
if (params.has("reset")) this.storage.clear();
if (params.has("state")) {
console.log("state owo")
this.loadState(JSON.parse(params.get("state")));
}
if (params.has("incognito")) {
this.storage = sessionStorage;
} else {
@ -13,6 +18,33 @@ export class PageState {
private storage: StorageType;
dumpState(): { [key: string]: unknown } {
return {
"baseMount": this.baseMount,
"secretPath": this.secretPath,
"secretVersion": this.secretVersion,
"secretItem": this.secretItem,
"secretMountType": this.secretMountType,
"policyItem": this.policyItem,
"authPath": this.authPath,
"userPassUser": this.userPassUser,
"currentPage": this.currentPage,
}
}
loadState(newState: { [key: string]: unknown }) {
console.log(newState)
for (let prop in newState) {
console.log("WANTS", prop)
if (prop in this) {
console.log("HAS", prop.toString());
// @ts-ignore
this[prop] = newState[prop];
}
}
}
// NOTE: When a item in the page state isn't a string (e.g it is a array or object),
// you need to add helper methods to mutate it or else it wont save.
// example: secretPath is a array so when you try to .push() to it
@ -22,6 +54,9 @@ export class PageState {
// by using a bunch of functions and modifying localStorage in order to remove some of
// the clunkyness of this approach, but for now, this works.
// these are all ones that persist across browser sessions
// usually in localStorage unless in incognito.
get apiURL(): string | null {
const apiurl = this.storage.getItem("apiURL") || "";
return apiurl.length > 0 ? apiurl : null;
@ -52,6 +87,10 @@ export class PageState {
this.storage.setItem("language", value);
}
// all of these are sessionStorage and not persisted
// so can have multiple tabs open
// TODO: move to just local variables maybe
get baseMount(): string {
return sessionStorage.getItem("baseMount") || "";
}

View file

@ -0,0 +1,33 @@
import { Component, JSX, createRef } from "preact";
import { addClipboardNotifications } from "../../pageUtils";
import ClipboardJS from "clipboard";
import { PageState } from "../../state/PageState";
export type CopyStateLinkButtonProps = {
state: PageState;
};
export class CopyStateLinkButton extends Component<CopyStateLinkButtonProps, unknown> {
buttonRef = createRef();
componentDidMount(): void {
const clipboard = new ClipboardJS(this.buttonRef.current);
addClipboardNotifications(clipboard, 600);
}
render(): JSX.Element {
const newURL = new URL(window.location.toString());
newURL.searchParams.set("state", JSON.stringify(this.props.state.dumpState()));
return (
<a
ref={this.buttonRef}
class="uk-icon uk-margin-small-left"
uk-icon={"icon: copy"}
role="img"
aria-label="Copy Link"
data-clipboard-text={newURL.toString()}
></a>
);
}
}

View file

@ -1,5 +1,7 @@
import { JSX } from "preact/jsx-runtime";
import { Page } from "../../../types/Page";
import { CopyStateLinkButton } from "../../elements/CopyStateLinkButton";
function currentTitleSecretText(page: Page): string {
let secretItemText = page.state.secretItem;
@ -61,6 +63,7 @@ export function SecretTitleElement(props: SecretTitleElementProps): JSX.Element
))}
{page.state.secretItem.length != 0 && <span>{currentTitleSecretText(page)}</span>}
{suffix.length != 0 && <span>{suffix}</span>}
<CopyStateLinkButton state={page.state} />
</div>
);
}