add ritajs, let it show rhymes for the selected word upon clicking the rhyme FAB
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
// https://elixirforum.com/t/how-to-connect-quill-with-phoenix/46004
|
||||
import Quill from 'quill';
|
||||
import socket from '../user_socket';
|
||||
import RhymeModule from '../lib/rhyme';
|
||||
|
||||
Quill.register('modules/rhymeModule', RhymeModule);
|
||||
|
||||
export let TextEditor = {
|
||||
mounted() {
|
||||
@@ -8,7 +11,10 @@ export let TextEditor = {
|
||||
this.clientId;
|
||||
|
||||
this.quill = new Quill(this.el, {
|
||||
theme: 'snow'
|
||||
theme: 'snow',
|
||||
modules: {
|
||||
rhymeModule: true
|
||||
}
|
||||
});
|
||||
|
||||
let channel = socket.channel(`pad:${padId}`, {});
|
||||
|
90
assets/js/lib/rhyme.js
Normal file
90
assets/js/lib/rhyme.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import { RiTa } from "rita";
|
||||
|
||||
class RhymeModule {
|
||||
constructor(quill, options) {
|
||||
this.rhymeElement = document.getElementById("poex-rhymes");
|
||||
this.rhymeContent = "";
|
||||
this.currentSelection = null;
|
||||
this.fabElement = document.getElementById("rhyme-fab");
|
||||
this.quill = quill;
|
||||
this.quill.on("selection-change", (range) => this.onSelectionChange(range));
|
||||
this.fabElement.addEventListener("click", () => {
|
||||
this.onFabClick();
|
||||
});
|
||||
this.quill.root.addEventListener("contextmenu", (event) => {
|
||||
event.preventDefault();
|
||||
const range = this.quill.getSelection();
|
||||
if (range && range.length > 0) {
|
||||
const word = this.getWordAtCursor(range.index + range.length - 1);
|
||||
if (word) {
|
||||
this.findAndPrintRhymes(word).bind(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onTextChange() {
|
||||
const range = this.quill.getSelection();
|
||||
if (range && range.length === 0) {
|
||||
const word = this.getWordAtCursor(range.index);
|
||||
if (word) {
|
||||
this.findAndPrintRhymes(word);
|
||||
}
|
||||
}
|
||||
this.hideFab();
|
||||
}
|
||||
|
||||
onSelectionChange(range) {
|
||||
if (range && range.length > 0) {
|
||||
const bounds = this.quill.getBounds(range);
|
||||
this.currentSelection = this.quill.getSelection();
|
||||
this.showFab(bounds.left + bounds.width / 2, bounds.top);
|
||||
} else {
|
||||
this.hideFab();
|
||||
}
|
||||
}
|
||||
|
||||
onFabClick() {
|
||||
const range = this.currentSelection;
|
||||
if (range && range.length > 0) {
|
||||
const word = this.getWordAtCursor(range.index + range.length - 1);
|
||||
if (word) {
|
||||
this.findAndPrintRhymes(word);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showFab(x, y) {
|
||||
this.fabElement.style.display = "block";
|
||||
this.fabElement.style.position = "absolute";
|
||||
this.fabElement.style.left = `${x}px`;
|
||||
this.fabElement.style.top = `${y}px`;
|
||||
}
|
||||
|
||||
hideFab() {
|
||||
this.fabElement.style.display = "none";
|
||||
}
|
||||
|
||||
getWordAtCursor(index) {
|
||||
const text = this.quill.getText();
|
||||
const wordBoundary = /\s/;
|
||||
let start = index;
|
||||
let end = index;
|
||||
|
||||
while (start > 0 && !wordBoundary.test(text[start - 1])) {
|
||||
start--;
|
||||
}
|
||||
while (end < text.length && !wordBoundary.test(text[end])) {
|
||||
end++;
|
||||
}
|
||||
return text.substring(start, end);
|
||||
}
|
||||
|
||||
async findAndPrintRhymes(word) {
|
||||
const rhymes = await RiTa.rhymes(word);
|
||||
this.rhymeContent += `Rhymes for '${word}': ${rhymes.join(", ")}\n`;
|
||||
this.rhymeElement.innerText = this.rhymeContent;
|
||||
}
|
||||
}
|
||||
|
||||
export default RhymeModule;
|
Reference in New Issue
Block a user