Merge pull request #390 from learnhouse/feat/remove-collaborative-feature

Remove collaborative features
This commit is contained in:
Badr B. 2024-11-26 17:05:13 +01:00 committed by GitHub
commit 6d668006f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 31 additions and 862 deletions

View file

@ -18,7 +18,6 @@ FROM base AS deps
ENV NEXT_PUBLIC_LEARNHOUSE_API_URL=http://localhost/api/v1/ ENV NEXT_PUBLIC_LEARNHOUSE_API_URL=http://localhost/api/v1/
ENV NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL=http://localhost/ ENV NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL=http://localhost/
ENV NEXT_PUBLIC_LEARNHOUSE_DOMAIN=localhost ENV NEXT_PUBLIC_LEARNHOUSE_DOMAIN=localhost
ENV NEXT_PUBLIC_LEARNHOUSE_COLLABORATION_WS_URL=ws://localhost:1998
WORKDIR /app/web WORKDIR /app/web
COPY ./apps/web/package.json ./apps/web/pnpm-lock.yaml* ./ COPY ./apps/web/package.json ./apps/web/pnpm-lock.yaml* ./

View file

@ -116,6 +116,7 @@ async def get_activity(
# Paid access check # Paid access check
has_paid_access = await check_activity_paid_access( has_paid_access = await check_activity_paid_access(
request=request,
activity_id=activity.id if activity.id else 0, activity_id=activity.id if activity.id else 0,
user=current_user, user=current_user,
db_session=db_session db_session=db_session

View file

@ -1,12 +1,14 @@
from sqlmodel import Session, select from sqlmodel import Session, select
from src.security.rbac.rbac import authorization_verify_if_user_is_author
from src.db.payments.payments_users import PaymentStatusEnum, PaymentsUser from src.db.payments.payments_users import PaymentStatusEnum, PaymentsUser
from src.db.users import PublicUser, AnonymousUser from src.db.users import PublicUser, AnonymousUser
from src.db.payments.payments_courses import PaymentsCourse from src.db.payments.payments_courses import PaymentsCourse
from src.db.courses.activities import Activity from src.db.courses.activities import Activity
from src.db.courses.courses import Course from src.db.courses.courses import Course
from fastapi import HTTPException from fastapi import HTTPException, Request
async def check_activity_paid_access( async def check_activity_paid_access(
request: Request,
activity_id: int, activity_id: int,
user: PublicUser | AnonymousUser, user: PublicUser | AnonymousUser,
db_session: Session, db_session: Session,
@ -33,6 +35,12 @@ async def check_activity_paid_access(
if not course: if not course:
raise HTTPException(status_code=404, detail="Course not found") raise HTTPException(status_code=404, detail="Course not found")
# Check if user is author of the course
is_course_author = await authorization_verify_if_user_is_author(request, user.id, "update", course.course_uuid, db_session)
if is_course_author:
return True
# Check if course is linked to a product # Check if course is linked to a product
statement = select(PaymentsCourse).where(PaymentsCourse.course_id == course.id) statement = select(PaymentsCourse).where(PaymentsCourse.course_id == course.id)

View file

@ -1 +0,0 @@
node_modules

View file

@ -1,34 +0,0 @@
# use the official Bun image
# see all versions at https://hub.docker.com/r/oven/bun/tags
FROM oven/bun:1 as base
WORKDIR /usr/src/app
# install dependencies into temp directory
# this will cache them and speed up future builds
FROM base AS install
RUN mkdir -p /temp/dev
COPY package.json /temp/dev/
RUN cd /temp/dev && bun install
# install with --production (exclude devDependencies)
RUN mkdir -p /temp/prod
COPY package.json pnpm-lock.yaml /temp/prod/
RUN cd /temp/prod && bun install --production
# copy node_modules from temp directory
# then copy all (non-ignored) project files into the image
FROM base AS prerelease
COPY --from=install /temp/dev/node_modules node_modules
COPY . .
# copy production dependencies and source code into final image
FROM base AS release
COPY --from=install /temp/prod/node_modules node_modules
COPY --from=prerelease /usr/src/app/app.ts .
COPY --from=prerelease /usr/src/app/package.json .
# run the app
USER bun
EXPOSE 1998/tcp
ENTRYPOINT [ "bun", "run", "app.ts" ]

View file

@ -1,9 +0,0 @@
import { Hocuspocus } from "@hocuspocus/server";
// Configure the server …
const server = new Hocuspocus({
port: 1998,
});
// … and run it!
server.listen();

View file

@ -1,20 +0,0 @@
{
"name": "collaboration",
"version": "1.0.0",
"description": "",
"main": "app.ts",
"scripts": {
"dev": "bun app.ts",
"start": "bun app.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@hocuspocus/server": "^2.13.7",
"bun": "^1.1.32",
"typescript": "5.4.4",
"y-protocols": "^1.0.6",
"yjs": "^13.6.20"
}
}

View file

@ -1,208 +0,0 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@hocuspocus/server':
specifier: ^2.13.7
version: 2.13.7(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20)
bun:
specifier: ^1.1.32
version: 1.1.32
typescript:
specifier: 5.4.4
version: 5.4.4
y-protocols:
specifier: ^1.0.6
version: 1.0.6(yjs@13.6.20)
yjs:
specifier: ^13.6.20
version: 13.6.20
packages:
'@hocuspocus/common@2.13.7':
resolution: {integrity: sha512-ROqYfW15XlAGd+qb/FVyp0zUC9Rosv7kdcck9LRMdfW3jT66wK9pDDWL2ily4Qj/zhbLCFtjAUPB4UKln/GYNQ==}
'@hocuspocus/server@2.13.7':
resolution: {integrity: sha512-D9juGX9NZoKT9/Ty/HGhaimHJe71DyKbYssC831oetYF33x3WSYV6GY82RhHo9xjKZE6r0Le7jgxgQb+u08slw==}
peerDependencies:
y-protocols: ^1.0.6
yjs: ^13.6.8
'@oven/bun-darwin-aarch64@1.1.32':
resolution: {integrity: sha512-/5lu8RJB/iEoC9pzFOCZLCEmNsEI3DEEyxfItZpih/piNOFhCYmoMvm7mM0YXqSc7pfxYaKukEZEHGeIOiu/3Q==}
cpu: [arm64]
os: [darwin]
'@oven/bun-darwin-x64-baseline@1.1.32':
resolution: {integrity: sha512-XRP+APoLxrXznL7BEHipAdDu0Mn1RwD9PsaqFu1Be5Dbyi+2bYICuTiN1W9vfZNN3kK8eTyniT7kjwLSTcHbEg==}
cpu: [x64]
os: [darwin]
'@oven/bun-darwin-x64@1.1.32':
resolution: {integrity: sha512-Slk4QFHcqZ94mnNlzsCG/9m+gET0mpi13bfizRGv8QNRku8mQTs9brN5XvovYrP5t0rfaZDFMOoaOs6wk6rcDg==}
cpu: [x64]
os: [darwin]
'@oven/bun-linux-aarch64@1.1.32':
resolution: {integrity: sha512-7QdyRCiLHb1MuwDH7iir5xD6gTKWlvMGxvcQhbY/U1djqG/gft4+PaJrSJQcVhqRb143mrMNXIhTgc84O6htMw==}
cpu: [arm64]
os: [linux]
'@oven/bun-linux-x64-baseline@1.1.32':
resolution: {integrity: sha512-zvXOAUTc6cOlUR26NEwh3isV+z2EW4QxFiWoxgvM7eIuZMnZjV22+H+dEzVKJzV58XgfPX//fEPi3Xjg4xXdMA==}
cpu: [x64]
os: [linux]
'@oven/bun-linux-x64@1.1.32':
resolution: {integrity: sha512-JgsQ1ZXKmovQNzf4YdA3WDZVrtEbMlbL43Yjcczovy6lDrhSZkTu1GjzMm5JQnuqNwBC4/eSIgVL27J1Pj6nlA==}
cpu: [x64]
os: [linux]
'@oven/bun-windows-x64-baseline@1.1.32':
resolution: {integrity: sha512-0DgP99AcBfKz3OCS5qO2/8e5TgNhBq8ZiNbPJzQaF4QOpS/Rt+mvFcQUa8x5gTOUPHH9ciaMz0IEs2Qv42eoAw==}
cpu: [x64]
os: [win32]
'@oven/bun-windows-x64@1.1.32':
resolution: {integrity: sha512-grzRSH/9YIKWUHumygtG9Aen04wJv+v6lbmTvqsfcc/1/BJJFCLf+69EN3PINAIisih1hycxGa9eleVxjL0fqg==}
cpu: [x64]
os: [win32]
async-lock@1.4.1:
resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==}
bun@1.1.32:
resolution: {integrity: sha512-W+UO0ihRmDHscmTfQAoPPaFLqLaloyBdAIr2iX70v3Vgo+7ZiKeyj7Aa4YDWStxQQmlzD5JP3NG/5TSWAK+1WQ==}
cpu: [arm64, x64]
os: [darwin, linux, win32]
hasBin: true
isomorphic.js@0.2.5:
resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==}
kleur@4.1.5:
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
engines: {node: '>=6'}
lib0@0.2.98:
resolution: {integrity: sha512-XteTiNO0qEXqqweWx+b21p/fBnNHUA1NwAtJNJek1oPrewEZs2uiT4gWivHKr9GqCjDPAhchz0UQO8NwU3bBNA==}
engines: {node: '>=16'}
hasBin: true
typescript@5.4.4:
resolution: {integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==}
engines: {node: '>=14.17'}
hasBin: true
uuid@10.0.0:
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
hasBin: true
ws@8.18.0:
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
y-protocols@1.0.6:
resolution: {integrity: sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
peerDependencies:
yjs: ^13.0.0
yjs@13.6.20:
resolution: {integrity: sha512-Z2YZI+SYqK7XdWlloI3lhMiKnCdFCVC4PchpdO+mCYwtiTwncjUbnRK9R1JmkNfdmHyDXuWN3ibJAt0wsqTbLQ==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
snapshots:
'@hocuspocus/common@2.13.7':
dependencies:
lib0: 0.2.98
'@hocuspocus/server@2.13.7(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20)':
dependencies:
'@hocuspocus/common': 2.13.7
async-lock: 1.4.1
kleur: 4.1.5
lib0: 0.2.98
uuid: 10.0.0
ws: 8.18.0
y-protocols: 1.0.6(yjs@13.6.20)
yjs: 13.6.20
transitivePeerDependencies:
- bufferutil
- utf-8-validate
'@oven/bun-darwin-aarch64@1.1.32':
optional: true
'@oven/bun-darwin-x64-baseline@1.1.32':
optional: true
'@oven/bun-darwin-x64@1.1.32':
optional: true
'@oven/bun-linux-aarch64@1.1.32':
optional: true
'@oven/bun-linux-x64-baseline@1.1.32':
optional: true
'@oven/bun-linux-x64@1.1.32':
optional: true
'@oven/bun-windows-x64-baseline@1.1.32':
optional: true
'@oven/bun-windows-x64@1.1.32':
optional: true
async-lock@1.4.1: {}
bun@1.1.32:
optionalDependencies:
'@oven/bun-darwin-aarch64': 1.1.32
'@oven/bun-darwin-x64': 1.1.32
'@oven/bun-darwin-x64-baseline': 1.1.32
'@oven/bun-linux-aarch64': 1.1.32
'@oven/bun-linux-x64': 1.1.32
'@oven/bun-linux-x64-baseline': 1.1.32
'@oven/bun-windows-x64': 1.1.32
'@oven/bun-windows-x64-baseline': 1.1.32
isomorphic.js@0.2.5: {}
kleur@4.1.5: {}
lib0@0.2.98:
dependencies:
isomorphic.js: 0.2.5
typescript@5.4.4: {}
uuid@10.0.0: {}
ws@8.18.0: {}
y-protocols@1.0.6(yjs@13.6.20):
dependencies:
lib0: 0.2.98
yjs: 13.6.20
yjs@13.6.20:
dependencies:
lib0: 0.2.98

View file

@ -1,67 +0,0 @@
import React, { useEffect, useState } from 'react'
import UserAvatar from '../UserAvatar'
import { useLHSession } from '@components/Contexts/LHSessionContext'
import { getUserAvatarMediaDirectory } from '@services/media/media';
import { getCollaborationServerUrl } from '@services/config/config';
import { useOrg } from '@components/Contexts/OrgContext';
type ActiveAvatarsProps = {
mouseMovements: any;
userRandomColor: string;
}
function ActiveAvatars(props: ActiveAvatarsProps) {
const session = useLHSession() as any;
const org = useOrg() as any;
const [activeUsers, setActiveUsers] = useState({} as any);
/* Collaboration Features */
const collab = getCollaborationServerUrl()
const isCollabEnabledOnThisOrg = org?.config.config.features.collaboration.enabled && collab
// Get users from the mouseMovements object
useEffect(() => {
const users: any = {};
Object.keys(props.mouseMovements).forEach((key) => {
users[props.mouseMovements[key].user.user_uuid] = props.mouseMovements[key].user;
});
// Remove the current user from the list
delete users[session.data.user.user_uuid];
setActiveUsers(users);
}
, [props.mouseMovements, session.data.user, org]);
return (
<div className=''>
<div className='flex -space-x-2 transition-all ease-linear'>
{isCollabEnabledOnThisOrg && Object.keys(activeUsers).map((key) => (
<div className='flex' style={{ position: 'relative' }} key={key}>
<UserAvatar
key={key}
width={40}
border="border-4"
rounded="rounded-full"
avatar_url={getUserAvatarMediaDirectory(activeUsers[key].user_uuid, activeUsers[key].avatar_image) as string}
/>
<div className="h-2 w-2 rounded-full" style={{ position: 'absolute', bottom: -5, right: 16, backgroundColor: props.mouseMovements[key].color }} />
</div>
))}
{session.status && (
<div className='z-50'>
<UserAvatar
width={40}
border="border-4"
rounded="rounded-full"
/>
</div>
)}
</div>
</div>
)
}
export default ActiveAvatars

View file

@ -21,7 +21,7 @@ import WarningCallout from './Extensions/Callout/Warning/WarningCallout'
import ImageBlock from './Extensions/Image/ImageBlock' import ImageBlock from './Extensions/Image/ImageBlock'
import Youtube from '@tiptap/extension-youtube' import Youtube from '@tiptap/extension-youtube'
import VideoBlock from './Extensions/Video/VideoBlock' import VideoBlock from './Extensions/Video/VideoBlock'
import { ComputerIcon, Eye, Monitor } from 'lucide-react' import { Eye, Monitor } from 'lucide-react'
import MathEquationBlock from './Extensions/MathEquation/MathEquationBlock' import MathEquationBlock from './Extensions/MathEquation/MathEquationBlock'
import PDFBlock from './Extensions/PDF/PDFBlock' import PDFBlock from './Extensions/PDF/PDFBlock'
import QuizBlock from './Extensions/Quiz/QuizBlock' import QuizBlock from './Extensions/Quiz/QuizBlock'
@ -45,17 +45,14 @@ import html from 'highlight.js/lib/languages/xml'
import python from 'highlight.js/lib/languages/python' import python from 'highlight.js/lib/languages/python'
import java from 'highlight.js/lib/languages/java' import java from 'highlight.js/lib/languages/java'
import { CourseProvider } from '@components/Contexts/CourseContext' import { CourseProvider } from '@components/Contexts/CourseContext'
import { useLHSession } from '@components/Contexts/LHSessionContext'
import AIEditorToolkit from './AI/AIEditorToolkit' import AIEditorToolkit from './AI/AIEditorToolkit'
import useGetAIFeatures from '@components/Hooks/useGetAIFeatures' import useGetAIFeatures from '@components/Hooks/useGetAIFeatures'
import Collaboration from '@tiptap/extension-collaboration'
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
import ActiveAvatars from './ActiveAvatars'
import { getUriWithOrg } from '@services/config/config' import { getUriWithOrg } from '@services/config/config'
import EmbedObjects from './Extensions/EmbedObjects/EmbedObjects' import EmbedObjects from './Extensions/EmbedObjects/EmbedObjects'
import Badges from './Extensions/Badges/Badges' import Badges from './Extensions/Badges/Badges'
import Buttons from './Extensions/Buttons/Buttons' import Buttons from './Extensions/Buttons/Buttons'
import { useMediaQuery } from 'usehooks-ts' import { useMediaQuery } from 'usehooks-ts'
import UserAvatar from '../UserAvatar'
interface Editor { interface Editor {
content: string content: string
@ -63,16 +60,10 @@ interface Editor {
course: any course: any
org: any org: any
session: any session: any
ydoc: any
hocuspocusProvider: any,
isCollabEnabledOnThisOrg: boolean
userRandomColor: string
mouseMovements: any
setContent: (content: string) => void setContent: (content: string) => void
} }
function Editor(props: Editor) { function Editor(props: Editor) {
const session = useLHSession() as any
const dispatchAIEditor = useAIEditorDispatch() as any const dispatchAIEditor = useAIEditorDispatch() as any
const aiEditorState = useAIEditor() as AIEditorStateTypes const aiEditorState = useAIEditor() as AIEditorStateTypes
const is_ai_feature_enabled = useGetAIFeatures({ feature: 'editor' }) const is_ai_feature_enabled = useGetAIFeatures({ feature: 'editor' })
@ -102,12 +93,8 @@ function Editor(props: Editor) {
const editor: any = useEditor({ const editor: any = useEditor({
editable: true, editable: true,
extensions: [ extensions: [
StarterKit.configure({ StarterKit,
// The Collaboration extension comes with its own history handling
history: props.isCollabEnabledOnThisOrg ? false : undefined,
}),
InfoCallout.configure({ InfoCallout.configure({
editable: true, editable: true,
}), }),
@ -159,28 +146,13 @@ function Editor(props: Editor) {
TableRow, TableRow,
TableHeader, TableHeader,
TableCell, TableCell,
// Add Collaboration and CollaborationCursor only if isCollabEnabledOnThisOrg is true
...(props.isCollabEnabledOnThisOrg ? [
Collaboration.configure({
document: props.hocuspocusProvider?.document,
}),
CollaborationCursor.configure({
provider: props.hocuspocusProvider,
user: {
name: props.session.data.user.first_name + ' ' + props.session.data.user.last_name,
color: props.userRandomColor,
},
}),
] : []),
], ],
content: props.content,
// If collab is enabled the onSynced callback ensures initial content is set only once using editor.setContent(), preventing repetitive content insertion on editor syncs. immediatelyRender: false,
content: props.isCollabEnabledOnThisOrg ? null : props.content,
}) })
console.log(props.content)
const isMobile = useMediaQuery('(max-width: 767px)') const isMobile = useMediaQuery('(max-width: 767px)')
if (isMobile) { if (isMobile) {
// TODO: Work on a better editor mobile experience // TODO: Work on a better editor mobile experience
@ -310,7 +282,7 @@ function Editor(props: Editor) {
/> />
<EditorUserProfileWrapper> <EditorUserProfileWrapper>
<ActiveAvatars userRandomColor={props.userRandomColor} mouseMovements={props.mouseMovements} /> <UserAvatar border="border-4" use_with_session={true} width={45} />
</EditorUserProfileWrapper> </EditorUserProfileWrapper>
</EditorUsersSection> </EditorUsersSection>
</EditorTop> </EditorTop>

View file

@ -1,5 +1,5 @@
'use client' 'use client'
import { default as React, useEffect, useRef, useState } from 'react' import { default as React } from 'react'
import Editor from './Editor' import Editor from './Editor'
import { updateActivity } from '@services/courses/activities' import { updateActivity } from '@services/courses/activities'
import { toast } from 'react-hot-toast' import { toast } from 'react-hot-toast'
@ -7,15 +7,7 @@ import Toast from '@components/Objects/StyledElements/Toast/Toast'
import { OrgProvider } from '@components/Contexts/OrgContext' import { OrgProvider } from '@components/Contexts/OrgContext'
import { useLHSession } from '@components/Contexts/LHSessionContext' import { useLHSession } from '@components/Contexts/LHSessionContext'
// Collaboration
import { HocuspocusProvider } from '@hocuspocus/provider'
import * as Y from 'yjs'
import { IndexeddbPersistence } from 'y-indexeddb'
import { getCollaborationServerUrl } from '@services/config/config'
import randomColor from 'randomcolor'
import MouseMovements from './MouseMovements'
import { v4 as uuidv4 } from 'uuid';
import { debounce } from '@/lib/utils';
interface EditorWrapperProps { interface EditorWrapperProps {
content: string content: string
@ -27,61 +19,11 @@ interface EditorWrapperProps {
function EditorWrapper(props: EditorWrapperProps): JSX.Element { function EditorWrapper(props: EditorWrapperProps): JSX.Element {
const session = useLHSession() as any const session = useLHSession() as any
const access_token = session?.data?.tokens?.access_token; const access_token = session?.data?.tokens?.access_token;
// Define provider in the state
const [provider, setProvider] = React.useState<HocuspocusProvider | null>(null);
const [thisPageColor, setThisPageColor] = useState(randomColor({ luminosity: 'light' }) as string)
let uuid = uuidv4();
const [onlinePageInstanceID, setOnlinePageInstanceID] = useState(uuid as string)
/* Collaboration Features */
const collab = getCollaborationServerUrl()
const isCollabEnabledOnThisOrg = props.org.config.config.features.collaboration.enabled && collab
const doc = new Y.Doc()
// mouse movement
const [mouseMovements, setMouseMovements] = useState({} as any);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const debouncedSetMouseMovements = (newMovements: any) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => {
setMouseMovements(newMovements);
}, 10);
};
// Store the Y document in the browser
new IndexeddbPersistence(props.activity.activity_uuid, doc)
document.addEventListener(
'mousemove',
debounce((event: MouseEvent) => {
provider?.setAwarenessField('userMouseMovement', {
user: session.data.user,
mouseX: event.clientX,
mouseY: event.clientY,
color: thisPageColor,
onlineInstanceID: onlinePageInstanceID,
})
}, 300)
)
async function setContent(content: any) { async function setContent(content: any) {
let activity = props.activity let activity = props.activity
activity.content = content activity.content = content
provider?.setAwarenessField("savings_states", {
[session.data.user.user_uuid]: {
status: 'action_save',
timestamp: new Date().toISOString(),
user: session.data.user
}
});
toast.promise(updateActivity(activity, activity.activity_uuid, access_token), { toast.promise(updateActivity(activity, activity.activity_uuid, access_token), {
loading: 'Saving...', loading: 'Saving...',
success: <b>Activity saved!</b>, success: <b>Activity saved!</b>,
@ -90,92 +32,10 @@ function EditorWrapper(props: EditorWrapperProps): JSX.Element {
} }
// Create a ref to store the last save timestamp of each user
const lastSaveTimestampRef = useRef({}) as any;
useEffect(() => {
// Check if provider is not already set
if (!provider) {
const newProvider = new HocuspocusProvider({
url: collab,
name: props.activity.activity_uuid,
document: doc,
// TODO(alpha code): This whole block of code should be improved to something more efficient and less hacky
onConnect: () => {
// Set the online page instance ID
setOnlinePageInstanceID(uuidv4());
// Set the user color
setThisPageColor(randomColor({ luminosity: 'light' }) as string);
},
onAwarenessUpdate: ({ states }) => {
const usersStates = states;
/* Showing user mouse movement */
usersStates.forEach((userState: any) => {
if (userState.userMouseMovement) {
const userMouseMovement = userState.userMouseMovement;
// Update the mouse movements state
debouncedSetMouseMovements((prevMovements: any) => {
return {
...prevMovements,
[userMouseMovement.user.user_uuid]: {
user: userMouseMovement.user,
mouseX: userMouseMovement.mouseX,
mouseY: userMouseMovement.mouseY,
color: userMouseMovement.color,
onlinePageInstanceID: userMouseMovement.onlineInstanceID
},
};
}
);
}
});
/* Notifiying if a user has saved course content */
usersStates.forEach((userState: any) => {
if (userState.savings_states) {
const savingsState = userState.savings_states
// Check if a user has saved the document
Object.keys(savingsState).forEach(user => {
const userObj = savingsState[user].user;
const status = savingsState[user].status;
const timestamp = savingsState[user].timestamp;
// Get the current timestamp
const currentTimestamp = new Date().getTime();
// If the user has saved the document and the timestamp is close to the current timestamp, show the toast
if (status === 'action_save' && Math.abs(currentTimestamp - new Date(timestamp).getTime()) < 10) { // 5000 milliseconds = 5 seconds
// Update the last save timestamp for this user
lastSaveTimestampRef.current[user] = timestamp;
toast.success(`${userObj.first_name} ${userObj.last_name} has saved the document`);
}
});
}
})
},
});
// Set the new provider
setProvider(newProvider);
}
}, []);
{ {
return ( return (
<> <>
<Toast></Toast> <Toast></Toast>
<MouseMovements org={props.org} movements={mouseMovements} onlinePageInstanceID={onlinePageInstanceID} />
<OrgProvider orgslug={props.org.slug}> <OrgProvider orgslug={props.org.slug}>
{!session.isLoading && (<Editor {!session.isLoading && (<Editor
org={props.org} org={props.org}
@ -184,11 +44,6 @@ function EditorWrapper(props: EditorWrapperProps): JSX.Element {
content={props.content} content={props.content}
setContent={setContent} setContent={setContent}
session={session} session={session}
ydoc={doc}
hocuspocusProvider={provider}
isCollabEnabledOnThisOrg={isCollabEnabledOnThisOrg}
userRandomColor={thisPageColor}
mouseMovements={mouseMovements}
></Editor>)} ></Editor>)}
</OrgProvider> </OrgProvider>
</> </>

View file

@ -1,80 +0,0 @@
import { getCollaborationServerUrl } from "@services/config/config";
import { motion } from "framer-motion";
import React, { useEffect } from 'react'
interface User {
user_uuid: string;
first_name: string;
last_name: string;
}
interface Movement {
user: User;
mouseX: number;
mouseY: number;
color: string;
onlinePageInstanceID: string;
}
interface MouseMovementsProps {
movements: Record<string, Movement>;
onlinePageInstanceID: string;
org ?: any;
}
function MouseMovements({ movements, onlinePageInstanceID, org }: MouseMovementsProps): JSX.Element {
/* Collaboration config */
const collab = getCollaborationServerUrl()
const isCollabEnabledOnThisOrg = org?.config.config.features.collaboration.enabled && collab
useEffect(() => {
}
, [movements, org]);
return (
<div>
{isCollabEnabledOnThisOrg && Object.keys(movements).map((key) => (
movements[key].onlinePageInstanceID !== onlinePageInstanceID && (<motion.div
key={key}
className="flex -space-x-2"
style={{
position: "fixed",
zIndex: 10000,
}}
initial={{ x: 0, y: 0 }}
animate={{ x: movements[key].mouseX, y: movements[key].mouseY }}
transition={{
type: "spring",
damping: 30,
mass: 0.8,
stiffness: 350,
}}
>
<CursorSvg color={movements[key].color} />
<div
style={{ backgroundColor: movements[key].color }}
className={`px-3 h-fit py-0.5 rounded-full font-bold text-[11px] shadow-sm text-black`}>{movements[key].user.first_name} {movements[key].user.last_name}</div>
</motion.div>)
))}
</div>
);
}
function CursorSvg({ color }: { color: string }) {
return (
<svg width="32" height="44" viewBox="0 0 24 36" fill="none">
<path
fill={color}
d="M5.65376 12.3673H5.46026L5.31717 12.4976L0.500002 16.8829L0.500002 1.19841L11.7841 12.3673H5.65376Z"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
export default MouseMovements;

View file

@ -12,7 +12,6 @@
}, },
"dependencies": { "dependencies": {
"@emoji-mart/react": "^1.1.1", "@emoji-mart/react": "^1.1.1",
"@hocuspocus/provider": "^2.13.7",
"@icons-pack/react-simple-icons": "^10.1.0", "@icons-pack/react-simple-icons": "^10.1.0",
"@radix-ui/colors": "^0.1.9", "@radix-ui/colors": "^0.1.9",
"@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-aspect-ratio": "^1.1.0",
@ -34,8 +33,6 @@
"@tanstack/react-table": "^8.20.5", "@tanstack/react-table": "^8.20.5",
"@tiptap/core": "^2.9.1", "@tiptap/core": "^2.9.1",
"@tiptap/extension-code-block-lowlight": "^2.9.1", "@tiptap/extension-code-block-lowlight": "^2.9.1",
"@tiptap/extension-collaboration": "^2.9.1",
"@tiptap/extension-collaboration-cursor": "^2.9.1",
"@tiptap/extension-table": "^2.9.1", "@tiptap/extension-table": "^2.9.1",
"@tiptap/extension-table-cell": "^2.9.1", "@tiptap/extension-table-cell": "^2.9.1",
"@tiptap/extension-table-header": "^2.9.1", "@tiptap/extension-table-header": "^2.9.1",
@ -47,6 +44,7 @@
"@tiptap/starter-kit": "^2.9.1", "@tiptap/starter-kit": "^2.9.1",
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
"@types/randomcolor": "^0.5.9", "@types/randomcolor": "^0.5.9",
"prosemirror-state": "^1.4.3",
"avvvatars-react": "^0.4.2", "avvvatars-react": "^0.4.2",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@ -63,7 +61,6 @@
"next": "14.2.15", "next": "14.2.15",
"next-auth": "^4.24.10", "next-auth": "^4.24.10",
"nextjs-toploader": "^1.6.12", "nextjs-toploader": "^1.6.12",
"prosemirror-state": "^1.4.3",
"randomcolor": "^0.6.2", "randomcolor": "^0.6.2",
"re-resizable": "^6.10.0", "re-resizable": "^6.10.0",
"react": "^18.3.1", "react": "^18.3.1",
@ -83,10 +80,6 @@
"unsplash-js": "^7.0.19", "unsplash-js": "^7.0.19",
"usehooks-ts": "^3.1.0", "usehooks-ts": "^3.1.0",
"uuid": "^9.0.1", "uuid": "^9.0.1",
"y-indexeddb": "^9.0.12",
"y-prosemirror": "^1.2.12",
"y-webrtc": "^10.3.0",
"yjs": "^13.6.20",
"yup": "^1.4.0" "yup": "^1.4.0"
}, },
"devDependencies": { "devDependencies": {

250
apps/web/pnpm-lock.yaml generated
View file

@ -11,9 +11,6 @@ importers:
'@emoji-mart/react': '@emoji-mart/react':
specifier: ^1.1.1 specifier: ^1.1.1
version: 1.1.1(emoji-mart@5.6.0)(react@18.3.1) version: 1.1.1(emoji-mart@5.6.0)(react@18.3.1)
'@hocuspocus/provider':
specifier: ^2.13.7
version: 2.13.7(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20)
'@icons-pack/react-simple-icons': '@icons-pack/react-simple-icons':
specifier: ^10.1.0 specifier: ^10.1.0
version: 10.1.0(react@18.3.1) version: 10.1.0(react@18.3.1)
@ -77,12 +74,6 @@ importers:
'@tiptap/extension-code-block-lowlight': '@tiptap/extension-code-block-lowlight':
specifier: ^2.9.1 specifier: ^2.9.1
version: 2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/extension-code-block@2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1)(highlight.js@11.10.0)(lowlight@3.1.0) version: 2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/extension-code-block@2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1)(highlight.js@11.10.0)(lowlight@3.1.0)
'@tiptap/extension-collaboration':
specifier: ^2.9.1
version: 2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1)(y-prosemirror@1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20))
'@tiptap/extension-collaboration-cursor':
specifier: ^2.9.1
version: 2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(y-prosemirror@1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20))
'@tiptap/extension-table': '@tiptap/extension-table':
specifier: ^2.9.1 specifier: ^2.9.1
version: 2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1) version: 2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1)
@ -224,18 +215,6 @@ importers:
uuid: uuid:
specifier: ^9.0.1 specifier: ^9.0.1
version: 9.0.1 version: 9.0.1
y-indexeddb:
specifier: ^9.0.12
version: 9.0.12(yjs@13.6.20)
y-prosemirror:
specifier: ^1.2.12
version: 1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20)
y-webrtc:
specifier: ^10.3.0
version: 10.3.0(yjs@13.6.20)
yjs:
specifier: ^13.6.20
version: 13.6.20
yup: yup:
specifier: ^1.4.0 specifier: ^1.4.0
version: 1.4.0 version: 1.4.0
@ -420,15 +399,6 @@ packages:
'@floating-ui/utils@0.2.8': '@floating-ui/utils@0.2.8':
resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==}
'@hocuspocus/common@2.13.7':
resolution: {integrity: sha512-ROqYfW15XlAGd+qb/FVyp0zUC9Rosv7kdcck9LRMdfW3jT66wK9pDDWL2ily4Qj/zhbLCFtjAUPB4UKln/GYNQ==}
'@hocuspocus/provider@2.13.7':
resolution: {integrity: sha512-BjZIIV8tWf/MD/8IcEMSFA+sW4wtR/M9MmhN+XSssYJOZxnszw44Gdwda23TmhsXvCV+qggS8lGEs+SfZSzEag==}
peerDependencies:
y-protocols: ^1.0.6
yjs: ^13.6.8
'@humanwhocodes/config-array@0.13.0': '@humanwhocodes/config-array@0.13.0':
resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
engines: {node: '>=10.10.0'} engines: {node: '>=10.10.0'}
@ -577,9 +547,6 @@ packages:
'@jridgewell/trace-mapping@0.3.25': '@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
'@lifeomic/attempt@3.1.0':
resolution: {integrity: sha512-QZqem4QuAnAyzfz+Gj5/+SLxqwCAw2qmt7732ZXodr6VDWGeYLG6w1i/vYLa55JQM9wRuBKLmXmiZ2P0LtE5rw==}
'@next/env@14.2.15': '@next/env@14.2.15':
resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==}
@ -1599,19 +1566,6 @@ packages:
peerDependencies: peerDependencies:
'@tiptap/core': ^2.7.0 '@tiptap/core': ^2.7.0
'@tiptap/extension-collaboration-cursor@2.9.1':
resolution: {integrity: sha512-mbNYEdlp22UpKY0SULVWRvOm3U19V80DokC+iDIDZXGXI2nCevB4vMQVkXmiQtiz3qT9I9mIN0vSgy3w75A7WA==}
peerDependencies:
'@tiptap/core': ^2.7.0
y-prosemirror: ^1.2.11
'@tiptap/extension-collaboration@2.9.1':
resolution: {integrity: sha512-AaS66O4X0rx1WLnCC3LW5fLk7ZULr0t7/gj/7dNgbBtyg4NhoYc3PhSBiimLbgD+R8wFrfm1lsHb02deaqQB6w==}
peerDependencies:
'@tiptap/core': ^2.7.0
'@tiptap/pm': ^2.7.0
y-prosemirror: ^1.2.11
'@tiptap/extension-document@2.9.1': '@tiptap/extension-document@2.9.1':
resolution: {integrity: sha512-1a+HCoDPnBttjqExfYLwfABq8MYdiowhy/wp8eCxVb6KGFEENO53KapstISvPzqH7eOi+qRjBB1KtVYb/ZXicg==} resolution: {integrity: sha512-1a+HCoDPnBttjqExfYLwfABq8MYdiowhy/wp8eCxVb6KGFEENO53KapstISvPzqH7eOi+qRjBB1KtVYb/ZXicg==}
peerDependencies: peerDependencies:
@ -2063,9 +2017,6 @@ packages:
balanced-match@1.0.2: balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
binary-extensions@2.3.0: binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -2088,9 +2039,6 @@ packages:
buffer-from@1.1.2: buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
busboy@1.6.0: busboy@1.6.0:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
engines: {node: '>=10.16.0'} engines: {node: '>=10.16.0'}
@ -2336,9 +2284,6 @@ packages:
resolution: {integrity: sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==} resolution: {integrity: sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
err-code@3.0.1:
resolution: {integrity: sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==}
es-abstract@1.23.3: es-abstract@1.23.3:
resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2604,9 +2549,6 @@ packages:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
get-browser-rtc@1.1.0:
resolution: {integrity: sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ==}
get-intrinsic@1.2.4: get-intrinsic@1.2.4:
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2720,9 +2662,6 @@ packages:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
ignore@5.3.2: ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
@ -2876,9 +2815,6 @@ packages:
isexe@2.0.0: isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
isomorphic.js@0.2.5:
resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==}
iterator.prototype@1.1.3: iterator.prototype@1.1.3:
resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==} resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2956,11 +2892,6 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
lib0@0.2.98:
resolution: {integrity: sha512-XteTiNO0qEXqqweWx+b21p/fBnNHUA1NwAtJNJek1oPrewEZs2uiT4gWivHKr9GqCjDPAhchz0UQO8NwU3bBNA==}
engines: {node: '>=16'}
hasBin: true
lilconfig@2.1.0: lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -3572,10 +3503,6 @@ packages:
read-cache@1.0.0: read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
readdirp@3.6.0: readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
@ -3697,9 +3624,6 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'} engines: {node: '>=14'}
simple-peer@9.11.1:
resolution: {integrity: sha512-D1SaWpOW8afq1CZGWB8xTfrT3FekjQmPValrqncJMX7QFl8YwhrPTZvMCANLtgBwwdS+7zURyqxDDEmY558tTw==}
simple-swizzle@0.2.2: simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
@ -3755,9 +3679,6 @@ packages:
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
strip-ansi@6.0.1: strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -4090,51 +4011,10 @@ packages:
wrappy@1.0.2: wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
ws@8.18.0:
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
xtend@4.0.2: xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'} engines: {node: '>=0.4'}
y-indexeddb@9.0.12:
resolution: {integrity: sha512-9oCFRSPPzBK7/w5vOkJBaVCQZKHXB/v6SIT+WYhnJxlEC61juqG0hBrAf+y3gmSMLFLwICNH9nQ53uscuse6Hg==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
peerDependencies:
yjs: ^13.0.0
y-prosemirror@1.2.12:
resolution: {integrity: sha512-UMnUIR5ppVn30n2kzeeBQEaesWGe4fsbnlch1HnNa3/snJMoOn7M7dieuS+o1OQwKs1dqx2eT3gFfGF2aOaQdw==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
peerDependencies:
prosemirror-model: ^1.7.1
prosemirror-state: ^1.2.3
prosemirror-view: ^1.9.10
y-protocols: ^1.0.1
yjs: ^13.5.38
y-protocols@1.0.6:
resolution: {integrity: sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
peerDependencies:
yjs: ^13.0.0
y-webrtc@10.3.0:
resolution: {integrity: sha512-KalJr7dCgUgyVFxoG3CQYbpS0O2qybegD0vI4bYnYHI0MOwoVbucED3RZ5f2o1a5HZb1qEssUKS0H/Upc6p1lA==}
engines: {node: '>=12'}
hasBin: true
peerDependencies:
yjs: ^13.6.8
yallist@3.1.1: yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
@ -4146,10 +4026,6 @@ packages:
engines: {node: '>= 14'} engines: {node: '>= 14'}
hasBin: true hasBin: true
yjs@13.6.20:
resolution: {integrity: sha512-Z2YZI+SYqK7XdWlloI3lhMiKnCdFCVC4PchpdO+mCYwtiTwncjUbnRK9R1JmkNfdmHyDXuWN3ibJAt0wsqTbLQ==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
yocto-queue@0.1.0: yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -4341,22 +4217,6 @@ snapshots:
'@floating-ui/utils@0.2.8': {} '@floating-ui/utils@0.2.8': {}
'@hocuspocus/common@2.13.7':
dependencies:
lib0: 0.2.98
'@hocuspocus/provider@2.13.7(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20)':
dependencies:
'@hocuspocus/common': 2.13.7
'@lifeomic/attempt': 3.1.0
lib0: 0.2.98
ws: 8.18.0
y-protocols: 1.0.6(yjs@13.6.20)
yjs: 13.6.20
transitivePeerDependencies:
- bufferutil
- utf-8-validate
'@humanwhocodes/config-array@0.13.0': '@humanwhocodes/config-array@0.13.0':
dependencies: dependencies:
'@humanwhocodes/object-schema': 2.0.3 '@humanwhocodes/object-schema': 2.0.3
@ -4479,8 +4339,6 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2 '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/sourcemap-codec': 1.5.0
'@lifeomic/attempt@3.1.0': {}
'@next/env@14.2.15': {} '@next/env@14.2.15': {}
'@next/eslint-plugin-next@14.2.16': '@next/eslint-plugin-next@14.2.16':
@ -5584,17 +5442,6 @@ snapshots:
dependencies: dependencies:
'@tiptap/core': 2.9.1(@tiptap/pm@2.9.1) '@tiptap/core': 2.9.1(@tiptap/pm@2.9.1)
'@tiptap/extension-collaboration-cursor@2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(y-prosemirror@1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20))':
dependencies:
'@tiptap/core': 2.9.1(@tiptap/pm@2.9.1)
y-prosemirror: 1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20)
'@tiptap/extension-collaboration@2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))(@tiptap/pm@2.9.1)(y-prosemirror@1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20))':
dependencies:
'@tiptap/core': 2.9.1(@tiptap/pm@2.9.1)
'@tiptap/pm': 2.9.1
y-prosemirror: 1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20)
'@tiptap/extension-document@2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))': '@tiptap/extension-document@2.9.1(@tiptap/core@2.9.1(@tiptap/pm@2.9.1))':
dependencies: dependencies:
'@tiptap/core': 2.9.1(@tiptap/pm@2.9.1) '@tiptap/core': 2.9.1(@tiptap/pm@2.9.1)
@ -6157,8 +6004,6 @@ snapshots:
balanced-match@1.0.2: {} balanced-match@1.0.2: {}
base64-js@1.5.1: {}
binary-extensions@2.3.0: {} binary-extensions@2.3.0: {}
brace-expansion@1.1.11: brace-expansion@1.1.11:
@ -6183,11 +6028,6 @@ snapshots:
buffer-from@1.1.2: {} buffer-from@1.1.2: {}
buffer@6.0.3:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
busboy@1.6.0: busboy@1.6.0:
dependencies: dependencies:
streamsearch: 1.1.0 streamsearch: 1.1.0
@ -6400,8 +6240,6 @@ snapshots:
entities@5.0.0: {} entities@5.0.0: {}
err-code@3.0.1: {}
es-abstract@1.23.3: es-abstract@1.23.3:
dependencies: dependencies:
array-buffer-byte-length: 1.0.1 array-buffer-byte-length: 1.0.1
@ -6508,8 +6346,8 @@ snapshots:
'@typescript-eslint/parser': 8.12.2(eslint@8.57.1)(typescript@5.4.4) '@typescript-eslint/parser': 8.12.2(eslint@8.57.1)(typescript@5.4.4)
eslint: 8.57.1 eslint: 8.57.1
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1)
eslint-plugin-react: 7.37.2(eslint@8.57.1) eslint-plugin-react: 7.37.2(eslint@8.57.1)
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1)
@ -6528,37 +6366,37 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1): eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1):
dependencies: dependencies:
'@nolyfill/is-core-module': 1.0.39 '@nolyfill/is-core-module': 1.0.39
debug: 4.3.7 debug: 4.3.7
enhanced-resolve: 5.17.1 enhanced-resolve: 5.17.1
eslint: 8.57.1 eslint: 8.57.1
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
fast-glob: 3.3.2 fast-glob: 3.3.2
get-tsconfig: 4.8.1 get-tsconfig: 4.8.1
is-bun-module: 1.2.1 is-bun-module: 1.2.1
is-glob: 4.0.3 is-glob: 4.0.3
optionalDependencies: optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
transitivePeerDependencies: transitivePeerDependencies:
- '@typescript-eslint/parser' - '@typescript-eslint/parser'
- eslint-import-resolver-node - eslint-import-resolver-node
- eslint-import-resolver-webpack - eslint-import-resolver-webpack
- supports-color - supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): eslint-module-utils@2.12.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
dependencies: dependencies:
debug: 3.2.7 debug: 3.2.7
optionalDependencies: optionalDependencies:
'@typescript-eslint/parser': 8.12.2(eslint@8.57.1)(typescript@5.4.4) '@typescript-eslint/parser': 8.12.2(eslint@8.57.1)(typescript@5.4.4)
eslint: 8.57.1 eslint: 8.57.1
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1):
dependencies: dependencies:
'@rtsao/scc': 1.1.0 '@rtsao/scc': 1.1.0
array-includes: 3.1.8 array-includes: 3.1.8
@ -6569,7 +6407,7 @@ snapshots:
doctrine: 2.1.0 doctrine: 2.1.0
eslint: 8.57.1 eslint: 8.57.1
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.12.2(eslint@8.57.1)(typescript@5.4.4))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1)
hasown: 2.0.2 hasown: 2.0.2
is-core-module: 2.15.1 is-core-module: 2.15.1
is-glob: 4.0.3 is-glob: 4.0.3
@ -6808,8 +6646,6 @@ snapshots:
gensync@1.0.0-beta.2: {} gensync@1.0.0-beta.2: {}
get-browser-rtc@1.1.0: {}
get-intrinsic@1.2.4: get-intrinsic@1.2.4:
dependencies: dependencies:
es-errors: 1.3.0 es-errors: 1.3.0
@ -6933,8 +6769,6 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
ieee754@1.2.1: {}
ignore@5.3.2: {} ignore@5.3.2: {}
import-fresh@3.3.0: import-fresh@3.3.0:
@ -7080,8 +6914,6 @@ snapshots:
isexe@2.0.0: {} isexe@2.0.0: {}
isomorphic.js@0.2.5: {}
iterator.prototype@1.1.3: iterator.prototype@1.1.3:
dependencies: dependencies:
define-properties: 1.2.1 define-properties: 1.2.1
@ -7160,10 +6992,6 @@ snapshots:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
type-check: 0.4.0 type-check: 0.4.0
lib0@0.2.98:
dependencies:
isomorphic.js: 0.2.5
lilconfig@2.1.0: {} lilconfig@2.1.0: {}
lilconfig@3.1.2: {} lilconfig@3.1.2: {}
@ -7779,12 +7607,6 @@ snapshots:
dependencies: dependencies:
pify: 2.3.0 pify: 2.3.0
readable-stream@3.6.2:
dependencies:
inherits: 2.0.4
string_decoder: 1.3.0
util-deprecate: 1.0.2
readdirp@3.6.0: readdirp@3.6.0:
dependencies: dependencies:
picomatch: 2.3.1 picomatch: 2.3.1
@ -7946,18 +7768,6 @@ snapshots:
signal-exit@4.1.0: {} signal-exit@4.1.0: {}
simple-peer@9.11.1:
dependencies:
buffer: 6.0.3
debug: 4.3.7
err-code: 3.0.1
get-browser-rtc: 1.1.0
queue-microtask: 1.2.3
randombytes: 2.1.0
readable-stream: 3.6.2
transitivePeerDependencies:
- supports-color
simple-swizzle@0.2.2: simple-swizzle@0.2.2:
dependencies: dependencies:
is-arrayish: 0.3.2 is-arrayish: 0.3.2
@ -8036,10 +7846,6 @@ snapshots:
define-properties: 1.2.1 define-properties: 1.2.1
es-object-atoms: 1.0.0 es-object-atoms: 1.0.0
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1
strip-ansi@6.0.1: strip-ansi@6.0.1:
dependencies: dependencies:
ansi-regex: 5.0.1 ansi-regex: 5.0.1
@ -8417,52 +8223,14 @@ snapshots:
wrappy@1.0.2: {} wrappy@1.0.2: {}
ws@8.18.0: {}
xtend@4.0.2: {} xtend@4.0.2: {}
y-indexeddb@9.0.12(yjs@13.6.20):
dependencies:
lib0: 0.2.98
yjs: 13.6.20
y-prosemirror@1.2.12(prosemirror-model@1.23.0)(prosemirror-state@1.4.3)(prosemirror-view@1.35.0)(y-protocols@1.0.6(yjs@13.6.20))(yjs@13.6.20):
dependencies:
lib0: 0.2.98
prosemirror-model: 1.23.0
prosemirror-state: 1.4.3
prosemirror-view: 1.35.0
y-protocols: 1.0.6(yjs@13.6.20)
yjs: 13.6.20
y-protocols@1.0.6(yjs@13.6.20):
dependencies:
lib0: 0.2.98
yjs: 13.6.20
y-webrtc@10.3.0(yjs@13.6.20):
dependencies:
lib0: 0.2.98
simple-peer: 9.11.1
y-protocols: 1.0.6(yjs@13.6.20)
yjs: 13.6.20
optionalDependencies:
ws: 8.18.0
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
yallist@3.1.1: {} yallist@3.1.1: {}
yallist@4.0.0: {} yallist@4.0.0: {}
yaml@2.6.0: {} yaml@2.6.0: {}
yjs@13.6.20:
dependencies:
lib0: 0.2.98
yocto-queue@0.1.0: {} yocto-queue@0.1.0: {}
youtube-player@5.5.2: youtube-player@5.5.2:

View file

@ -5,8 +5,6 @@ export const LEARNHOUSE_BACKEND_URL = `${process.env.NEXT_PUBLIC_LEARNHOUSE_BACK
export const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN export const LEARNHOUSE_DOMAIN = process.env.NEXT_PUBLIC_LEARNHOUSE_DOMAIN
export const LEARNHOUSE_TOP_DOMAIN = export const LEARNHOUSE_TOP_DOMAIN =
process.env.NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN process.env.NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN
export const LEARNHOUSE_COLLABORATION_WS_URL =
process.env.NEXT_PUBLIC_LEARNHOUSE_COLLABORATION_WS_URL
export const getAPIUrl = () => LEARNHOUSE_API_URL export const getAPIUrl = () => LEARNHOUSE_API_URL
export const getBackendUrl = () => LEARNHOUSE_BACKEND_URL export const getBackendUrl = () => LEARNHOUSE_BACKEND_URL
@ -48,8 +46,6 @@ export const getDefaultOrg = () => {
return process.env.NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG return process.env.NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG
} }
export const getCollaborationServerUrl = () => {
return `${LEARNHOUSE_COLLABORATION_WS_URL}`
}

View file

@ -13,10 +13,6 @@ services:
condition: service_healthy condition: service_healthy
redis: redis:
condition: service_healthy condition: service_healthy
collaboration:
build: apps/collaboration/.
ports:
- "1998:1998"
db: db:
image: postgres:16-alpine image: postgres:16-alpine
restart: always restart: always