diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/documents/DocUtils.ts | 79 | ||||
-rw-r--r-- | src/client/documents/Documents.ts | 36 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/DailyJournal.tsx | 84 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 28 | ||||
-rw-r--r-- | src/fields/RichTextField.ts | 29 |
5 files changed, 137 insertions, 119 deletions
diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 1c7ccadd1..84e2db989 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -715,32 +715,59 @@ export namespace DocUtils { nativeWidth: 40, nativeHeight: 40, }) - : Docs.Create.TextDocument('', { - annotationOn, - backgroundColor, - x, - y, - title, - ...(defaultTextTemplate - ? {} // if the new doc will inherit from a template, don't set any layout fields since that would block the inheritance - : { - _width: width || BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 * 6 : 200, - _height: BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 : 35, - _layout_centered: BoolCast(Doc.UserDoc()._layout_centered), - _layout_fitWidth: true, - _layout_autoHeight: true, - backgroundColor: StrCast(Doc.UserDoc().textBackgroundColor), - borderColor: Doc.UserDoc().borderColor as string, - borderWidth: Doc.UserDoc().borderWidth as number, - text_fitBox: BoolCast(Doc.UserDoc().fitBox), - text_align: StrCast(Doc.UserDoc().textAlign), - text_fontColor: StrCast(Doc.UserDoc().fontColor), - text_fontFamily: StrCast(Doc.UserDoc().fontFamily), - text_fontWeight: StrCast(Doc.UserDoc().fontWeight), - text_fontStyle: StrCast(Doc.UserDoc().fontStyle), - text_fontDecoration: StrCast(Doc.UserDoc().fontDecoration), - }), - }); + : defaultTextTemplate?.type === DocumentType.JOURNAL + ? Docs.Create.DailyJournalDocument('', { + annotationOn, + backgroundColor, + x, + y, + title, + ...(defaultTextTemplate + ? {} // if the new doc will inherit from a template, don't set any layout fields since that would block the inheritance + : { + _width: width || BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 * 6 : 200, + _height: BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 : 35, + _layout_centered: BoolCast(Doc.UserDoc()._layout_centered), + _layout_fitWidth: true, + _layout_autoHeight: true, + backgroundColor: StrCast(Doc.UserDoc().textBackgroundColor), + borderColor: Doc.UserDoc().borderColor as string, + borderWidth: Doc.UserDoc().borderWidth as number, + text_fitBox: BoolCast(Doc.UserDoc().fitBox), + text_align: StrCast(Doc.UserDoc().textAlign), + text_fontColor: StrCast(Doc.UserDoc().fontColor), + text_fontFamily: StrCast(Doc.UserDoc().fontFamily), + text_fontWeight: StrCast(Doc.UserDoc().fontWeight), + text_fontStyle: StrCast(Doc.UserDoc().fontStyle), + text_fontDecoration: StrCast(Doc.UserDoc().fontDecoration), + }), + }) + : Docs.Create.TextDocument('', { + annotationOn, + backgroundColor, + x, + y, + title, + ...(defaultTextTemplate + ? {} // if the new doc will inherit from a template, don't set any layout fields since that would block the inheritance + : { + _width: width || BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 * 6 : 200, + _height: BoolCast(Doc.UserDoc().fitBox) ? Number(StrCast(Doc.UserDoc().fontSize).replace('px', '')) * 1.5 : 35, + _layout_centered: BoolCast(Doc.UserDoc()._layout_centered), + _layout_fitWidth: true, + _layout_autoHeight: true, + backgroundColor: StrCast(Doc.UserDoc().textBackgroundColor), + borderColor: Doc.UserDoc().borderColor as string, + borderWidth: Doc.UserDoc().borderWidth as number, + text_fitBox: BoolCast(Doc.UserDoc().fitBox), + text_align: StrCast(Doc.UserDoc().textAlign), + text_fontColor: StrCast(Doc.UserDoc().fontColor), + text_fontFamily: StrCast(Doc.UserDoc().fontFamily), + text_fontWeight: StrCast(Doc.UserDoc().fontWeight), + text_fontStyle: StrCast(Doc.UserDoc().fontStyle), + text_fontDecoration: StrCast(Doc.UserDoc().fontDecoration), + }), + }); if (defaultTextTemplate) { tbox.layout_fieldKey = 'layout_' + StrCast(defaultTextTemplate.title); diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 317bb7feb..fe121021d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -920,22 +920,36 @@ export namespace Docs { // AARAV ADD // export function DailyJournalDocument(text: string | RichTextField, options: DocumentOptions = {}, fieldKey: string = 'text') { - const styles = { - bold: true, // Make the journal date bold - color: 'blue', // Set the journal date color to blue - fontSize: 18, // Set the font size to 18px for the whole text + const getFormattedDate = () => { + const date = new Date().toLocaleDateString(undefined, { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + }); + return date; + }; + + const getDailyText = () => { + const placeholderText = 'Start writing here...'; + const dateText = `${getFormattedDate()}`; + + return RichTextField.textToRtfFormat( + [ + { text: 'Journal Entry:', styles: { bold: true, color: 'black', fontSize: 20 } }, + { text: dateText, styles: { italic: true, color: 'gray', fontSize: 15 } }, + { text: placeholderText, styles: { fontSize: 14, color: 'gray' } }, + ], + undefined, + placeholderText.length + ); }; return InstanceFromProto( Prototypes.get(DocumentType.JOURNAL), - typeof text === 'string' ? RichTextField.textToRtf(text, undefined, styles, undefined) : text, + getDailyText(), { - title: new Date().toLocaleDateString(undefined, { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric', - }), + title: getFormattedDate(), ...options, }, undefined, diff --git a/src/client/views/nodes/formattedText/DailyJournal.tsx b/src/client/views/nodes/formattedText/DailyJournal.tsx index ec1f7a023..51e9d9ec1 100644 --- a/src/client/views/nodes/formattedText/DailyJournal.tsx +++ b/src/client/views/nodes/formattedText/DailyJournal.tsx @@ -1,6 +1,5 @@ -import { action, makeObservable, observable } from 'mobx'; +import { makeObservable } from 'mobx'; import * as React from 'react'; -import { RichTextField } from '../../../../fields/RichTextField'; import { Docs } from '../../../documents/Documents'; import { DocumentType } from '../../../documents/DocumentTypes'; import { ViewBoxAnnotatableComponent } from '../../DocComponent'; @@ -8,8 +7,6 @@ import { FieldView, FieldViewProps } from '../FieldView'; import { FormattedTextBox, FormattedTextBoxProps } from './FormattedTextBox'; export class DailyJournal extends ViewBoxAnnotatableComponent<FieldViewProps>() { - @observable journalDate: string; - public static LayoutString(fieldStr: string) { return FieldView.LayoutString(DailyJournal, fieldStr); } @@ -17,73 +14,26 @@ export class DailyJournal extends ViewBoxAnnotatableComponent<FieldViewProps>() constructor(props: FormattedTextBoxProps) { super(props); makeObservable(this); - this.journalDate = this.getFormattedDate(); - - console.log('Constructor: Setting initial title and text...'); - this.setDailyTitle(); - this.setDailyText(); - } - - getFormattedDate(): string { - const date = new Date().toLocaleDateString(undefined, { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric', - }); - console.log('getFormattedDate():', date); - return date; - } - - @action - setDailyTitle() { - console.log('setDailyTitle() called...'); - console.log('Current title before update:', this.dataDoc.title); - - if (!this.dataDoc.title || this.dataDoc.title !== this.journalDate) { - console.log('Updating title to:', this.journalDate); - this.dataDoc.title = this.journalDate; - } - - console.log('New title after update:', this.dataDoc.title); - } - - @action - setDailyText() { - console.log('setDailyText() called...'); - const placeholderText = 'Start writing here...'; - const initialText = `Journal Entry - ${this.journalDate}\n${placeholderText}`; - - console.log('Checking if dataDoc has text field...'); - - const styles = { - bold: true, // Make the journal date bold - color: 'blue', // Set the journal date color to blue - fontSize: 18, // Set the font size to 18px for the whole text - }; - - console.log('Setting new text field with:', initialText); - this.dataDoc[this.fieldKey] = RichTextField.textToRtf( - initialText, - undefined, // No image DocId - styles, // Pass the styles object here - placeholderText.length // The position for text selection - ); - - console.log('Current text field:', this.dataDoc[this.fieldKey]); - } - - componentDidMount(): void { - console.log('componentDidMount() triggered...'); - // bcz: This should be moved into Docs.Create.DailyJournalDocument() - // otherwise, it will override all the text whenever the note is reloaded - this.setDailyTitle(); - this.setDailyText(); } render() { return ( - <div style={{ background: 'beige', width: '100%', height: '100%' }}> + <div + style={{ + // background: 'beige', + width: '100%', + height: '100%', + backgroundColor: 'beige', + backgroundImage: ` + repeating-linear-gradient( + to bottom, + rgba(255, 26, 26, 0.2) 0px, rgba(255, 26, 26, 0.2) 1px, /* Thin red stripes */ + transparent 1px, transparent 20px + ) + `, + backgroundSize: '100% 20px', + backgroundRepeat: 'repeat', + }}> <FormattedTextBox {...this._props} fieldKey={'text'} Document={this.Document} TemplateDataDocument={undefined} /> </div> ); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 3844616fd..9d3050d90 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -2,9 +2,10 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; +import { Property } from 'csstype'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction } from 'mobx'; import { observer } from 'mobx-react'; -import { baseKeymap, selectAll } from 'prosemirror-commands'; +import { baseKeymap, selectAll, splitBlock } from 'prosemirror-commands'; import { history } from 'prosemirror-history'; import { inputRules } from 'prosemirror-inputrules'; import { keymap } from 'prosemirror-keymap'; @@ -49,12 +50,14 @@ import { AnchorMenu } from '../../pdf/AnchorMenu'; import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup'; import { PinDocView, PinProps } from '../../PinFuncs'; import { SidebarAnnos } from '../../SidebarAnnos'; +import { StickerPalette } from '../../smartdraw/StickerPalette'; import { StyleProp } from '../../StyleProp'; import { styleFromLayoutString } from '../../StyleProvider'; import { mediaState } from '../AudioBox'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { FocusViewOptions } from '../FocusViewOptions'; +import { LabelBox } from '../LabelBox'; import { LinkInfo } from '../LinkDocPreview'; import { OpenWhere } from '../OpenWhere'; import './FormattedTextBox.scss'; @@ -64,9 +67,6 @@ import { removeMarkWithAttrs } from './prosemirrorPatches'; import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; -import { Property } from 'csstype'; -import { LabelBox } from '../LabelBox'; -import { StickerPalette } from '../../smartdraw/StickerPalette'; // import * as applyDevTools from 'prosemirror-dev-tools'; export interface FormattedTextBoxProps extends FieldViewProps { @@ -449,7 +449,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB Doc.MyPublishedDocs.filter(term => term.title).forEach(term => { tr = this.hyperlinkTerm(tr, term, newAutoLinks); }); - tr = tr.setSelection(new TextSelection(tr.doc.resolve(from), tr.doc.resolve(to))); + const marks = tr.storedMarks; + tr = tr.setSelection(new TextSelection(tr.doc.resolve(from), tr.doc.resolve(to))).setStoredMarks(marks); this.EditorView?.dispatch(tr); } oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.Document).forEach(doc => Doc.DeleteLink?.(doc)); @@ -1541,25 +1542,24 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB this._editorView.TextView = this; } - const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, DocumentView.SelectOnLoad) && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.())); + const selectOnLoad = + Doc.AreProtosEqual(this._props.TemplateDataDocument ?? DocCast(this.Document.rootDocument, this.Document), DocumentView.SelectOnLoad) && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.())); const selLoadChar = FormattedTextBox.SelectOnLoadChar; if (selectOnLoad) { DocumentView.SetSelectOnLoad(undefined); FormattedTextBox.SelectOnLoadChar = ''; } if (this.EditorView && selectOnLoad && !this._props.dontRegisterView && !this._props.dontSelectOnLoad && this.isActiveTab(this.ProseRef)) { - const $from = this.EditorView.state.selection.anchor ? this.EditorView.state.doc.resolve(this.EditorView.state.selection.anchor - 1) : undefined; + const { $from } = this.EditorView.state.selection; const mark = schema.marks.user_mark.create({ userid: ClientUtils.CurrentUserEmail(), modified: Math.floor(Date.now() / 1000) }); const curMarks = this.EditorView.state.storedMarks ?? $from?.marksAcross(this.EditorView.state.selection.$head) ?? []; const storedMarks = [...curMarks.filter(m => m.type !== mark.type), mark]; - let { tr } = this.EditorView.state; - if (selLoadChar) { - const tr1 = this.EditorView.state.tr.setStoredMarks(storedMarks); - tr = selLoadChar === 'Enter' ? tr1.insert(this.EditorView.state.doc.content.size - 1, schema.nodes.paragraph.create()) : tr1.insertText(selLoadChar, this.EditorView.state.doc.content.size - 1); - } - this.EditorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(tr.doc.content.size - 1))).setStoredMarks(storedMarks)); + if (selLoadChar === 'Enter') { + splitBlock(this.EditorView.state, (tx3: Transaction) => this.EditorView?.dispatch(tx3.setStoredMarks(storedMarks))); + } else if (selLoadChar) { + this.EditorView.dispatch(this.EditorView.state.tr.replaceSelectionWith(this.EditorView.state.schema.text(selLoadChar, storedMarks))); // prettier-ignore + } else this.EditorView.dispatch(this.EditorView.state.tr.setStoredMarks(storedMarks)); this.tryUpdateDoc(true); // calling select() above will make isContentActive() true only after a render .. which means the selectAll() above won't write to the Document and the incomingValue will overwrite the selection with the non-updated data - console.log(this.EditorView.state); } if (selectOnLoad) { this.EditorView!.focus(); diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts index 63ae61c2f..81b6c9ea9 100644 --- a/src/fields/RichTextField.ts +++ b/src/fields/RichTextField.ts @@ -42,7 +42,8 @@ export class RichTextField extends ObjectField { return this.Text; } - // AARAV ADD= + // AARAV ADD + static ToProsemirrorDoc = (content: Record<string, unknown>[], selection: Record<string, unknown>) => ({ doc: { type: 'doc', @@ -86,7 +87,33 @@ export class RichTextField extends ObjectField { { type: 'text', anchor: 2 + plaintext.length - (selectBack ?? 0), head: 2 + plaintext.length } ); + // AARAV ADD + + // takes in text segments instead of single text field + private static ToProsemirrorSegmented = (textSegments: { text: string; styles?: { bold?: boolean; italic?: boolean; fontSize?: number; color?: string } }[], imgDocId?: string, selectBack?: number) => + RichTextField.ToProsemirrorDoc( + textSegments.map(seg => ({ + type: 'paragraph', // Each segment becomes its own paragraph + content: [...RichTextField.ToProsemirrorTextContent(seg.text, seg.styles), ...(imgDocId ? RichTextField.ToProsemirrorDashDocContent(imgDocId) : [])], + })), + (textLen => ({ + type: 'text', + anchor: textLen - (selectBack ?? 0), + head: textLen, + }))(2 * textSegments.length + textSegments.map(seg => seg.text).join('').length - 1) + // selection/doc end = text length + 2 for each paragraph. subtract 1 to set selection inside of end of last paragraph + ); + + // AARAV ADD || + public static textToRtf(text: string, imgDocId?: string, styles?: { bold?: boolean; italic?: boolean; fontSize?: number; color?: string }, selectBack?: number) { return new RichTextField(JSON.stringify(RichTextField.ToProsemirror(text, imgDocId, styles, selectBack)), text); } + + // AARAV ADD + public static textToRtfFormat(textSegments: { text: string; styles?: { bold?: boolean; italic?: boolean; fontSize?: number; color?: string } }[], imgDocId?: string, selectBack?: number) { + return new RichTextField(JSON.stringify(RichTextField.ToProsemirrorSegmented(textSegments, imgDocId, selectBack)), textSegments.map(seg => seg.text).join('')); + } + + // AARAV ADD } |