add button that updates the calendar with another source. tooltip format change, multiple color
commit frequently pls
This commit is contained in:
1 parent
6800a75825
commit
3330ff1205
4 files changed
+68
-10
No files matched your search
+6
-2
@@ -9,8 +9,12 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input type="text" id="ics_file">
|
||||
<input type="button" value="hi" id="ics_run">
|
||||
<div class="flex_input">
|
||||
<input type="text" id="ics_file">
|
||||
<input type="button" value="new calendar" id="ics_run">
|
||||
<input type="button" value="add a calendar" id="ics_add">
|
||||
</div>
|
||||
|
||||
<div id="calendar"></div>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
let sourceCount = 0;
|
||||
|
||||
/** how ass would this shit be? */
|
||||
export function getNextColor() {
|
||||
// Spread hues evenly around the color wheel
|
||||
const hue = (sourceCount * 137) % 360; // 137 is the golden angle
|
||||
sourceCount++;
|
||||
return `hsl(${hue}, 70%, 50%)`;
|
||||
}
|
||||
+28
-8
@@ -10,24 +10,30 @@ import bootstrap5Plugin from "@fullcalendar/bootstrap5";
|
||||
|
||||
import tippy, { followCursor } from "tippy.js";
|
||||
import "tippy.js/dist/tippy.css";
|
||||
import { getNextColor } from "./color_generator";
|
||||
import { formatTooltip } from "./tooltip_parser";
|
||||
|
||||
const text_field = document.getElementById("ics_file");
|
||||
const confirm_button = document.getElementById("ics_run");
|
||||
const cal = document.getElementById("calendar");
|
||||
const add_button = document.getElementById("ics_add");
|
||||
const cal_ele = document.getElementById("calendar");
|
||||
let currentTippy = null;
|
||||
|
||||
let calendar = null;
|
||||
const new_tippy = (info) => {
|
||||
if (info.el._tippy === currentTippy) {
|
||||
currentTippy.show();
|
||||
} // what does this even MEAN
|
||||
else if (info.event.extendedProps.description) {
|
||||
} // what does this even MEAN
|
||||
else { // if (info.event.extendedProps.description)
|
||||
// Destroy previous tippy if exists
|
||||
if (currentTippy) {
|
||||
currentTippy.destroy();
|
||||
currentTippy = null;
|
||||
}
|
||||
currentTippy = tippy(info.el, {
|
||||
content: info.event.extendedProps.description,
|
||||
content: formatTooltip(
|
||||
info.event.title,
|
||||
info.event.extendedProps.description
|
||||
),
|
||||
allowHTML: true,
|
||||
theme: "light",
|
||||
interactive: true,
|
||||
@@ -57,7 +63,8 @@ const tippy_die = (info) => {
|
||||
confirm_button.addEventListener("click", (_e) => {
|
||||
console.log("nawgh:", text_field.value);
|
||||
if (text_field.value) {
|
||||
const calendar = new Calendar(cal, {
|
||||
if (calendar) calendar.destroy();
|
||||
calendar = new Calendar(cal_ele, {
|
||||
plugins: [
|
||||
bootstrap5Plugin,
|
||||
listPlugin,
|
||||
@@ -69,23 +76,26 @@ confirm_button.addEventListener("click", (_e) => {
|
||||
// multiMonthMaxColumns: 1,
|
||||
navLinks: true,
|
||||
dayMaxEvents: true,
|
||||
eventMaxStack: 3,
|
||||
dayMaxEventRows: true,
|
||||
nowIndicator: true,
|
||||
weekNumbers: true,
|
||||
headerToolbar: {
|
||||
left: "prev,next",
|
||||
center: "title",
|
||||
right: "today dayGridMonth,timeGridWeek,timeGridDay,listWeek", // Add the views you want
|
||||
right: "today dayGridMonth,timeGridWeek,timeGridDay,listMonth", // Add the views you want
|
||||
},
|
||||
views: {
|
||||
dayGridMonth: { buttonText: "Month" },
|
||||
timeGridWeek: { buttonText: "Week" },
|
||||
timeGridDay: { buttonText: "Day" },
|
||||
listWeek: { buttonText: "List" },
|
||||
listMonth: { buttonText: "List" },
|
||||
},
|
||||
|
||||
events: {
|
||||
url: text_field.value,
|
||||
format: "ics",
|
||||
color: getNextColor(),
|
||||
},
|
||||
// eventClick: new_tippy,
|
||||
eventMouseEnter: new_tippy,
|
||||
@@ -99,3 +109,13 @@ confirm_button.addEventListener("click", (_e) => {
|
||||
// text_field.value = "http://127.0.0.1:8080/filtered-ics";
|
||||
// confirm_button.click();
|
||||
// wow
|
||||
|
||||
add_button.addEventListener("click", () => {
|
||||
if (calendar && text_field.value) {
|
||||
calendar.addEventSource({
|
||||
url: text_field.value,
|
||||
format: "ics",
|
||||
color: getNextColor(),
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
// Escapes HTML special characters to prevent XSS
|
||||
export function escapeHtml(text) {
|
||||
const div = document.createElement("div");
|
||||
div.innerText = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// Converts URLs in text to clickable links, after escaping
|
||||
export function linkify(text) {
|
||||
let safe = escapeHtml(text);
|
||||
return safe.replace(
|
||||
/(https?:\/\/[^\s<]+)/g,
|
||||
(url) =>
|
||||
`<a href="${url}" target="_blank" rel="noopener noreferrer">${url}</a>`
|
||||
);
|
||||
}
|
||||
|
||||
// Formats tooltip content: escapes, linkifies, and replaces newlines with <br>
|
||||
export function formatTooltip(title, description) {
|
||||
const safeTitle = escapeHtml(title);
|
||||
const safeDesc = description
|
||||
? linkify(description).replace(/\n/g, "<br>")
|
||||
: "";
|
||||
return `<strong>${safeTitle}</strong><br><br>${safeDesc}`;
|
||||
}
|
||||
Reference in new issue
Block a user