From 8d8311abc058312aa008f24aa2679b811f62cccd Mon Sep 17 00:00:00 2001 From: Andres Valencia Date: Tue, 9 Jun 2020 21:30:18 -0500 Subject: [PATCH] These changes implement the read only feature for the editor, it disables the editor and hides the editor toolbar --- src/main/i18n/translations/en.ts | 1 + src/main/i18n/translations/es.ts | 1 + .../elements/editor/editor/Editor.tsx | 7 ++-- .../editor/editor/EditorContainer.tsx | 1 + .../pref-overlay/entries-pref/EntriesPref.tsx | 3 ++ .../read-only-pref/ReadOnlyPref.tsx | 35 +++++++++++++++++++ .../read-only-pref/ReadOnlyPrefContainer.tsx | 16 +++++++++ src/renderer/files/preferences/preferences.ts | 15 ++++++++ src/renderer/store/app/actionCreators.ts | 17 +++++++++ src/renderer/store/app/reducer.ts | 9 +++++ src/renderer/store/app/types.ts | 10 ++++++ src/shared/types.ts | 1 + 12 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPref.tsx create mode 100644 src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPrefContainer.tsx diff --git a/src/main/i18n/translations/en.ts b/src/main/i18n/translations/en.ts index e8363ee5..38bc0baf 100644 --- a/src/main/i18n/translations/en.ts +++ b/src/main/i18n/translations/en.ts @@ -88,6 +88,7 @@ const translationsEn: Translations = { "reset-diary-confirm": "Yes, I am sure", "reset-diary-msg": "Are you sure you want to reset your diary? This will delete all of your content. The data cannot be restored.", + "read-only": "Read only", // Password and directory "change-directory": "Change directory", diff --git a/src/main/i18n/translations/es.ts b/src/main/i18n/translations/es.ts index 175b5f4a..4c916d5f 100644 --- a/src/main/i18n/translations/es.ts +++ b/src/main/i18n/translations/es.ts @@ -77,6 +77,7 @@ const translationsEs: Partial = { auto: "Automático", "diary-entries": "Entradas del diario", "first-day-of-week": "Primer día de la semana", + "read-only": "Solo lectura", // Password and directory "change-directory": "Cambiar carpeta", diff --git a/src/renderer/components/elements/editor/editor/Editor.tsx b/src/renderer/components/elements/editor/editor/Editor.tsx index e465e267..d717c7ce 100644 --- a/src/renderer/components/elements/editor/editor/Editor.tsx +++ b/src/renderer/components/elements/editor/editor/Editor.tsx @@ -33,6 +33,7 @@ const plugins = [listPlugin]; export interface StateProps { enableSpellcheck: boolean; hideTitles: boolean; + readOnly: boolean; dateSelected: Moment; entries: Entries; } @@ -165,7 +166,7 @@ export default class Editor extends PureComponent { render = (): ReactNode => { const { dateSelected, textEditorState, titleEditorState } = this.state; - const { enableSpellcheck, hideTitles } = this.props; + const { enableSpellcheck, hideTitles, readOnly } = this.props; // Detect active inline/block styles const blockType = RichUtils.getCurrentBlockType(textEditorState); @@ -187,6 +188,7 @@ export default class Editor extends PureComponent { onChange={this.onTitleChange} placeholder={translations["add-a-title"]} spellCheck={enableSpellcheck} + readOnly={readOnly} /> )} @@ -202,10 +204,11 @@ export default class Editor extends PureComponent { placeholder={isOl || isUl ? "" : `${translations["write-something"]}…`} plugins={plugins} spellCheck={enableSpellcheck} + readOnly={readOnly} /> - + {!readOnly && ()} ); }; diff --git a/src/renderer/components/elements/editor/editor/EditorContainer.tsx b/src/renderer/components/elements/editor/editor/EditorContainer.tsx index d9a98f83..54ad021d 100644 --- a/src/renderer/components/elements/editor/editor/EditorContainer.tsx +++ b/src/renderer/components/elements/editor/editor/EditorContainer.tsx @@ -8,6 +8,7 @@ import Editor, { DispatchProps, StateProps } from "./Editor"; const mapStateToProps = (state: RootState): StateProps => ({ enableSpellcheck: state.app.enableSpellcheck, hideTitles: state.app.hideTitles, + readOnly: state.app.readOnly, dateSelected: state.diary.dateSelected, entries: state.file.entries, }); diff --git a/src/renderer/components/overlays/pref-overlay/entries-pref/EntriesPref.tsx b/src/renderer/components/overlays/pref-overlay/entries-pref/EntriesPref.tsx index 2d0bbdfa..70d649e0 100644 --- a/src/renderer/components/overlays/pref-overlay/entries-pref/EntriesPref.tsx +++ b/src/renderer/components/overlays/pref-overlay/entries-pref/EntriesPref.tsx @@ -3,6 +3,7 @@ import React, { ReactElement } from "react"; import { translations } from "../../../../utils/i18n"; import FutureEntriesPrefContainer from "./future-entries-pref/FutureEntriesPrefContainer"; import HideTitlesPrefContainer from "./hide-titles-pref/HideTitlesPrefContainer"; +import ReadOnlyPrefContainer from "./read-only-pref/ReadOnlyPrefContainer"; import SpellcheckPrefContainer from "./spellcheck-pref/SpellcheckPrefContainer"; /** @@ -18,6 +19,8 @@ export default function EntriesPref(): ReactElement {
+
+ ); diff --git a/src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPref.tsx b/src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPref.tsx new file mode 100644 index 00000000..5dad2fd1 --- /dev/null +++ b/src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPref.tsx @@ -0,0 +1,35 @@ +import React, { ReactElement } from "react"; + +import { translations } from "../../../../../utils/i18n"; + +export interface StateProps { + readOnly: boolean; +} + +export interface DispatchProps { + updateReadOnlyPref: (readOnly: boolean) => void; +} + +type Props = StateProps & DispatchProps; + +/** + * Preference fieldset for setting the editor state + */ +export default function ReadOnlyPref(props: Props): ReactElement { + const { readOnly, updateReadOnlyPref } = props; + + const toggleReadOnly = (): void => updateReadOnlyPref(!readOnly); + + return ( + + ); +} diff --git a/src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPrefContainer.tsx b/src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPrefContainer.tsx new file mode 100644 index 00000000..0c6de7e6 --- /dev/null +++ b/src/renderer/components/overlays/pref-overlay/entries-pref/read-only-pref/ReadOnlyPrefContainer.tsx @@ -0,0 +1,16 @@ +import { connect } from "react-redux"; + +import { updateReadOnlyPref } from "../../../../../store/app/actionCreators"; +import { RootState, ThunkDispatchT } from "../../../../../store/store"; +import ReadOnlyPref, { DispatchProps, StateProps } from "./ReadOnlyPref"; + +const mapStateToProps = (state: RootState): StateProps => ({ + readOnly: state.app.readOnly, +}); + +const mapDispatchToProps = (dispatch: ThunkDispatchT): DispatchProps => ({ + updateReadOnlyPref: (readOnly: boolean): void => + dispatch(updateReadOnlyPref(readOnly)), +}); + +export default connect(mapStateToProps, mapDispatchToProps)(ReadOnlyPref); diff --git a/src/renderer/files/preferences/preferences.ts b/src/renderer/files/preferences/preferences.ts index a4f2805e..05068f95 100644 --- a/src/renderer/files/preferences/preferences.ts +++ b/src/renderer/files/preferences/preferences.ts @@ -9,6 +9,7 @@ import { supportsNativeTheme } from "../../utils/native-theme"; const DEFAULT_ALLOW_FUTURE_ENTRIES = false; const DEFAULT_FIRST_DAY_OF_WEEK = null; // Let the system locale determine the first day of the week const DEFAULT_HIDE_TITLES = false; +const DEFAULT_READ_ONLY = false; const DEFAULT_ENABLE_SPELLCHECK = true; const DEFAULT_THEME_PREF: ThemePref = "light"; const PREF_DIR = remote.app.getPath("userData"); @@ -91,6 +92,13 @@ export function loadHideTitlesPref(): boolean { return getPref("hideTitles", DEFAULT_HIDE_TITLES); } +/** + * Return the preference if the editor should be read only + */ +export function loadReadOnlyPref(): boolean { + return getPref("readOnly", DEFAULT_READ_ONLY); +} + /** * Update the preference for hiding diary entry titles */ @@ -98,6 +106,13 @@ export function saveHideTitlesPref(hideTitles: boolean): void { setPref("hideTitles", hideTitles); } +/** + * Update the preference for enabling read only mode + */ +export function saveReadOnlyPref(readOnly: boolean): void { + setPref("readOnly", readOnly); +} + // Spellcheck /** diff --git a/src/renderer/store/app/actionCreators.ts b/src/renderer/store/app/actionCreators.ts index ef4b6154..ef4ec58f 100644 --- a/src/renderer/store/app/actionCreators.ts +++ b/src/renderer/store/app/actionCreators.ts @@ -3,6 +3,7 @@ import { saveFirstDayOfWeekPref, saveFutureEntriesPref, saveHideTitlesPref, + saveReadOnlyPref, saveThemePref, saveSpellcheckPref, } from "../../files/preferences/preferences"; @@ -13,6 +14,7 @@ import { SET_ALLOW_FUTURE_ENTRIES, SET_ENABLE_SPELLCHECK, SET_HIDE_TITLES, + SET_READ_ONLY, SET_FIRST_DAY_OF_WEEK, SET_OVERLAY, SET_THEME, @@ -24,6 +26,7 @@ import { SetThemeAction, SetThemePrefAction, SetHideTitlesAction, + SetReadOnlyAction, } from "./types"; // Action creators @@ -55,6 +58,15 @@ function setHideTitles(hideTitles: boolean): SetHideTitlesAction { }; } +function setReadOnly(readOnly: boolean): SetReadOnlyAction { + return { + type: SET_READ_ONLY, + payload: { + readOnly, + } + }; +} + function setFirstDayOfWeek(firstDayOfWeek: Weekday | null): SetFirstDayOfWeekAction { return { type: SET_FIRST_DAY_OF_WEEK, @@ -121,6 +133,11 @@ export const updateHideTitlesPref = (hideTitles: boolean): ThunkActionT => (disp saveHideTitlesPref(hideTitles); }; +export const updateReadOnlyPref = (readOnly: boolean): ThunkActionT => (dispatch): void => { + dispatch(setReadOnly(readOnly)); + saveReadOnlyPref(readOnly); +}; + export const updateFirstDayOfWeekPref = (firstDayOfWeek: Weekday | null): ThunkActionT => ( dispatch, ): void => { diff --git a/src/renderer/store/app/reducer.ts b/src/renderer/store/app/reducer.ts index 7a883776..f3ed0766 100644 --- a/src/renderer/store/app/reducer.ts +++ b/src/renderer/store/app/reducer.ts @@ -4,6 +4,7 @@ import { loadFutureEntriesPref, loadThemePref, loadHideTitlesPref, + loadReadOnlyPref, } from "../../files/preferences/preferences"; import { getThemeFromPref } from "../../utils/native-theme"; import { @@ -16,6 +17,7 @@ import { SET_THEME, SET_THEME_PREF, SET_HIDE_TITLES, + SET_READ_ONLY, } from "./types"; const themePref = loadThemePref(); @@ -26,6 +28,7 @@ const initialState: AppState = { enableSpellcheck: loadSpellcheckPref(), firstDayOfWeek: loadFirstDayOfWeekPref(), hideTitles: loadHideTitlesPref(), + readOnly: loadReadOnlyPref(), overlay: "none", theme, themePref, @@ -51,6 +54,12 @@ function appReducer(state = initialState, action: AppAction): AppState { hideTitles: action.payload.hideTitles, }; } + case SET_READ_ONLY: { + return { + ...state, + readOnly: action.payload.readOnly, + }; + } case SET_FIRST_DAY_OF_WEEK: { return { ...state, diff --git a/src/renderer/store/app/types.ts b/src/renderer/store/app/types.ts index 5533185d..be4e1ee4 100644 --- a/src/renderer/store/app/types.ts +++ b/src/renderer/store/app/types.ts @@ -10,6 +10,7 @@ export interface AppState { enableSpellcheck: boolean; firstDayOfWeek: Weekday | null; hideTitles: boolean; + readOnly: boolean; overlay: OverlayType; theme: Theme; themePref: ThemePref; @@ -21,6 +22,7 @@ export const SET_ALLOW_FUTURE_ENTRIES = "SET_ALLOW_FUTURE_ENTRIES"; export const SET_ENABLE_SPELLCHECK = "SET_ENABLE_SPELLCHECK"; export const SET_FIRST_DAY_OF_WEEK = "SET_FIRST_DAY_OF_WEEK"; export const SET_HIDE_TITLES = "SET_HIDE_TITLES"; +export const SET_READ_ONLY = "SET_READ_ONLY"; export const SET_OVERLAY = "SET_OVERLAY"; export const SET_THEME = "SET_THEME"; export const SET_THEME_PREF = "SET_THEME_PREF"; @@ -55,6 +57,13 @@ export interface SetHideTitlesAction extends Action { }; } +export interface SetReadOnlyAction extends Action { + type: typeof SET_READ_ONLY; + payload: { + readOnly: boolean; + }; +} + export interface SetOverlayAction extends Action { type: typeof SET_OVERLAY; payload: { @@ -81,6 +90,7 @@ export type AppAction = | SetEnableSpellcheckAction | SetFirstDayOfWeekAction | SetHideTitlesAction + | SetReadOnlyAction | SetOverlayAction | SetThemeAction | SetThemePrefAction; diff --git a/src/shared/types.ts b/src/shared/types.ts index 89721fcd..570f0d6a 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -99,6 +99,7 @@ export interface Translations { "reset-diary": string; "reset-diary-confirm": string; "reset-diary-msg": string; + "read-only": string; // Password and directory "change-directory": string;