CLASSROOMIO-T-132: [BUG] WYSIWIG editing has wrong behavior

CLASSROOMIO-T-132: Final test & remove logs

CLASSROOMIO-T-132: Merge Fix (Tailwind Styling)

CLASSROOMIO-T-132: Merge Fix

Try out cl-editor

CLASSROOMIO-T-132: Experimental gpttyping + wysiwig implementation


Co-authored-by: Rotimi Best <rotimiibitoyeemma@gmail.com>
Co-authored-by: Tunji Adeyemi <tunji@digdippa.com>


Merge-request: CLASSROOMIO-MR-58
Merged-by: Best Admin <best@digdippa.com>
This commit is contained in:
Rotimi Best
2023-08-28 13:10:23 +00:00
committed by Space Cloud
co-authored by Rotimi Best Tunji Adeyemi
parent a3132371a1
commit 6a691d9fbd
5 changed files with 82 additions and 18 deletions
+1
View File
@@ -31,6 +31,7 @@
"axios": "^1.4.0", "axios": "^1.4.0",
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"canvas-confetti": "^1.6.0", "canvas-confetti": "^1.6.0",
"cl-editor": "^2.3.0",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"copy-to-clipboard": "^3.3.3", "copy-to-clipboard": "^3.3.3",
"form-data": "^4.0.0", "form-data": "^4.0.0",
+46
View File
@@ -0,0 +1,46 @@
<script>
import Editor from 'cl-editor/src/Editor.svelte';
export let html = '';
export let editor;
let colors = [
'#000000',
'#e60000',
'#ff9900',
'#ffff00',
'#008a00',
'#0066cc',
'#9933ff',
'#ffffff',
'#facccc',
'#ffebcc',
'#ffffcc',
'#cce8cc',
'#cce0f5',
'#ebd6ff',
'#bbbbbb',
'#f06666',
'#ffc266',
'#ffff66',
'#66b966',
'#66a3e0',
'#c285ff',
'#888888',
'#a10000',
'#b26b00',
'#b2b200',
'#006100',
'#0047b2',
'#6b24b2',
'#444444',
'#5c0000',
'#663d00',
'#666600',
'#003700',
'#002966',
'#3d1466'
];
</script>
<Editor bind:this={editor} {html} {colors} on:change={(evt) => (html = evt.detail)} />
@@ -17,6 +17,7 @@
import { VARIANTS } from '$lib/components/PrimaryButton/constants'; import { VARIANTS } from '$lib/components/PrimaryButton/constants';
import TextField from '$lib/components/Form/TextField.svelte'; import TextField from '$lib/components/Form/TextField.svelte';
import TextEditor from '$lib/components/TextEditor/index.svelte'; import TextEditor from '$lib/components/TextEditor/index.svelte';
// import ClEditor from '$lib/components/ClEditor/index.svelte';
import { import {
lesson, lesson,
lessons, lessons,
@@ -28,6 +29,7 @@
import VideoUploader from '$lib/components/Course/components/Lesson/Materials/Video/Index.svelte'; import VideoUploader from '$lib/components/Course/components/Lesson/Materials/Video/Index.svelte';
import { course } from '$lib/components/Course/store'; import { course } from '$lib/components/Course/store';
import * as CONSTANTS from './constants'; import * as CONSTANTS from './constants';
import isEmpty from 'lodash/isEmpty';
export let mode = MODES.view; export let mode = MODES.view;
export let prevMode = ''; export let prevMode = '';
@@ -61,6 +63,14 @@
handleUpdateLessonMaterials(_lesson, lessonId); handleUpdateLessonMaterials(_lesson, lessonId);
} }
function isNoteEmpty(note) {
if (!note || typeof note !== 'string') return true;
if (!note.trim()) return true;
if (note.trim() === '<p><br></p>') return true;
return false;
}
function handleSave(prevMode: string) { function handleSave(prevMode: string) {
if (prevMode === MODES.edit) { if (prevMode === MODES.edit) {
saveLesson(); saveLesson();
@@ -71,19 +81,15 @@
const { slide_url, videos, note } = materials; const { slide_url, videos, note } = materials;
tabs = tabs.map((tab) => { tabs = tabs.map((tab) => {
const badgeValue = let badgeValue = 0;
tab.value === 1
? note?.length > 15
? 1
: 0
: tab.value === 2
? !!slide_url
? 1
: 0
: Array.isArray(videos)
? videos.length
: 0;
if (tab.value === 1 && !isNoteEmpty(note)) {
badgeValue = 1;
} else if (tab.value === 2 && !!slide_url) {
badgeValue = 1;
} else if (tab.value === 3 && !isEmpty(videos)) {
badgeValue = 1;
}
tab.badgeValue = badgeValue; tab.badgeValue = badgeValue;
return tab; return tab;
}); });
@@ -227,8 +233,9 @@
bind:content={$lesson.materials.note} bind:content={$lesson.materials.note}
onChange={(c) => ($lesson.materials.note = c)} onChange={(c) => ($lesson.materials.note = c)}
/> />
<!-- <ClEditor bind:html={$lesson.materials.note} /> -->
</div> </div>
{:else if $lesson.materials?.note?.length > 15} {:else if !isNoteEmpty($lesson.materials?.note)}
<article class="preview prose prose-sm sm:prose p-2"> <article class="preview prose prose-sm sm:prose p-2">
{@html $lesson.materials.note} {@html $lesson.materials.note}
</article> </article>
+14 -1
View File
@@ -29,6 +29,7 @@
}; };
let quill = null; let quill = null;
let isUserTyping = false;
function resetContent(docId) { function resetContent(docId) {
if (quill && quill.setText) { if (quill && quill.setText) {
@@ -64,6 +65,16 @@
quill.on('text-change', function () { quill.on('text-change', function () {
onChange(quill.getHTML()); onChange(quill.getHTML());
}); });
quill.getModule('toolbar').container.addEventListener('mousedown', (e) => {
e.preventDefault();
isUserTyping = true;
});
quill.root.addEventListener('focus', () => {
isUserTyping = true;
});
quill.root.addEventListener('blur', () => {
isUserTyping = false;
});
}); });
$: { $: {
@@ -76,7 +87,9 @@
} }
} }
$: setQuillHTML(content); $: if (!isUserTyping) {
setQuillHTML(content);
}
$: resetContent(docId); $: resetContent(docId);
</script> </script>
+1 -4
View File
@@ -22,19 +22,16 @@ const instruction = {
export async function POST({ request }) { export async function POST({ request }) {
const { prompt } = await request.json(); const { prompt } = await request.json();
const { courseTitle, lessonTitle, type } = prompt; const { courseTitle, lessonTitle, type } = prompt;
console.log('prompt', prompt);
console.time('debugOpenAi');
const response = await openai.createChatCompletion({ const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo', model: 'gpt-3.5-turbo',
messages: [ messages: [
{ {
role: 'user', role: 'user',
content: `Generate a ${instruction[type]} given the course title is "${courseTitle}" and the lesson is "${lessonTitle}". Format in HTML without any styling, don't include the title of the course and title of the lesson in the result & make sure the content is well detailed.` content: `Generate a ${instruction[type]} given the course title is "${courseTitle}" and the lesson is "${lessonTitle}". Format in HTML without any styling, no ul, ol or li tags, don't include the title of the course and title of the lesson in the result & make sure the content is well detailed.`
} }
], ],
stream: true stream: true
}); });
console.timeEnd('debugOpenAi');
// Convert the response into a friendly text-stream // Convert the response into a friendly text-stream
const stream = OpenAIStream(response); const stream = OpenAIStream(response);
// Respond with the stream // Respond with the stream