Add drafts utilities, draft segment, and draft type

This commit is contained in:
Marquis Kurt 2019-12-11 14:32:07 -05:00
parent 927c9c06a1
commit bd15fb3e63
No known key found for this signature in database
GPG Key ID: 725636D259F5402D
4 changed files with 117 additions and 0 deletions

View File

@ -45,5 +45,25 @@ export const styles = (theme: Theme) =>
},
pollWizardFlexGrow: {
flexGrow: 1
},
draftDisplayArea: {
display: "flex",
paddingLeft: 8,
paddingRight: 8,
paddingTop: 4,
paddingBottom: 4,
borderColor: theme.palette.action.disabledBackground,
borderWidth: 0.25,
borderStyle: "solid",
borderRadius: 2,
verticalAlign: "middle",
marginLeft: 16,
marginRight: 16
},
draftText: {
padding: theme.spacing.unit / 2
},
draftFlexGrow: {
flexGrow: 1
}
});

View File

@ -44,6 +44,7 @@ import {
getConfig,
getUserDefaultBool
} from "../utilities/settings";
import { draftExists, writeDraft, loadDraft } from "../utilities/compose";
interface IComposerState {
account: UAccount;
@ -141,6 +142,31 @@ class Composer extends Component<any, IComposerState> {
});
}
/**
* Check if there is unsaved text and store it as a draft.
*/
componentWillUnmount() {
if (this.state.text !== "") {
writeDraft(
this.state.text,
this.state.reply ? Number(this.state.reply) : -999
);
this.props.enqueueSnackbar("Draft saved.");
}
}
/**
* Restore the draft from session storage and pre-load it into the state.
*/
restoreDraft() {
const draft = loadDraft();
const text = draft.contents;
const reply =
draft.replyId !== -999 ? draft.replyId.toString() : undefined;
this.setState({ text, reply });
this.props.enqueueSnackbar("Restored draft.");
}
checkComposerParams(location?: string): ParsedQuery {
let params = "";
if (location !== undefined && typeof location === "string") {
@ -738,6 +764,21 @@ class Composer extends Component<any, IComposerState> {
) : null}
</Menu>
</Toolbar>
{draftExists() ? (
<DialogContent className={classes.draftDisplayArea}>
<Typography className={classes.draftText}>
You have an unsaved post.
</Typography>
<div className={classes.draftFlexGrow} />
<Button
color="primary"
size="small"
onClick={() => this.restoreDraft()}
>
Restore
</Button>
</DialogContent>
) : null}
<DialogActions>
<Button color="secondary" onClick={() => this.post()}>
Post

13
src/types/Draft.tsx Normal file
View File

@ -0,0 +1,13 @@
/**
* Base draft type for a cached draft.
*/
export type Draft = {
/**
* The contents of the draft (i.e, its post text).
*/
contents: string;
/**
* The ID of the post it replies to, if applicable. If there isn't one, it should be set to -999.
*/
replyId: number;
};

43
src/utilities/compose.tsx Normal file
View File

@ -0,0 +1,43 @@
import { Draft } from "../types/Draft";
/**
* Check whether a cached draft exists.
*/
export function draftExists(): boolean {
return sessionStorage.getItem("cachedDraft") !== null;
}
/**
* Write a draft to session storage.
* @param draft The text of the post.
* @param replyId The post's reply ID, if available.
*/
export function writeDraft(draft: string, replyId?: number) {
let cachedDraft = {
contents: draft,
replyId: replyId ? replyId : -999
};
sessionStorage.setItem("cachedDraft", JSON.stringify(cachedDraft));
}
/**
* Return the cached draft and remove it from session storage.
* @returns A Draft object with the draft's contents and reply ID (or -999).
*/
export function loadDraft(): Draft {
let contents = "";
let replyId = -999;
if (draftExists()) {
let draft = sessionStorage.getItem("cachedDraft");
sessionStorage.removeItem("cachedDraft");
if (draft != null) {
const draftObject = JSON.parse(draft);
contents = draftObject.contents;
replyId = draftObject.replyId;
}
}
return {
contents: contents,
replyId: replyId
};
}