1
0
Fork 0
mirror of https://github.com/Findus23/RPGnotes.git synced 2024-09-18 14:33:44 +02:00

autocomplete names in the editor

This commit is contained in:
Lukas Winkler 2024-08-07 23:37:26 +02:00
parent 3609095a4e
commit 46388002f5
Signed by: lukas
GPG key ID: 54DE4D798D244853
4 changed files with 130 additions and 30 deletions

View file

@ -4,4 +4,5 @@ from common import views
urlpatterns = [
path("api/draft/save", views.save_draft, name="save_draft"),
path("api/suggestions",views.name_completions,name="name_completions"),
]

View file

@ -7,7 +7,12 @@ from django.views.generic import TemplateView
from ipware import get_client_ip
from sentry_sdk import last_event_id
from characters.models import Character
from common.models import Draft
from factions.models import Faction
from locations.models import Location
from loot.models import Loot
from notes.models import Note
from rpg_notes.secrets import SENTRY_DSN
from utils.assets import get_css, get_file_hash
@ -51,6 +56,42 @@ def save_draft(request: HttpRequest) -> HttpResponse:
})
def name_completions(request: HttpRequest) -> HttpResponse:
response_data = []
for obj in (list(Location.objects.all()) +
list(Note.objects.all()) +
list(Faction.objects.all()) +
list(Loot.objects.all())):
response_data.append({
"name": obj.name
})
if obj.aliases:
for alias in obj.aliases:
response_data.append({
"name": alias,
"details":obj.name
})
for char in Character.objects.all():
response_data.append({
"name": char.name,
"details": char.subtitle
})
if char.aliases:
for alias in char.aliases:
response_data.append({
"name": alias,
"details":char.name
})
response = JsonResponse({
"suggestions": response_data
})
response['Cache-Control'] = f'max-age={24 * 60 * 60}'
return response
@condition(etag_func=calc_etag)
def debug_css(request: HttpRequest) -> HttpResponse:
css, source_map = get_css(debug=True)

View file

@ -1,6 +1,12 @@
import {EditorView, minimalSetup} from "codemirror"
import {markdownLanguage} from "@codemirror/lang-markdown"
import {markdown, markdownLanguage} from "@codemirror/lang-markdown"
import {foldGutter} from "@codemirror/language";
import {
autocompletion,
Completion,
CompletionContext,
CompletionResult
} from "@codemirror/autocomplete"
interface DraftSaveResponse {
message: string
@ -25,6 +31,53 @@ ids.forEach(function (id) {
// color: "red",
// colorLight: "lightred"
// })
interface Element {
name: string,
details?: string
}
interface HTTPResponse {
suggestions: Element[]
}
let names: Element[] = []
fetch("/api/suggestions", {})
.then(response => response.json())
.then((data: HTTPResponse) => {
names = data.suggestions
})
function myCompletions(context: CompletionContext): CompletionResult | null {
if (names.length == 0) {
return null
}
let word
if (!context.explicit) {
word = context.matchBefore(/@\w*/)
} else {
word = context.matchBefore(/\w*/)
}
if (!word) {
return null
}
if (word.from == word.to)
return null
const options = names.map((s: Element): Completion => ({
label: "@" + s.name,
apply: s.name,
displayLabel: s.name,
detail: s.details
}))
return {
from: word.from,
options: options
}
}
const labelEl = element.labels[0]
const div = document.createElement("div")
element.style.display = "none"
@ -33,7 +86,11 @@ ids.forEach(function (id) {
extensions: [
minimalSetup,
foldGutter(),
markdownLanguage,
markdown({base: markdownLanguage}),
autocompletion({
activateOnTyping: true,
override: [myCompletions],
}),
EditorView.lineWrapping,
EditorView.contentAttributes.of({spellcheck: "true"}),
// yCollab(ytext, provider.awareness, {undoManager})
@ -44,31 +101,31 @@ ids.forEach(function (id) {
element.form!.addEventListener("submit", () => {
element.value = view.state.doc.toString()
})
// const easyMDE = new EasyMDE({
// element: element,
// forceSync: true, // for "required" to work
// spellChecker: false,
// nativeSpellcheck: true,
// autoDownloadFontAwesome: false,
// autosave: {
// delay: 1000,
// submit_delay: 5000,
// timeFormat: {
// locale: 'de-AT',
// format: {
// year: 'numeric',
// month: 'long',
// day: '2-digit',
// hour: '2-digit',
// minute: '2-digit',
// second: '2-digit',
// },
// },
// },
// inputStyle: "contenteditable",
// status: ["lines", "words", "cursor", "saveStatus"],
// });
// window.editor = easyMDE
// const easyMDE = new EasyMDE({
// element: element,
// forceSync: true, // for "required" to work
// spellChecker: false,
// nativeSpellcheck: true,
// autoDownloadFontAwesome: false,
// autosave: {
// delay: 1000,
// submit_delay: 5000,
// timeFormat: {
// locale: 'de-AT',
// format: {
// year: 'numeric',
// month: 'long',
// day: '2-digit',
// hour: '2-digit',
// minute: '2-digit',
// second: '2-digit',
// },
// },
// },
// inputStyle: "contenteditable",
// status: ["lines", "words", "cursor", "saveStatus"],
// });
// window.editor = easyMDE
const originalLabel = labelEl.innerText
setInterval(function () {
const content = view.state.doc.toString();
@ -88,4 +145,5 @@ ids.forEach(function (id) {
})
}, 1000 * 30)
});
})
;

View file

@ -3,9 +3,9 @@ import 'vite/modulepreload-polyfill'
// import "./scss/main.scss"
import "./js/sentry"
// @ts-ignore
import {default as Dropdown} from 'bootstrap/js/src/dropdown'
import Dropdown from 'bootstrap/js/src/dropdown'
// @ts-ignore
import {default as Collapse} from 'bootstrap/js/src/collapse'
import Collapse from 'bootstrap/js/src/collapse'
import "./js/autocomplete"
import "./js/popover"