diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/SettingsManager.scss | 276 | ||||
-rw-r--r-- | src/client/util/SettingsManager.tsx | 220 | ||||
-rw-r--r-- | src/client/views/MainViewModal.tsx | 10 |
3 files changed, 414 insertions, 92 deletions
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss index 6923fe879..075879198 100644 --- a/src/client/util/SettingsManager.scss +++ b/src/client/util/SettingsManager.scss @@ -1,7 +1,7 @@ @import "../views/globalCssVariables"; .settings-interface { - background-color: whitesmoke !important; + //background-color: whitesmoke !important; color: grey; width: 450px; height: 300px; @@ -22,24 +22,166 @@ } } +.settings-title { + font-size: 25px; + font-weight: bold; + padding-right: 15px; + color: black; +} + +.settings-section { + display: flex; + border-bottom: 1px solid grey; + padding-bottom: 8px; + padding-top: 6px; + + .settings-section-title { + font-size: 16; + font-weight: bold; + text-align: left; + color: black; + width: 80; + margin-right: 50px; + } + + &:last-child { + border-bottom: none; + } +} + + +.password-content { + display: flex; + + .password-content-inputs { + width: 100; + + .password-inputs { + border: none; + margin-bottom: 8px; + width: 180; + color: black; + border-radius: 5px; + } + } + + .password-content-buttons { + margin-left: 84px; + width: 100; + + .password-submit { + margin-left: 85px; + } + + .password-forgot { + margin-left: 65px; + margin-top: -20px; + white-space: nowrap; + } + } +} + +.accounts-content { + display: flex; +} + +.modes-content { + display: flex; + + .modes-select { + width: 170px; + margin-right: 65px; + color: black; + border-radius: 5px; + } + + .modes-playground { + display: flex; + + .playground-check { + margin-right: 5px; + } + + .playground-text { + color: black; + } + } +} + +.colorFlyout { + margin-top: 2px; + margin-right: 25px; + + .colorFlyout-button { + width: 20px; + height: 20px; + border: 0.5px solid black; + border-radius: 5px; + } +} + +.preferences-content { + display: flex; + margin-top: 4px; + + .preferences-color { + display: flex; + + .preferences-color-text { + color: black; + font-size: 11; + margin-top: 4; + margin-right: 4; + } + } + + .preferences-font { + display: flex; + + .preferences-font-text { + color: black; + font-size: 11; + margin-top: 4; + margin-right: 4; + } + + .font-select { + width: 100px; + color: black; + font-size: 9; + margin-right: 6; + border-radius: 5px; + } + + .size-select { + width: 60px; + color: black; + font-size: 9; + border-radius: 5px; + } + } +} + .settings-interface { display: flex; flex-direction: column; button { - width: 100%; + width: auto; align-self: center; background: #252b33; - margin-top: 4px; + margin-right: 15px; + + //margin-top: 4px; &:hover { background: $main-accent; } } - .delete-button { - background: rgb(227, 86, 86); - } + // .delete-button { + // background: rgb(227, 86, 86); + // } .close-button { position: absolute; @@ -48,57 +190,89 @@ cursor: pointer; } - .settings-heading { - letter-spacing: .5em; - } + // .settings-heading { + // letter-spacing: .5em; + // } + .settings-content { + background: #e4e4e4; + border-radius: 6px; + padding: 10px; + width: 560px; + } - .settings-body { + .settings-top { display: flex; - justify-content: space-between; - margin-top: -10; + margin-bottom: 10px; + } - .settings-type { - display: flex; - flex-direction: column; - flex-basis: 45%; + // .settings-body { + // display: flex; + // justify-content: space-between; + // margin-top: -10; - } + // .settings-type { + // display: flex; + // flex-direction: column; + // flex-basis: 45%; - .settings-content { - padding-left: 1em; - padding-right: 1em; - display: flex; - flex-direction: column; - flex-basis: 70%; - justify-content: space-around; - text-align: left; - - ::placeholder { - color: $intermediate-color; - } - - input { - border-radius: 5px; - border: none; - padding: 4px; - min-width: 100%; - margin: 2px 0; - } - - .error-text { - color: #C40233; - } - - .success-text { - color: #009F6B; - } - - p { - padding: 0 0 .1em .2em; - } + // } - } + // .settings-content { + // background: whitesmoke; + // border-radius: 6px; + + // // padding-left: 1em; + // // padding-right: 1em; + // // display: flex; + // // flex-direction: column; + // // flex-basis: 70%; + // // justify-content: space-around; + // // text-align: left; + + // ::placeholder { + // color: $intermediate-color; + // } + + // input { + // border-radius: 5px; + // border: none; + // padding: 4px; + // min-width: 100%; + // margin: 2px 0; + // } + + // .error-text { + // color: #C40233; + // } + + // .success-text { + // color: #009F6B; + // } + + // p { + // padding: 0 0 .1em .2em; + // } + + // } + // } + + .error-text { + color: #C40233; + width: 300; + margin-left: -20; + font-size: 10; + margin-bottom: 4; + margin-top: -3; + } + + .success-text { + width: 300; + margin-left: -20; + font-size: 10; + margin-bottom: 4; + margin-top: -3; + color: #009F6B; } .focus-span { @@ -138,8 +312,6 @@ color: black; } - - } } diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 6276fae96..9282559e2 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -15,6 +15,12 @@ import GroupManager from "./GroupManager"; import HypothesisAuthenticationManager from "../apis/HypothesisAuthenticationManager"; import GoogleAuthenticationManager from "../apis/GoogleAuthenticationManager"; import { DocServer } from "../DocServer"; +import { BoolCast } from "../../fields/Types"; +import { undoBatch } from "./UndoManager"; +import { ColorState, SketchPicker } from "react-color"; +const higflyout = require("@hig/flyout"); +export const { anchorPoints } = higflyout; +export const Flyout = higflyout.default; library.add(fa.faTimes); @@ -33,6 +39,9 @@ export default class SettingsManager extends React.Component<{}> { private new_password_ref = React.createRef<HTMLInputElement>(); private new_confirm_ref = React.createRef<HTMLInputElement>(); + + @observable private backgroundColor = "white"; + public open = action(() => { SelectionManager.DeselectAll(); this.isOpen = true; @@ -107,50 +116,183 @@ export default class SettingsManager extends React.Component<{}> { addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "pink !important" }); } + @action + changeMode = (e: any) => { + if (e.currentTarget.value === "Novice") { + Doc.UserDoc().noviceMode = true; + } else { + Doc.UserDoc().noviceMode = false; + } + } + + @action @undoBatch + switchColor = (color: ColorState) => { + const val = String(color.hex); + this.backgroundColor = val; + return true; + } + private get settingsInterface() { - return ( - <div className={"settings-interface"}> - <div className="settings-heading"> - <h1>settings</h1> - <div className={"close-button"} onClick={this.close}> - <FontAwesomeIcon icon={fa.faTimes} color="black" size={"lg"} /> - </div> + + const oldSettings = <div className={"settings-interface"}> + <div className="settings-heading"> + <h1>Settings</h1> + <div className={"close-button"} onClick={this.close}> + <FontAwesomeIcon icon={fa.faTimes} color="black" size={"lg"} /> + </div> + </div> + <div className="settings-body"> + <div className="settings-type"> + <button onClick={this.onClick} value="password">reset password</button> + <button onClick={this.noviceToggle} value="data">{`Set ${Doc.UserDoc().noviceMode ? "developer" : "novice"} mode`}</button> + <button onClick={this.togglePlaygroundMode}>{`${this.playgroundMode ? "Disable" : "Enable"} playground mode`}</button> + <button onClick={this.googleAuthorize} value="data">{`Link to Google`}</button> + <button onClick={this.hypothesisAuthorize} value="data">{`Link to Hypothes.is`}</button> + <button onClick={() => GroupManager.Instance.open()}>Manage groups</button> + <button onClick={() => window.location.assign(Utils.prepend("/logout"))}> + {CurrentUserUtils.GuestWorkspace ? "Exit" : "Log Out"} + </button> </div> - <div className="settings-body"> - <div className="settings-type"> - <button onClick={this.onClick} value="password">reset password</button> - <button onClick={this.noviceToggle} value="data">{`Set ${Doc.UserDoc().noviceMode ? "developer" : "novice"} mode`}</button> - <button onClick={this.togglePlaygroundMode}>{`${this.playgroundMode ? "Disable" : "Enable"} playground mode`}</button> - <button onClick={this.googleAuthorize} value="data">{`Link to Google`}</button> - <button onClick={this.hypothesisAuthorize} value="data">{`Link to Hypothes.is`}</button> - <button onClick={() => GroupManager.Instance.open()}>Manage groups</button> - <button onClick={() => window.location.assign(Utils.prepend("/logout"))}> - {CurrentUserUtils.GuestWorkspace ? "Exit" : "Log Out"} - </button> + {this.settingsContent === "password" ? + <div className="settings-content"> + <input placeholder="current password" ref={this.curr_password_ref} /> + <input placeholder="new password" ref={this.new_password_ref} /> + <input placeholder="confirm new password" ref={this.new_confirm_ref} /> + {this.errorText ? <div className="error-text">{this.errorText}</div> : undefined} + {this.successText ? <div className="success-text">{this.successText}</div> : undefined} + <button onClick={this.dispatchRequest}>submit</button> + <a style={{ marginLeft: 65, marginTop: -20 }} href="/forgotPassword">forgot password?</a> + + </div> + : undefined} + {this.settingsContent === "data" ? + <div className="settings-content"> + <p>WARNING: <br /> + THIS WILL ERASE ALL YOUR CURRENT DOCUMENTS STORED ON DASH. IF YOU WISH TO PROCEED, CLICK THE BUTTON BELOW.</p> + <button className="delete-button">DELETE</button> + </div> + : undefined} + </div> + + </div>; + + + const passwordContent = <div className="password-content"> + <div className="password-content-inputs"> + <input className="password-inputs" placeholder="current password" ref={this.curr_password_ref} /> + <input className="password-inputs" placeholder="new password" ref={this.new_password_ref} /> + <input className="password-inputs" placeholder="confirm new password" ref={this.new_confirm_ref} /> + </div> + <div className="password-content-buttons"> + {this.errorText ? <div className="error-text">{this.errorText}</div> : undefined} + {this.successText ? <div className="success-text">{this.successText}</div> : undefined} + <button className="password-submit" onClick={this.dispatchRequest}>submit</button> + <a className="password-forgot" style={{ marginLeft: 65, marginTop: -20 }} + href="/forgotPassword">forgot password?</a> + </div> + </div>; + + const modesContent = <div className="modes-content"> + <select className="modes-select" + onChange={e => this.changeMode(e)}> + <option key={"Novice"} value={"Novice"} selected={BoolCast(Doc.UserDoc().noviceMode)}> + Novice + </option> + <option key={"Developer"} value={"Developer"} selected={!BoolCast(Doc.UserDoc().noviceMode)}> + Developer + </option> + </select> + <div className="modes-playground"> + <input className="playground-check" type="checkbox" + checked={this.playgroundMode} + onChange={undoBatch(action(() => this.togglePlaygroundMode()))} + /><div className="playground-text">Playground Mode</div> + </div> + </div>; + + const accountsContent = <div className="accounts-content"> + <button onClick={this.googleAuthorize} value="data">{`Link to Google`}</button> + <button onClick={this.hypothesisAuthorize} value="data">{`Link to Hypothes.is`}</button> + <button onClick={() => GroupManager.Instance.open()}>Manage groups</button> + </div>; + + const colorBox = <SketchPicker onChange={this.switchColor} + presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', + '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', + '#FFFFFF', '#f1efeb', 'transparent']} + color={this.backgroundColor} />; + + const colorFlyout = <div className="colorFlyout"> + <Flyout anchorPoint={anchorPoints.LEFT_TOP} + content={colorBox}> + <div> + <div className="colorFlyout-button" style={{ backgroundColor: this.backgroundColor }} + onPointerDown={e => e.stopPropagation()} > + <FontAwesomeIcon icon="palette" size="sm" color={this.backgroundColor} /> </div> - {this.settingsContent === "password" ? - <div className="settings-content"> - <input placeholder="current password" ref={this.curr_password_ref} /> - <input placeholder="new password" ref={this.new_password_ref} /> - <input placeholder="confirm new password" ref={this.new_confirm_ref} /> - {this.errorText ? <div className="error-text">{this.errorText}</div> : undefined} - {this.successText ? <div className="success-text">{this.successText}</div> : undefined} - <button onClick={this.dispatchRequest}>submit</button> - <a style={{ marginLeft: 65, marginTop: -20 }} href="/forgotPassword">forgot password?</a> - - </div> - : undefined} - {this.settingsContent === "data" ? - <div className="settings-content"> - <p>WARNING: <br /> - THIS WILL ERASE ALL YOUR CURRENT DOCUMENTS STORED ON DASH. IF YOU WISH TO PROCEED, CLICK THE BUTTON BELOW.</p> - <button className="delete-button">DELETE</button> - </div> - : undefined} </div> + </Flyout> + </div>; + const preferencesContent = <div className="preferences-content"> + <div className="preferences-color"> + <div className="preferences-color-text">Background Color</div> {colorFlyout} </div> - ); + <div className="preferences-font"> + <div className="preferences-font-text">Default Font</div> + <select className="font-select" + onChange={e => this.changeMode(e)}> + <option key={"Times New Roman"} value={"Times New Roman"} selected={BoolCast(Doc.UserDoc().noviceMode)}> + Times New Roman + </option> + <option key={"Georgia"} value={"Georgia"} selected={!BoolCast(Doc.UserDoc().noviceMode)}> + Georgia + </option> + <option key={"Georgia"} value={"Georgia"} selected={!BoolCast(Doc.UserDoc().noviceMode)}> + Georgia + </option> + </select> + <select className="size-select" + onChange={e => this.changeMode(e)}> + <option key={"5px"} value={"5px"} selected={BoolCast(Doc.UserDoc().noviceMode)}> + 5px + </option> + <option key={"8px"} value={"8px"} selected={!BoolCast(Doc.UserDoc().noviceMode)}> + 8px + </option> + </select> + </div> + </div>; + + return (<div className="settings-interface"> + <div className="settings-top"> + <div className="settings-title">Settings</div> + <button onClick={() => window.location.assign(Utils.prepend("/logout"))}> + {CurrentUserUtils.GuestWorkspace ? "Exit" : "Log Out"} + </button> + <div className="close-button" onClick={this.close}> + <FontAwesomeIcon icon={fa.faTimes} color="black" size={"lg"} /> + </div> + </div> + <div className="settings-content"> + <div className="settings-section"> + <div className="settings-section-title">Password</div> + <div className="settings-section-context">{passwordContent}</div> + </div> + <div className="settings-section"> + <div className="settings-section-title">Modes</div> + <div className="settings-section-context">{modesContent}</div> + </div> + <div className="settings-section"> + <div className="settings-section-title">Accounts</div> + <div className="settings-section-context">{accountsContent}</div> + </div> + <div className="settings-section" style={{ paddingBottom: 4 }}> + <div className="settings-section-title">Preferences</div> + <div className="settings-section-context">{preferencesContent}</div> + </div> + </div> + </div>); } render() { @@ -160,6 +302,8 @@ export default class SettingsManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} + width={600} + height={340} /> ); } diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx index 66ea2dbf8..c7b752b60 100644 --- a/src/client/views/MainViewModal.tsx +++ b/src/client/views/MainViewModal.tsx @@ -10,6 +10,8 @@ export interface MainViewOverlayProps { overlayStyle?: React.CSSProperties; dialogueBoxDisplayedOpacity?: number; overlayDisplayedOpacity?: number; + width?: number; + height?: number; closeOnExternalClick?: () => void; // the close method of a MainViewModal, triggered if there is a click on the overlay (closing the modal) } @@ -21,13 +23,17 @@ export default class MainViewModal extends React.Component<MainViewOverlayProps> const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1; const overlayOpacity = p.overlayDisplayedOpacity || 0.4; return !p.isDisplayed ? (null) : ( - <div style={{ pointerEvents: p.isDisplayed && p.interactive ? "all" : "none" }}> + <div style={{ + pointerEvents: p.isDisplayed && p.interactive ? "all" : "none" + }}> <div className={"dialogue-box"} style={{ borderColor: "black", ...(p.dialogueBoxStyle || {}), - opacity: p.isDisplayed ? dialogueOpacity : 0 + opacity: p.isDisplayed ? dialogueOpacity : 0, + width: this.props.width ? this.props.width : "auto", + height: this.props.height ? this.props.height : "auto" }} >{p.contents}</div> <div |