integrate ydb client and adapt some demos

This commit is contained in:
Kevin Jahns
2018-10-13 14:38:29 +02:00
parent 3b08267daa
commit 4c01a34d09
27 changed files with 314 additions and 91 deletions

View File

@@ -2,7 +2,16 @@
<html>
</head>
<script src="./index.js" type="module"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body contenteditable="true">
<body>
<div class="sidebar">
<h3 id="createNoteButton">+ Create Note</h3>
<div class="notelist"></div>
</div>
<div class="main">
<h1 id="headline"></h1>
<div id="editor" contenteditable="true"></div>
</div>
</body>
</html>
</html>

88
examples/notes/index.js Normal file
View File

@@ -0,0 +1,88 @@
/* eslint-env browser */
import { createYdbClient } from '../../YdbClient/index.js'
import Y from '../../src/Y.dist.js'
import * as ydb from '../../YdbClient/YdbClient.js'
import DomBinding from '../../src/Bindings/DomBinding/DomBinding.js'
const uuidv4 = () => 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
})
createYdbClient('ws://localhost:8899/ws').then(ydbclient => {
const y = ydbclient.getY('notelist')
let ynotelist = y.define('notelist', Y.Array)
const domNoteList = document.querySelector('.notelist')
// utils
const addEventListener = (element, eventname, f) => element.addEventListener(eventname, f)
// create note button
const createNoteButton = event => {
ynotelist.insert(0, [{
guid: uuidv4(),
title: 'Note #' + ynotelist.length
}])
}
addEventListener(document.querySelector('#createNoteButton'), 'click', createNoteButton)
window.createNote = createNoteButton
window.createNotes = n => {
y.transact(() => {
for (let i = 0; i < n; i++) {
createNoteButton()
}
})
}
// clear note list function
window.clearNotes = () => ynotelist.delete(0, ynotelist.length)
// update editor and editor title
let domBinding = null
const updateEditor = () => {
domNoteList.querySelectorAll('a').forEach(a => a.classList.remove('selected'))
const domNote = document.querySelector('.notelist').querySelector(`[href="${location.hash}"]`)
if (domNote !== null) {
domNote.classList.add('selected')
const note = ynotelist.toArray().find(note => note.guid === location.hash.slice(1))
if (note !== undefined) {
const ydoc = ydbclient.getY(note.guid)
const ycontent = ydoc.define('content', Y.XmlFragment)
if (domBinding !== null) {
domBinding.destroy()
}
domBinding = new DomBinding(ycontent, document.querySelector('#editor'))
document.querySelector('#headline').innerText = note.title
document.querySelector('#editor').focus()
}
}
}
// listen to url-hash changes
addEventListener(window, 'hashchange', updateEditor)
updateEditor()
// render note list
const renderNoteList = addedElements => {
const fragment = document.createDocumentFragment()
addedElements.forEach(note => {
const a = document.createElement('a')
a.setAttribute('href', '#' + note.guid)
a.innerText = note.title
fragment.insertBefore(a, null)
})
domNoteList.insertBefore(fragment, domNoteList.firstChild)
}
renderNoteList(ynotelist.toArray())
ydb.subscribeRooms(ydbclient, ynotelist.map(note => note.guid))
ynotelist.observe(event => {
const addedNotes = []
event.addedElements.forEach(itemJson => itemJson._content.forEach(json => addedNotes.push(json)))
// const arr = ynotelist.toArray().filter(note => event.addedElements.has(note))
renderNoteList(addedNotes.reverse())
if (domBinding === null) {
updateEditor()
}
})
})

View File

@@ -1,48 +0,0 @@
import IndexedDBPersistence from '../../src/Persistences/IndexeddbPersistence.js'
import YWebsocketsConnector from '../../src/Connectors/WebsocketsConnector/WebsocketsConnector.js'
import Y from '../../src/Y.js'
import YXmlFragment from '../../src/Types/YXml/YXmlFragment.js'
const yCollection = new YCollection(new YWebsocketsConnector(), new IndexedDBPersistence())
const y = yCollection.getDocument('my-notes')
persistence.addConnector(persistence)
const y = new Y()
await persistence.persistY(y)
connector.connectY('html-editor', y)
persistence.connectY('html-editor', y)
window.connector = connector
window.onload = function () {
window.domBinding = new DomBinding(window.yXmlType, document.body, { scrollingElement: document.scrollingElement })
}
window.y = y
window.yXmlType = y.define('xml', YXmlFragment)
window.undoManager = new UndoManager(window.yXmlType, {
captureTimeout: 500
})
document.onkeydown = function interceptUndoRedo (e) {
if (e.keyCode === 90 && (e.metaKey || e.ctrlKey)) {
if (!e.shiftKey) {
window.undoManager.undo()
} else {
window.undoManager.redo()
}
e.preventDefault()
}
}

57
examples/notes/style.css Normal file
View File

@@ -0,0 +1,57 @@
.sidebar {
height: 100%; /* Full-height: remove this if you want "auto" height */
width: 180px; /* Set the width of the sidebar */
position: fixed; /* Fixed Sidebar (stay in place on scroll) */
z-index: 1; /* Stay on top */
top: 0; /* Stay at the top */
left: 0;
background-color: #111; /* Black */
overflow-x: hidden; /* Disable horizontal scroll */
padding-top: 20px;
color: #50abff;
}
#createNoteButton {
padding-left: .5em;
padding-top: .5em;
padding-bottom: .7em;
margin: 0;
cursor: pointer;
}
.sidebar a {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 13px;
color: #818181;
display: block;
}
.sidebar a.selected {
border-style: outset;
}
/* When you mouse over the navigation links, change their color */
.sidebar a:hover {
color: #f1f1f1;
}
/* Style page content */
.main {
margin-left: 180px; /* Same as the width of the sidebar */
padding: 0px 10px;
}
/* On smaller screens, where height is less than 450px, change the style of the sidebar (less padding and a smaller font size) */
@media screen and (max-height: 450px) {
.sidebar {padding-top: 15px;}
.sidebar a {font-size: 18px;}
}
#editor {
min-height: 400px;
}
[contenteditable]:focus {
outline: 0px solid transparent;
}

View File

@@ -1,4 +1,4 @@
import { createYdbClient } from '../../ydb/index.js'
import { createYdbClient } from '../../YdbClient/index.js'
import Y from '../../src/Y.dist.js'
createYdbClient('ws://localhost:8899/ws').then(ydbclient => {