feat: replace accordion in change editor menu with regular menu (#871)

This commit is contained in:
Aman Harwara
2022-02-16 17:57:06 +05:30
committed by GitHub
parent cb013dbce9
commit cc2bc1e21c
10 changed files with 428 additions and 487 deletions

View File

@@ -1,16 +1,10 @@
import { KeyboardKey } from '@/services/ioService';
import { STRING_EDIT_LOCKED_ATTEMPT } from '@/strings';
import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';
import {
MENU_MARGIN_FROM_APP_BORDER,
MAX_MENU_SIZE_MULTIPLIER,
} from '@/views/constants';
import {
reloadFont,
transactionForAssociateComponentWithCurrentNote,
transactionForDisassociateComponentWithCurrentNote,
} from '@/components/NoteView/NoteView';
import {
Disclosure,
DisclosureButton,
@@ -19,18 +13,14 @@ import {
import {
ComponentArea,
IconType,
ItemMutator,
NoteMutator,
PrefKey,
SNComponent,
SNNote,
TransactionalMutation,
} from '@standardnotes/snjs';
import { FunctionComponent } from 'preact';
import { useEffect, useRef, useState } from 'preact/hooks';
import { Icon } from '../Icon';
import { createEditorMenuGroups } from './changeEditor/createEditorMenuGroups';
import { EditorAccordionMenu } from './changeEditor/EditorAccordionMenu';
import { ChangeEditorMenu } from './changeEditor/ChangeEditorMenu';
type ChangeEditorOptionProps = {
appState: AppState;
@@ -59,6 +49,7 @@ type MenuPositionStyle = {
right?: number | 'auto';
bottom: number | 'auto';
left?: number | 'auto';
visibility?: 'hidden' | 'visible';
};
const calculateMenuPosition = (
@@ -102,11 +93,13 @@ const calculateMenuPosition = (
position = {
bottom: positionBottom,
right: clientWidth - buttonRect.left,
visibility: 'hidden',
};
} else {
position = {
bottom: positionBottom,
left: buttonRect.right,
visibility: 'hidden',
};
}
}
@@ -121,12 +114,14 @@ const calculateMenuPosition = (
...position,
top: MENU_MARGIN_FROM_APP_BORDER + buttonRect.top - buttonRect.height,
bottom: 'auto',
visibility: 'visible',
};
} else {
return {
...position,
top: MENU_MARGIN_FROM_APP_BORDER,
bottom: 'auto',
visibility: 'visible',
};
}
}
@@ -135,15 +130,16 @@ const calculateMenuPosition = (
return position;
};
const TIME_IN_MS_TO_WAIT_BEFORE_REPAINT = 1;
export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
application,
appState,
closeOnBlur,
note,
}) => {
const [changeEditorMenuOpen, setChangeEditorMenuOpen] = useState(false);
const [changeEditorMenuVisible, setChangeEditorMenuVisible] = useState(false);
const [changeEditorMenuMaxHeight, setChangeEditorMenuMaxHeight] = useState<
number | 'auto'
>('auto');
const [changeEditorMenuPosition, setChangeEditorMenuPosition] =
useState<MenuPositionStyle>({
right: 0,
@@ -193,84 +189,29 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
);
if (newMenuPosition) {
const { clientHeight } = document.documentElement;
const footerElementRect = document
.getElementById('footer-bar')
?.getBoundingClientRect();
const footerHeightInPx = footerElementRect?.height;
if (
footerHeightInPx &&
newMenuPosition.top &&
newMenuPosition.top !== 'auto'
) {
setChangeEditorMenuMaxHeight(
clientHeight - newMenuPosition.top - footerHeightInPx - 2
);
}
setChangeEditorMenuPosition(newMenuPosition);
setChangeEditorMenuVisible(true);
}
}, TIME_IN_MS_TO_WAIT_BEFORE_REPAINT);
});
}
}, [changeEditorMenuOpen]);
const selectComponent = async (component: SNComponent | null) => {
if (component) {
if (component.conflictOf) {
application.changeAndSaveItem(component.uuid, (mutator) => {
mutator.conflictOf = undefined;
});
}
}
const transactions: TransactionalMutation[] = [];
if (appState.getActiveNoteController()?.isTemplateNote) {
await appState.getActiveNoteController().insertTemplatedNote();
}
if (note.locked) {
application.alertService.alert(STRING_EDIT_LOCKED_ATTEMPT);
return;
}
if (!component) {
if (!note.prefersPlainEditor) {
transactions.push({
itemUuid: note.uuid,
mutate: (m: ItemMutator) => {
const noteMutator = m as NoteMutator;
noteMutator.prefersPlainEditor = true;
},
});
}
const currentEditor = application.componentManager.editorForNote(note);
if (currentEditor?.isExplicitlyEnabledForItem(note.uuid)) {
transactions.push(
transactionForDisassociateComponentWithCurrentNote(
currentEditor,
note
)
);
}
reloadFont(application.getPreference(PrefKey.EditorMonospaceEnabled));
} else if (component.area === ComponentArea.Editor) {
const currentEditor = application.componentManager.editorForNote(note);
if (currentEditor && component.uuid !== currentEditor.uuid) {
transactions.push(
transactionForDisassociateComponentWithCurrentNote(
currentEditor,
note
)
);
}
const prefersPlain = note.prefersPlainEditor;
if (prefersPlain) {
transactions.push({
itemUuid: note.uuid,
mutate: (m: ItemMutator) => {
const noteMutator = m as NoteMutator;
noteMutator.prefersPlainEditor = false;
},
});
}
transactions.push(
transactionForAssociateComponentWithCurrentNote(component, note)
);
}
await application.runTransactionalMutations(transactions);
/** Dirtying can happen above */
application.sync();
setSelectedEditor(application.componentManager.editorForNote(note));
};
return (
<Disclosure open={changeEditorMenuOpen} onChange={toggleChangeEditorMenu}>
<DisclosureButton
@@ -299,17 +240,19 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
}}
style={{
...changeEditorMenuPosition,
maxHeight: changeEditorMenuMaxHeight,
position: 'fixed',
}}
className="sn-dropdown flex flex-col max-h-120 min-w-68 fixed overflow-y-auto"
>
<EditorAccordionMenu
<ChangeEditorMenu
application={application}
closeOnBlur={closeOnBlur}
currentEditor={selectedEditor}
setSelectedEditor={setSelectedEditor}
note={note}
groups={editorMenuGroups}
isOpen={changeEditorMenuOpen}
selectComponent={selectComponent}
isOpen={changeEditorMenuVisible}
/>
</DisclosurePanel>
</Disclosure>