Skip to content

Commit

Permalink
chat: move cursor to end of line
Browse files Browse the repository at this point in the history
- also fix possible loss of data when editing a reply to a chat and
  scrolling around
  • Loading branch information
williamstein committed Oct 12, 2024
1 parent e793d72 commit 4d9695a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 50 deletions.
17 changes: 13 additions & 4 deletions src/packages/frontend/chat/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function ChatInput({
() => redux.getStore("account").get_account_id(),
[],
);

const controlRef = useRef<any>(null);
const [input, setInput] = useState<string>("");
useEffect(() => {
const dbInput = syncdb
Expand All @@ -80,12 +80,20 @@ export default function ChatInput({
// the db version is used when you refresh your browser while editing, or scroll up and down
// thus unmounting and remounting the currently editing message (due to virtualization).
// See https://github.com/sagemathinc/cocalc/issues/6415
setInput(dbInput ?? propsInput);
const input = dbInput ?? propsInput;
setInput(input);
if (input?.trim()) {
// have to wait until it's all rendered -- i hate code like this...
for (const n of [1, 10, 50]) {
setTimeout(() => {
controlRef.current?.moveCursorToEndOfLine();
}, n);
}
}
}, [date, sender_id, propsInput]);

const currentInputRef = useRef<string>(input);
const saveOnUnmountRef = useRef<boolean>(true);

const isMountedRef = useIsMountedRef();
const lastSavedRef = useRef<string>(input);
const saveChat = useDebouncedCallback(
Expand Down Expand Up @@ -142,7 +150,7 @@ export default function ChatInput({
// Note: it is still slightly annoying, due to loss of focus... however, data
// loss is NOT ok, whereas loss of focus is.
const input = currentInputRef.current;
if (input == null || syncdb == null) {
if (!input || syncdb == null) {
return;
}
if (
Expand Down Expand Up @@ -212,6 +220,7 @@ export default function ChatInput({
onBlur={onBlur}
cacheId={cacheId}
value={input}
controlRef={controlRef}
enableUpload={true}
enableMentions={true}
submitMentionsRef={submitMentionsRef}
Expand Down
95 changes: 49 additions & 46 deletions src/packages/frontend/editors/markdown-input/multimode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,54 +134,56 @@ interface Props {
overflowEllipsis?: boolean; // if true, show "..." button popping up all menu entries

dirtyRef?: MutableRefObject<boolean>; // a boolean react ref that gets set to true whenever document changes for any reason (client should explicitly set this back to false).

controlRef?: MutableRefObject<any>;
}

export default function MultiMarkdownInput(props: Props) {
const {
autoFocus,
cacheId,
cmOptions,
compact,
cursors,
defaultMode,
dirtyRef,
editBarStyle,
editorDivRef,
enableMentions,
enableUpload = true,
extraHelp,
fixedMode,
fontSize,
getValueRef,
height = "auto",
hideHelp,
isFocused,
minimal,
modeSwitchStyle,
noVfill,
onBlur,
onChange,
onCursorBottom,
onCursors,
onCursorTop,
onFocus,
onModeChange,
onRedo,
onSave,
onShiftEnter,
onUndo,
onUploadEnd,
onUploadStart,
overflowEllipsis = false,
placeholder,
refresh,
registerEditor,
saveDebounceMs = SAVE_DEBOUNCE_MS,
style,
submitMentionsRef,
unregisterEditor,
value,
} = props;
export default function MultiMarkdownInput({
autoFocus,
cacheId,
cmOptions,
compact,
cursors,
defaultMode,
dirtyRef,
editBarStyle,
editorDivRef,
enableMentions,
enableUpload = true,
extraHelp,
fixedMode,
fontSize,
getValueRef,
height = "auto",
hideHelp,
isFocused,
minimal,
modeSwitchStyle,
noVfill,
onBlur,
onChange,
onCursorBottom,
onCursors,
onCursorTop,
onFocus,
onModeChange,
onRedo,
onSave,
onShiftEnter,
onUndo,
onUploadEnd,
onUploadStart,
overflowEllipsis = false,
placeholder,
refresh,
registerEditor,
saveDebounceMs = SAVE_DEBOUNCE_MS,
style,
submitMentionsRef,
unregisterEditor,
value,
controlRef,
}: Props) {
const {
isFocused: isFocusedFrame,
isVisible,
Expand Down Expand Up @@ -529,6 +531,7 @@ export default function MultiMarkdownInput(props: Props) {
submitMentionsRef={submitMentionsRef}
editBar2={editBar2}
dirtyRef={dirtyRef}
controlRef={controlRef}
/>
</div>
) : undefined}
Expand Down
11 changes: 11 additions & 0 deletions src/packages/frontend/editors/slate/editable-markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { markdown_to_html } from "@cocalc/frontend/markdown";
import Fragment, { FragmentId } from "@cocalc/frontend/misc/fragment-id";
import { Descendant, Editor, Range, Transforms, createEditor } from "slate";
import { resetSelection } from "./control";
import * as control from "./control";
import { useBroadcastCursors, useCursorDecorate } from "./cursors";
import { EditBar, useLinkURL, useListProperties, useMarks } from "./edit-bar";
import { Element } from "./element";
Expand Down Expand Up @@ -121,6 +122,9 @@ interface Props {
editBar2?: MutableRefObject<JSX.Element | undefined>;
dirtyRef?: MutableRefObject<boolean>;
minimal?: boolean;
controlRef?: MutableRefObject<{
moveCursorToEndOfLine: () => void;
} | null>;
}

export const EditableMarkdown: React.FC<Props> = React.memo((props: Props) => {
Expand Down Expand Up @@ -159,6 +163,7 @@ export const EditableMarkdown: React.FC<Props> = React.memo((props: Props) => {
submitMentionsRef,
unregisterEditor,
value,
controlRef,
} = props;
const { project_id, path, desc, isVisible } = useFrameContext();
const isMountedRef = useIsMountedRef();
Expand Down Expand Up @@ -246,6 +251,12 @@ export const EditableMarkdown: React.FC<Props> = React.memo((props: Props) => {
};
}

if (controlRef != null) {
controlRef.current = {
moveCursorToEndOfLine: () => control.moveCursorToEndOfLine(ed),
};
}

ed.onCursorBottom = onCursorBottom;
ed.onCursorTop = onCursorTop;

Expand Down

0 comments on commit 4d9695a

Please sign in to comment.