aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraaravkumar <aarav.kumar1510@gmail.com>2025-03-19 19:05:43 -0400
committeraaravkumar <aarav.kumar1510@gmail.com>2025-03-19 19:05:43 -0400
commit9c5d14fdd562dc1bcc8aa0f73ce7ad189c9fbf23 (patch)
tree48914694f915460ac7bbc7cf93737df95779fe26
parent289030cc82c4cef6db46695c841cb99e4cd90101 (diff)
daily journal title/text update fixes + GPT prompts button for journalling prompts integration
-rw-r--r--src/client/documents/Documents.ts52
-rw-r--r--src/client/views/nodes/formattedText/DailyJournal.tsx145
2 files changed, 169 insertions, 28 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fe121021d..668725d2b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -920,36 +920,36 @@ export namespace Docs {
// AARAV ADD //
export function DailyJournalDocument(text: string | RichTextField, options: DocumentOptions = {}, fieldKey: string = '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
- );
- };
+ // 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),
- getDailyText(),
+ "",
{
- title: getFormattedDate(),
+ title: "",
...options,
},
undefined,
diff --git a/src/client/views/nodes/formattedText/DailyJournal.tsx b/src/client/views/nodes/formattedText/DailyJournal.tsx
index 51e9d9ec1..31108f05a 100644
--- a/src/client/views/nodes/formattedText/DailyJournal.tsx
+++ b/src/client/views/nodes/formattedText/DailyJournal.tsx
@@ -1,12 +1,17 @@
-import { makeObservable } from 'mobx';
+import { makeObservable, action, observable, autorun } from 'mobx';
import * as React from 'react';
import { Docs } from '../../../documents/Documents';
import { DocumentType } from '../../../documents/DocumentTypes';
import { ViewBoxAnnotatableComponent } from '../../DocComponent';
import { FieldView, FieldViewProps } from '../FieldView';
import { FormattedTextBox, FormattedTextBoxProps } from './FormattedTextBox';
+import { gptAPICall, GPTCallType, gptImageLabel } from '../../../apis/gpt/GPT';
+import { RichTextField } from '../../../../fields/RichTextField';
+import { TextSelection } from 'prosemirror-state';
export class DailyJournal extends ViewBoxAnnotatableComponent<FieldViewProps>() {
+ @observable journalDate: string;
+
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(DailyJournal, fieldStr);
}
@@ -14,8 +19,126 @@ export class DailyJournal extends ViewBoxAnnotatableComponent<FieldViewProps>()
constructor(props: FormattedTextBoxProps) {
super(props);
makeObservable(this);
+ this.journalDate = this.getFormattedDate();
+ }
+
+ 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() {
+ const placeholderText = 'Start writing here...';
+ const dateText = `${this.journalDate}\n`;
+
+ console.log('Checking if dataDoc has text field...');
+
+ this.dataDoc[this.fieldKey] = 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
+ );
+
+ console.log('Current text field:', this.dataDoc[this.fieldKey]);
+ }
+
+ componentDidMount(): void {
+ console.log('componentDidMount() triggered...');
+ console.log("Text: " + (this.Document.text as any)?.Text);
+
+ const rawText = (this.Document.text as any)?.Text ?? '';
+ const isTextEmpty = !rawText || rawText === "";
+
+ const currentTitle = this.dataDoc.title || "";
+ const isTitleString = typeof currentTitle === 'string';
+ const isDefaultTitle = isTitleString && currentTitle.includes("Untitled DailyJournal");
+
+ if (isTextEmpty && isDefaultTitle) {
+ console.log('Journal title and text are default. Initializing...');
+ this.setDailyTitle();
+ this.setDailyText();
+ } else {
+ console.log('Journal already has content. Skipping initialization.');
+ }
}
+ @action handleGeneratePrompts = async () => {
+ const rawText = (this.Document.text as any)?.Text ?? '';
+ console.log('Extracted Journal Text:', rawText);
+ console.log('Before Update:', this.Document.text, 'Type:', typeof this.Document.text);
+
+ if (!rawText.trim()) {
+ alert('Journal is empty! Write something first.');
+ return;
+ }
+
+ try {
+ // Call GPT API to generate prompts
+ const res = await gptAPICall('Generate 1-2 short journal prompts for the following journal entry: ' + rawText, GPTCallType.COMPLETION);
+
+ if (!res) {
+ console.error('GPT call failed.');
+ return;
+ }
+
+ const editorView = this._ref.current?.EditorView;
+ if (!editorView) {
+ console.error('EditorView is not available.');
+ return;
+ }
+
+ else {
+ const { state, dispatch } = editorView;
+ const { schema } = state;
+
+ // Use available marks
+ const boldMark = schema.marks.strong.create();
+ const italicMark = schema.marks.em.create();
+ const fontSizeMark = schema.marks.pFontSize.create({ fontSize: "14px" });
+ const fontColorMark = schema.marks.pFontColor.create({ fontColor: "gray" });
+
+ // Create text nodes with formatting
+ const headerText = schema.text('\n\n# Suggested Prompts:\n', [boldMark, italicMark, fontSizeMark, fontColorMark]);
+ const responseText = schema.text(res, [fontSizeMark, fontColorMark]);
+
+ // Insert formatted text
+ const transaction = state.tr.insert(
+ state.selection.from, headerText).insert(
+ state.selection.from + headerText.nodeSize, responseText);
+ dispatch(transaction);
+ }
+
+ } catch (err) {
+ console.error('Error calling GPT:', err);
+ }
+ };
+
+ _ref = React.createRef<FormattedTextBox>();
+
render() {
return (
<div
@@ -34,7 +157,25 @@ export class DailyJournal extends ViewBoxAnnotatableComponent<FieldViewProps>()
backgroundSize: '100% 20px',
backgroundRepeat: 'repeat',
}}>
- <FormattedTextBox {...this._props} fieldKey={'text'} Document={this.Document} TemplateDataDocument={undefined} />
+ {/* GPT Button */}
+ <button
+ style={{
+ position: 'absolute',
+ bottom: '5px',
+ right: '5px',
+ padding: '5px 10px',
+ backgroundColor: '#9EAD7C',
+ color: 'white',
+ border: 'none',
+ borderRadius: '5px',
+ cursor: 'pointer',
+ zIndex: 10,
+ }}
+ onClick={this.handleGeneratePrompts}>
+ Prompts
+ </button>
+
+ <FormattedTextBox ref={this._ref} {...this._props} fieldKey={'text'} Document={this.Document} TemplateDataDocument={undefined} />
</div>
);
}