diff --git a/front/components/auth/HeaderProfileBox.tsx b/front/components/auth/HeaderProfileBox.tsx
index f9e023e8..1d2f969e 100644
--- a/front/components/auth/HeaderProfileBox.tsx
+++ b/front/components/auth/HeaderProfileBox.tsx
@@ -3,10 +3,11 @@ import styled from "styled-components";
import Link from "next/link";
import { AuthContext } from "../security/AuthProvider";
import { getBackendUrl } from "../../services/config";
+import Avvvatars from "avvvatars-react";
export const HeaderProfileBox = () => {
const auth: any = React.useContext(AuthContext);
-
+
return (
{!auth.isAuthenticated && (
@@ -25,10 +26,14 @@ export const HeaderProfileBox = () => {
)}
- {auth.isAuthenticated &&
- {auth.userInfo.username}
-
- }
+ {auth.isAuthenticated && (
+
+ {auth.userInfo.username}
+
+
+ )}
);
};
@@ -38,10 +43,10 @@ const AccountArea = styled.div`
display: flex;
place-items: center;
- div{
+ div {
margin-right: 10px;
}
- img{
+ img {
width: 29px;
border-radius: 19px;
}
@@ -51,8 +56,6 @@ const ProfileArea = styled.div`
display: flex;
place-items: stretch;
place-items: center;
-
-
`;
const UnidentifiedArea = styled.div`
diff --git a/front/components/drags/chapter.tsx b/front/components/drags/chapter.tsx
index b588b6bc..07eba77a 100644
--- a/front/components/drags/chapter.tsx
+++ b/front/components/drags/chapter.tsx
@@ -27,7 +27,7 @@ function Chapter(props: any) {
{(provided) => (
{props.info.list.elements.map((element: any, index: any) => (
-
+
))}
{provided.placeholder}
diff --git a/front/components/editor/Editor.tsx b/front/components/editor/Editor.tsx
index d1a26729..2be56686 100644
--- a/front/components/editor/Editor.tsx
+++ b/front/components/editor/Editor.tsx
@@ -2,6 +2,7 @@ import { default as React, useEffect, useRef } from "react";
import * as Y from "yjs";
import { WebrtcProvider } from "y-webrtc";
import EditorWithOptions from "./EditorWithOptions";
+import { IndexeddbPersistence } from 'y-indexeddb'
// tools
@@ -14,6 +15,7 @@ function Editor() {
function createRTCProvider() {
const provider = new WebrtcProvider("learnhouse-1", ydoc);
+
setYdocState(ydoc);
setProviderState(provider);
setIsLoading(false);
diff --git a/front/components/editor/EditorWithOptions.tsx b/front/components/editor/EditorWithOptions.tsx
index 7b73e943..b79b013c 100644
--- a/front/components/editor/EditorWithOptions.tsx
+++ b/front/components/editor/EditorWithOptions.tsx
@@ -3,8 +3,12 @@ import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Collaboration from "@tiptap/extension-collaboration";
import CollaborationCursor from "@tiptap/extension-collaboration-cursor";
+import { AuthContext } from "../security/AuthProvider";
+
function EditorWithOptions(props: any) {
+ const auth: any = React.useContext(AuthContext);
+
const MenuBar = ({ editor }: any) => {
if (!editor) {
return null;
@@ -110,6 +114,7 @@ function EditorWithOptions(props: any) {
StarterKit.configure({
// The Collaboration extension comes with its own history handling
history: false,
+
}),
// Register the document with Tiptap
Collaboration.configure({
@@ -119,14 +124,16 @@ function EditorWithOptions(props: any) {
CollaborationCursor.configure({
provider: props.provider,
user: {
- name: "Cyndi Lauper",
+ name: auth.userInfo.username,
color: "#f783ac",
},
}),
],
+
content: "
diff --git a/front/package-lock.json b/front/package-lock.json
index a13f3717..16f820df 100644
--- a/front/package-lock.json
+++ b/front/package-lock.json
@@ -12,12 +12,14 @@
"@tiptap/extension-collaboration-cursor": "^2.0.0-beta.199",
"@tiptap/react": "^2.0.0-beta.199",
"@tiptap/starter-kit": "^2.0.0-beta.199",
+ "avvvatars-react": "^0.4.2",
"framer-motion": "^7.3.6",
"next": "12.3.1",
"react": "18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "18.2.0",
"styled-components": "^5.3.5",
+ "y-indexeddb": "^9.0.9",
"y-webrtc": "^10.2.3",
"yjs": "^13.5.42"
},
@@ -1488,6 +1490,18 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/avvvatars-react": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/avvvatars-react/-/avvvatars-react-0.4.2.tgz",
+ "integrity": "sha512-D/bnSM+P6pQi71dFeFVqQsqmv+ct5XG7uO2lvJoiksALpXLd6kPgpRR1SUQxFZJkJNrkmg0NPgbhIgJgOsDYRQ==",
+ "dependencies": {
+ "goober": "^2.1.8"
+ },
+ "peerDependencies": {
+ "react": ">= 16",
+ "react-dom": ">= 16"
+ }
+ },
"node_modules/axe-core": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz",
@@ -2682,6 +2696,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/goober": {
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.11.tgz",
+ "integrity": "sha512-5SS2lmxbhqH0u9ABEWq7WPU69a4i2pYcHeCxqaNq6Cw3mnrF0ghWNM4tEGid4dKy8XNIAUbuThuozDHHKJVh3A==",
+ "peerDependencies": {
+ "csstype": "^3.0.10"
+ }
+ },
"node_modules/grapheme-splitter": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
@@ -4596,6 +4618,21 @@
}
}
},
+ "node_modules/y-indexeddb": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/y-indexeddb/-/y-indexeddb-9.0.9.tgz",
+ "integrity": "sha512-GcJbiJa2eD5hankj46Hea9z4hbDnDjvh1fT62E5SpZRsv8GcEemw34l1hwI2eknGcv5Ih9JfusT37JLx9q3LFg==",
+ "dependencies": {
+ "lib0": "^0.2.35"
+ },
+ "funding": {
+ "type": "GitHub Sponsors ❤",
+ "url": "https://github.com/sponsors/dmonad"
+ },
+ "peerDependencies": {
+ "yjs": "^13.0.0"
+ }
+ },
"node_modules/y-prosemirror": {
"version": "1.0.20",
"resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.0.20.tgz",
@@ -5640,6 +5677,14 @@
"postcss-value-parser": "^4.2.0"
}
},
+ "avvvatars-react": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/avvvatars-react/-/avvvatars-react-0.4.2.tgz",
+ "integrity": "sha512-D/bnSM+P6pQi71dFeFVqQsqmv+ct5XG7uO2lvJoiksALpXLd6kPgpRR1SUQxFZJkJNrkmg0NPgbhIgJgOsDYRQ==",
+ "requires": {
+ "goober": "^2.1.8"
+ }
+ },
"axe-core": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz",
@@ -6533,6 +6578,12 @@
"slash": "^3.0.0"
}
},
+ "goober": {
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.11.tgz",
+ "integrity": "sha512-5SS2lmxbhqH0u9ABEWq7WPU69a4i2pYcHeCxqaNq6Cw3mnrF0ghWNM4tEGid4dKy8XNIAUbuThuozDHHKJVh3A==",
+ "requires": {}
+ },
"grapheme-splitter": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
@@ -7876,6 +7927,14 @@
"optional": true,
"requires": {}
},
+ "y-indexeddb": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/y-indexeddb/-/y-indexeddb-9.0.9.tgz",
+ "integrity": "sha512-GcJbiJa2eD5hankj46Hea9z4hbDnDjvh1fT62E5SpZRsv8GcEemw34l1hwI2eknGcv5Ih9JfusT37JLx9q3LFg==",
+ "requires": {
+ "lib0": "^0.2.35"
+ }
+ },
"y-prosemirror": {
"version": "1.0.20",
"resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.0.20.tgz",
diff --git a/front/package.json b/front/package.json
index 6ecb3588..50136b3f 100644
--- a/front/package.json
+++ b/front/package.json
@@ -13,12 +13,14 @@
"@tiptap/extension-collaboration-cursor": "^2.0.0-beta.199",
"@tiptap/react": "^2.0.0-beta.199",
"@tiptap/starter-kit": "^2.0.0-beta.199",
+ "avvvatars-react": "^0.4.2",
"framer-motion": "^7.3.6",
"next": "12.3.1",
"react": "18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "18.2.0",
"styled-components": "^5.3.5",
+ "y-indexeddb": "^9.0.9",
"y-webrtc": "^10.2.3",
"yjs": "^13.5.42"
},
diff --git a/front/pages/org/[orgslug]/course/[courseid]/[elementid]/edit.tsx b/front/pages/org/[orgslug]/course/[courseid]/[elementid]/edit.tsx
index 0b8061cc..d32088aa 100644
--- a/front/pages/org/[orgslug]/course/[courseid]/[elementid]/edit.tsx
+++ b/front/pages/org/[orgslug]/course/[courseid]/[elementid]/edit.tsx
@@ -3,6 +3,7 @@ import { default as React, useEffect, useRef } from "react";
import Layout from "../../../../../../components/ui/layout";
import { Title } from "../../../../../../components/ui/styles/title";
import dynamic from "next/dynamic";
+import { AuthContext } from "../../../../../../components/security/AuthProvider";
const Editor = dynamic(() => import("../../../../../../components/editor/editor"), {
ssr: false,
@@ -11,8 +12,8 @@ const Editor = dynamic(() => import("../../../../../../components/editor/editor"
// tools
function EditElement() {
- // A new Y document
-
+
+
return (
Edit Page
diff --git a/front/pages/org/[orgslug]/course/[courseid]/[elementid]/index.tsx b/front/pages/org/[orgslug]/course/[courseid]/[elementid]/index.tsx
index e69de29b..3aef1a47 100644
--- a/front/pages/org/[orgslug]/course/[courseid]/[elementid]/index.tsx
+++ b/front/pages/org/[orgslug]/course/[courseid]/[elementid]/index.tsx
@@ -0,0 +1,9 @@
+import React from 'react'
+
+function ElementPage() {
+ return (
+ ElementPage
+ )
+}
+
+export default ElementPage
\ No newline at end of file
diff --git a/front/styles/globals.css b/front/styles/globals.css
index d2c85aca..46708c0f 100644
--- a/front/styles/globals.css
+++ b/front/styles/globals.css
@@ -26,3 +26,41 @@ a {
background: #FBFBFB;
}
}
+
+/* Basic editor styles */
+.ProseMirror > * + * {
+ margin-top: 0.75em;
+}
+/* Placeholder (at the top) */
+.ProseMirror p.is-editor-empty:first-child::before {
+ color: #adb5bd;
+ content: attr(data-placeholder);
+ float: left;
+ height: 0;
+ pointer-events: none;
+}
+/* Give a remote user a caret */
+.collaboration-cursor__caret {
+ border-left: 1px solid #0d0d0d;
+ border-right: 1px solid #0d0d0d;
+ margin-left: -1px;
+ margin-right: -1px;
+ pointer-events: none;
+ position: relative;
+ word-break: normal;
+}
+/* Render the username above the caret */
+.collaboration-cursor__label {
+ border-radius: 3px 3px 3px 0;
+ color: #0d0d0d;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 600;
+ left: -1px;
+ line-height: normal;
+ padding: 0.1rem 0.3rem;
+ position: absolute;
+ top: -1.4em;
+ user-select: none;
+ white-space: nowrap;
+}