aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/SettingsManager.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/SettingsManager.tsx')
-rw-r--r--src/client/util/SettingsManager.tsx155
1 files changed, 83 insertions, 72 deletions
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 8133e9eff..dc852596f 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -13,21 +13,16 @@ import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager
import { DocServer } from '../DocServer';
import { Networking } from '../Network';
import { MainViewModal } from '../views/MainViewModal';
-import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
import { GroupManager } from './GroupManager';
import './SettingsManager.scss';
import { undoBatch } from './UndoManager';
-const higflyout = require('@hig/flyout');
-export const { anchorPoints } = higflyout;
-export const Flyout = higflyout.default;
export enum ColorScheme {
Dark = 'Dark',
Light = 'Light',
- CoolBlue = 'Cool Blue',
- Cupcake = 'Cupcake',
- System = 'Match System',
Custom = 'Custom',
+ CoolBlue = 'CoolBlue',
+ Cupcake = 'Cupcake',
}
export enum freeformScrollMode {
@@ -51,17 +46,24 @@ export class SettingsManager extends React.Component<{}> {
@observable public static propertiesWidth: number = 0;
@observable public static headerBarHeight: number = 0;
- @computed get backgroundColor() {
- return Doc.UserDoc().activeCollectionBackground;
- }
- @computed get userTheme() {
- return Doc.UserDoc().userTheme;
- }
-
constructor(props: {}) {
super(props);
SettingsManager.Instance = this;
+ this.matchSystem();
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
+ if (Doc.UserDoc().userThemeSystem) {
+ if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark);
+ if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light);
+ }
+ // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
+ });
}
+ matchSystem = () => {
+ if (Doc.UserDoc().userThemeSystem) {
+ if (window.matchMedia('(prefers-color-scheme: dark)').matches) this.changeColorScheme(ColorScheme.Dark);
+ if (window.matchMedia('(prefers-color-scheme: light)').matches) this.changeColorScheme(ColorScheme.Light);
+ }
+ };
public close = action(() => (this.isOpen = false));
public open = action(() => (this.isOpen = true));
@@ -77,15 +79,15 @@ export class SettingsManager extends React.Component<{}> {
}
};
- @computed get userColor() {
+ @computed public static get userColor() {
return StrCast(Doc.UserDoc().userColor);
}
- @computed get userVariantColor() {
+ @computed public static get userVariantColor() {
return StrCast(Doc.UserDoc().userVariantColor);
}
- @computed get userBackgroundColor() {
+ @computed public static get userBackgroundColor() {
return StrCast(Doc.UserDoc().userBackgroundColor);
}
@@ -97,11 +99,11 @@ export class SettingsManager extends React.Component<{}> {
Doc.UserDoc().userBackgroundColor = color;
addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${color} !important` });
});
- @undoBatch switchUserColor = action((color: string) => {
- Doc.UserDoc().userColor = color;
- });
- @undoBatch switchUserVariantColor = action((color: string) => {
- Doc.UserDoc().userVariantColor = color;
+ @undoBatch switchUserColor = action((color: string) => (Doc.UserDoc().userColor = color));
+ @undoBatch switchUserVariantColor = action((color: string) => (Doc.UserDoc().userVariantColor = color));
+ @undoBatch userThemeSystemToggle = action(() => {
+ Doc.UserDoc().userThemeSystem = !Doc.UserDoc().userThemeSystem;
+ this.matchSystem();
});
@undoBatch playgroundModeToggle = action(() => {
this.playgroundMode = !this.playgroundMode;
@@ -138,18 +140,11 @@ export class SettingsManager extends React.Component<{}> {
break;
case ColorScheme.Custom:
break;
- case ColorScheme.System:
- default:
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
- e.matches ? ColorScheme.Dark : ColorScheme.Light; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
- });
- break;
}
});
@computed get colorsContent() {
- const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.Cupcake, ColorScheme.CoolBlue, ColorScheme.Custom, ColorScheme.System];
- const schemeMap = ['Light', 'Dark', 'Cupcake', 'Cool Blue', 'Custom', 'Match System'];
+ const schemeMap = Array.from(Object.keys(ColorScheme));
const userTheme = StrCast(Doc.UserDoc().userTheme);
return (
<div style={{ width: '100%' }}>
@@ -157,42 +152,48 @@ export class SettingsManager extends React.Component<{}> {
formLabel="Theme"
size={Size.SMALL}
type={Type.TERT}
+ closeOnSelect={false}
selectedVal={userTheme}
- setSelectedVal={scheme => this.changeColorScheme(scheme as string)}
- items={colorSchemes.map((scheme, i) => ({
- text: schemeMap[i],
+ setSelectedVal={scheme => {
+ this.changeColorScheme(scheme as string);
+ Doc.UserDoc().userThemeSystem = false;
+ }}
+ items={Object.keys(ColorScheme).map((scheme, i) => ({
+ text: schemeMap[i].replace(/([a-z])([A-Z])/, '$1 $2'),
val: scheme,
}))}
dropdownType={DropdownType.SELECT}
- color={this.userColor}
+ color={SettingsManager.userColor}
fillWidth
/>
+ <Toggle formLabel="Match System" toggleType={ToggleType.SWITCH} color={SettingsManager.userColor} toggleStatus={BoolCast(Doc.UserDoc().userThemeSystem)} onClick={this.userThemeSystemToggle} />
+
{userTheme === ColorScheme.Custom && (
<Group formLabel="Custom Theme">
<ColorPicker
tooltip={'User Color'} //
- color={this.userColor}
+ color={SettingsManager.userColor}
type={Type.SEC}
icon={<FaFillDrip />}
- selectedColor={this.userColor}
+ selectedColor={SettingsManager.userColor}
setSelectedColor={this.switchUserColor}
setFinalColor={this.switchUserColor}
/>
<ColorPicker
tooltip={'User Background Color'}
- color={this.userColor}
+ color={SettingsManager.userColor}
type={Type.SEC}
icon={<FaPalette />}
- selectedColor={this.userBackgroundColor}
+ selectedColor={SettingsManager.userBackgroundColor}
setSelectedColor={this.switchUserBackgroundColor}
setFinalColor={this.switchUserBackgroundColor}
/>
<ColorPicker
tooltip={'User Variant Color'}
- color={this.userColor}
+ color={SettingsManager.userColor}
type={Type.SEC}
icon={<FaPalette />}
- selectedColor={this.userVariantColor}
+ selectedColor={SettingsManager.userVariantColor}
setSelectedColor={this.switchUserVariantColor}
setFinalColor={this.switchUserVariantColor}
/>
@@ -212,7 +213,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc().layout_showTitle = Doc.UserDoc().layout_showTitle ? undefined : 'author_date')}
toggleStatus={Doc.UserDoc().layout_showTitle !== undefined}
size={Size.XSMALL}
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
<Toggle
formLabel={'Show Full Toolbar'}
@@ -221,25 +222,25 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc()['documentLinksButton-fullMenu'] = !Doc.UserDoc()['documentLinksButton-fullMenu'])}
toggleStatus={BoolCast(Doc.UserDoc()['documentLinksButton-fullMenu'])}
size={Size.XSMALL}
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
<Toggle
formLabel={'Show Button Labels'}
formLabelPlacement={'right'}
toggleType={ToggleType.SWITCH}
- onClick={e => FontIconBox.SetShowLabels(!FontIconBox.GetShowLabels())}
- toggleStatus={FontIconBox.GetShowLabels()}
+ onClick={e => Doc.SetShowIconLabels(!Doc.GetShowIconLabels())}
+ toggleStatus={Doc.GetShowIconLabels()}
size={Size.XSMALL}
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
<Toggle
formLabel={'Recognize Ink Gestures'}
formLabelPlacement={'right'}
toggleType={ToggleType.SWITCH}
- onClick={e => FontIconBox.SetRecognizeGestures(!FontIconBox.GetRecognizeGestures())}
- toggleStatus={FontIconBox.GetRecognizeGestures()}
+ onClick={e => Doc.SetRecognizeGestures(!Doc.GetRecognizeGestures())}
+ toggleStatus={Doc.GetRecognizeGestures()}
size={Size.XSMALL}
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
<Toggle
formLabel={'Hide Labels In Ink Shapes'}
@@ -248,7 +249,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc().activeInkHideTextLabels = !Doc.UserDoc().activeInkHideTextLabels)}
toggleStatus={BoolCast(Doc.UserDoc().activeInkHideTextLabels)}
size={Size.XSMALL}
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
<Toggle
formLabel={'Open Ink Docs in Lightbox'}
@@ -257,7 +258,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc().openInkInLightbox = !Doc.UserDoc().openInkInLightbox)}
toggleStatus={BoolCast(Doc.UserDoc().openInkInLightbox)}
size={Size.XSMALL}
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
<Toggle
formLabel={'Show Link Lines'}
@@ -266,7 +267,7 @@ export class SettingsManager extends React.Component<{}> {
onClick={e => (Doc.UserDoc().showLinkLines = !Doc.UserDoc().showLinkLines)}
toggleStatus={BoolCast(Doc.UserDoc().showLinkLines)}
size={Size.XSMALL}
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
</div>
);
@@ -298,7 +299,7 @@ export class SettingsManager extends React.Component<{}> {
<div className="tab-column-content">
{/* <NumberInput/> */}
<Group formLabel={'Default Font'}>
- <NumberDropdown color={this.userColor} numberDropdownType={'input'} min={0} max={50} step={2} type={Type.TERT} number={0} unit={'px'} setNumber={() => {}} />
+ <NumberDropdown color={SettingsManager.userColor} numberDropdownType={'input'} min={0} max={50} step={2} type={Type.TERT} number={0} unit={'px'} setNumber={() => {}} />
<Dropdown
items={fontFamilies.map(val => {
return {
@@ -309,13 +310,14 @@ export class SettingsManager extends React.Component<{}> {
},
};
})}
+ closeOnSelect={true}
dropdownType={DropdownType.SELECT}
type={Type.TERT}
selectedVal={StrCast(Doc.UserDoc().fontFamily)}
setSelectedVal={val => {
this.changeFontFamily(val as string);
}}
- color={this.userColor}
+ color={SettingsManager.userColor}
fillWidth
/>
</Group>
@@ -343,12 +345,12 @@ export class SettingsManager extends React.Component<{}> {
@computed get passwordContent() {
return (
<div className="password-content">
- <EditableText placeholder="Current password" type={Type.SEC} color={this.userColor} val={''} setVal={val => this.changeVal(val as string, 'curr')} fillWidth password />
- <EditableText placeholder="New password" type={Type.SEC} color={this.userColor} val={''} setVal={val => this.changeVal(val as string, 'new')} fillWidth password />
- <EditableText placeholder="Confirm new password" type={Type.SEC} color={this.userColor} val={''} setVal={val => this.changeVal(val as string, 'conf')} fillWidth password />
+ <EditableText placeholder="Current password" type={Type.SEC} color={SettingsManager.userColor} val={''} setVal={val => this.changeVal(val as string, 'curr')} fillWidth password />
+ <EditableText placeholder="New password" type={Type.SEC} color={SettingsManager.userColor} val={''} setVal={val => this.changeVal(val as string, 'new')} fillWidth password />
+ <EditableText placeholder="Confirm new password" type={Type.SEC} color={SettingsManager.userColor} val={''} setVal={val => this.changeVal(val as string, 'conf')} fillWidth password />
{!this.passwordResultText ? null : <div className={`${this.passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this.passwordResultText}</div>}
- <Button type={Type.SEC} text={'Forgot Password'} color={this.userColor} />
- <Button type={Type.TERT} text={'Submit'} onClick={this.changePassword} color={this.userColor} />
+ <Button type={Type.SEC} text={'Forgot Password'} color={SettingsManager.userColor} />
+ <Button type={Type.TERT} text={'Submit'} onClick={this.changePassword} color={SettingsManager.userColor} />
</div>
);
}
@@ -388,6 +390,7 @@ export class SettingsManager extends React.Component<{}> {
<div className="tab-column-content">
<Dropdown
formLabel={'Mode'}
+ closeOnSelect={true}
items={[
{
text: 'Novice',
@@ -408,17 +411,18 @@ export class SettingsManager extends React.Component<{}> {
dropdownType={DropdownType.SELECT}
type={Type.TERT}
placement="bottom-start"
- color={this.userColor}
+ color={SettingsManager.userColor}
fillWidth
/>
- <Toggle formLabel={'Playground Mode'} toggleType={ToggleType.SWITCH} toggleStatus={this.playgroundMode} onClick={this.playgroundModeToggle} color={this.userColor} />
+ <Toggle formLabel={'Playground Mode'} toggleType={ToggleType.SWITCH} toggleStatus={this.playgroundMode} onClick={this.playgroundModeToggle} color={SettingsManager.userColor} />
</div>
<div className="tab-column-title" style={{ marginTop: 20, marginBottom: 10 }}>
Freeform Navigation
</div>
<div className="tab-column-content">
<Dropdown
- formLabel={'Scroll Mode'}
+ formLabel="Scroll Mode"
+ closeOnSelect={true}
items={[
{
text: 'Scroll to Pan',
@@ -436,15 +440,22 @@ export class SettingsManager extends React.Component<{}> {
dropdownType={DropdownType.SELECT}
type={Type.TERT}
placement="bottom-start"
- color={this.userColor}
+ color={SettingsManager.userColor}
/>
</div>
</div>
<div className="tab-column">
<div className="tab-column-title">Permissions</div>
<div className="tab-column-content">
- <Button text={'Manage Groups'} type={Type.TERT} onClick={() => GroupManager.Instance?.open()} color={this.userColor} />
- <Toggle toggleType={ToggleType.SWITCH} formLabel={'Default access private'} color={this.userColor} toggleStatus={BoolCast(Doc.defaultAclPrivate)} onClick={action(() => (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))} />
+ <Button text={'Manage Groups'} type={Type.TERT} onClick={() => GroupManager.Instance?.open()} color={SettingsManager.userColor} />
+ <Toggle
+ toggleType={ToggleType.SWITCH}
+ formLabel={'Default access private'}
+ color={SettingsManager.userColor}
+ toggleStatus={BoolCast(Doc.defaultAclPrivate)}
+ onClick={action(() => (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))}
+ />
+ <Toggle toggleType={ToggleType.SWITCH} formLabel={'Enable Sharing UI'} color={SettingsManager.userColor} toggleStatus={BoolCast(Doc.IsSharingEnabled)} onClick={action(() => (Doc.IsSharingEnabled = !Doc.IsSharingEnabled))} />
</div>
</div>
</div>
@@ -463,7 +474,7 @@ export class SettingsManager extends React.Component<{}> {
];
return (
<div className="settings-interface">
- <div className="settings-panel" style={{ background: this.userColor }}>
+ <div className="settings-panel" style={{ background: SettingsManager.userColor }}>
<div className="settings-tabs">
{tabs.map(tab => {
const isActive = this.activeTab === tab.title;
@@ -471,8 +482,8 @@ export class SettingsManager extends React.Component<{}> {
<div
key={tab.title}
style={{
- background: isActive ? this.userBackgroundColor : this.userColor,
- color: isActive ? this.userColor : this.userBackgroundColor,
+ background: isActive ? SettingsManager.userBackgroundColor : SettingsManager.userColor,
+ color: isActive ? SettingsManager.userColor : SettingsManager.userBackgroundColor,
}}
className={'tab-control ' + (isActive ? 'active' : 'inactive')}
onClick={action(() => (this.activeTab = tab.title))}>
@@ -483,19 +494,19 @@ export class SettingsManager extends React.Component<{}> {
</div>
<div className="settings-user">
- <div style={{ color: this.userBackgroundColor }}>{DashVersion}</div>
- <div className="settings-username" style={{ color: this.userBackgroundColor }}>
+ <div style={{ color: SettingsManager.userBackgroundColor }}>{DashVersion}</div>
+ <div className="settings-username" style={{ color: SettingsManager.userBackgroundColor }}>
{Doc.CurrentUserEmail}
</div>
- <Button text={Doc.GuestDashboard ? 'Exit' : 'Log Out'} type={Type.TERT} color={this.userVariantColor} onClick={() => window.location.assign(Utils.prepend('/logout'))} />
+ <Button text={Doc.GuestDashboard ? 'Exit' : 'Log Out'} type={Type.TERT} color={SettingsManager.userVariantColor} onClick={() => window.location.assign(Utils.prepend('/logout'))} />
</div>
</div>
<div className="close-button">
- <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={this.close} color={this.userColor} />
+ <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={this.close} color={SettingsManager.userColor} />
</div>
- <div className="settings-content" style={{ color: this.userColor, background: this.userBackgroundColor }}>
+ <div className="settings-content" style={{ color: SettingsManager.userColor, background: SettingsManager.userBackgroundColor }}>
{tabs.map(tab => (
<div key={tab.title} className={'tab-section ' + (this.activeTab === tab.title ? 'active' : 'inactive')}>
{tab.ele}