mirror of
https://github.com/litruv/lit.ruv.wtf.git
synced 2026-07-24 02:36:02 +10:00
fix: update regex for blob URL matching and enhance display name input in comments
This commit is contained in:
Binary file not shown.
@@ -780,7 +780,7 @@
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function uploadRemainingBlobs(markdown) {
|
||||
const blobMatches = [...markdown.matchAll(/!\[([^\]]*)\]\((blob:[^)]+)\)/g)];
|
||||
const blobMatches = [...markdown.matchAll(/!\[([^\]]*)\]\((blob:[^\s)]+)/g)];
|
||||
if (blobMatches.length === 0) return markdown;
|
||||
console.warn(`[Blog Editor] Found ${blobMatches.length} remaining blob URLs - uploading them`);
|
||||
const uploads = blobMatches.map(async m => {
|
||||
@@ -820,7 +820,8 @@
|
||||
let result = markdown;
|
||||
for (const { blobUrl, relPath } of results) {
|
||||
if (relPath) {
|
||||
result = result.replace(new RegExp(`!\\[([^\\]]*)\\]\\(${blobUrl.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\)`, 'g'), ``);
|
||||
result = result.replace(new RegExp(`!\\[([^\\]]*)\\]\\(${blobUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(\\s+["'][\\s\\S]*?["'])?\\)`, 'g'), ``);
|
||||
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -1574,7 +1575,7 @@
|
||||
|
||||
const rawDoc = buildDocument();
|
||||
console.log('[Blog Editor] savePost called, cleaning image paths...');
|
||||
const blobs = [...rawDoc.matchAll(/!\[[^\]]*\]\((blob:[^)]+)\)/g)].map(m => m[1]);
|
||||
const blobs = [...rawDoc.matchAll(/!\[[^\]]*\]\((blob:[^\s)]+)/g)].map(m => m[1]);
|
||||
const unknown = [...new Set(blobs.filter(b => !blobToRelative.has(b)))];
|
||||
|
||||
if (unknown.length > 0) {
|
||||
|
||||
BIN
website/data/blog/media/paste-1778545573604-pe0k3.png
Normal file
BIN
website/data/blog/media/paste-1778545573604-pe0k3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 MiB |
@@ -230,7 +230,7 @@ export class BlogComments {
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the "Commenting as [name] ✏️" identity bar.
|
||||
* Renders the "Commenting as [name]" identity bar with editable text box.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
@@ -244,50 +244,67 @@ export class BlogComments {
|
||||
label.className = "blog-comments-identity-label";
|
||||
label.textContent = "Commenting as ";
|
||||
|
||||
const nameSpan = document.createElement("strong");
|
||||
nameSpan.className = "blog-comments-identity-name";
|
||||
nameSpan.textContent = this.#displayName;
|
||||
|
||||
const editBtn = document.createElement("button");
|
||||
editBtn.type = "button";
|
||||
editBtn.className = "blog-comments-identity-edit-btn";
|
||||
editBtn.setAttribute("aria-label", "Edit display name");
|
||||
const nameInput = document.createElement("input");
|
||||
nameInput.type = "text";
|
||||
nameInput.className = "blog-comments-identity-name-input";
|
||||
nameInput.value = this.#displayName;
|
||||
nameInput.maxLength = 64;
|
||||
nameInput.setAttribute("aria-label", "Display name");
|
||||
|
||||
const remaining = this.#nickCooldownRemaining();
|
||||
if (remaining > 0) {
|
||||
editBtn.disabled = true;
|
||||
editBtn.title = `Wait ${remaining}s before changing name again`;
|
||||
editBtn.textContent = `✏️ ${remaining}s`;
|
||||
this.#startCooldownTick(editBtn);
|
||||
nameInput.disabled = true;
|
||||
nameInput.title = `Wait ${remaining}s before changing name again`;
|
||||
this.#startCooldownTick(nameInput);
|
||||
} else {
|
||||
editBtn.title = "Edit display name";
|
||||
editBtn.textContent = "✏️";
|
||||
editBtn.addEventListener("click", () => this.#startEditName());
|
||||
nameInput.title = "Edit your display name";
|
||||
}
|
||||
|
||||
this.#identityEl.append(label, nameSpan, editBtn);
|
||||
const updateWidth = () => {
|
||||
const tempSpan = document.createElement("span");
|
||||
tempSpan.style.visibility = "hidden";
|
||||
tempSpan.style.position = "absolute";
|
||||
tempSpan.style.fontSize = "0.85rem";
|
||||
tempSpan.style.fontFamily = getComputedStyle(nameInput).fontFamily;
|
||||
tempSpan.textContent = nameInput.value || nameInput.placeholder || "Guest";
|
||||
document.body.appendChild(tempSpan);
|
||||
const width = Math.min(250, Math.max(60, tempSpan.offsetWidth + 20));
|
||||
document.body.removeChild(tempSpan);
|
||||
nameInput.style.width = `${width}px`;
|
||||
};
|
||||
|
||||
nameInput.addEventListener("input", updateWidth);
|
||||
nameInput.addEventListener("blur", () => {
|
||||
const newName = nameInput.value.trim();
|
||||
if (newName && newName !== this.#displayName) {
|
||||
this.#saveDisplayName(newName);
|
||||
} else {
|
||||
nameInput.value = this.#displayName;
|
||||
}
|
||||
updateWidth();
|
||||
});
|
||||
|
||||
this.#identityEl.append(label, nameInput);
|
||||
updateWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ticks the countdown text on the edit button without rebuilding the DOM.
|
||||
* Ticks the countdown on the name input without rebuilding the DOM.
|
||||
*
|
||||
* @param {HTMLButtonElement} editBtn
|
||||
* @param {HTMLInputElement} nameInput
|
||||
* @returns {void}
|
||||
*/
|
||||
#startCooldownTick(editBtn) {
|
||||
#startCooldownTick(nameInput) {
|
||||
if (this.#nickCooldownTimer !== null) clearInterval(this.#nickCooldownTimer);
|
||||
this.#nickCooldownTimer = setInterval(() => {
|
||||
const remaining = this.#nickCooldownRemaining();
|
||||
if (remaining <= 0) {
|
||||
clearInterval(this.#nickCooldownTimer);
|
||||
this.#nickCooldownTimer = null;
|
||||
editBtn.disabled = false;
|
||||
editBtn.title = "Edit display name";
|
||||
editBtn.textContent = "✏️";
|
||||
editBtn.addEventListener("click", () => this.#startEditName());
|
||||
nameInput.disabled = false;
|
||||
nameInput.title = "Edit your display name";
|
||||
} else {
|
||||
editBtn.textContent = `✏️ ${remaining}s`;
|
||||
editBtn.title = `Wait ${remaining}s before changing name again`;
|
||||
nameInput.title = `Wait ${remaining}s before changing name again`;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ svg.world-image {
|
||||
width: 100%;
|
||||
font-family: inherit;
|
||||
font-size: 10px;
|
||||
padding: 3px 8px;
|
||||
padding: 0 4px;
|
||||
background: rgba(137, 180, 250, 0.15);
|
||||
color: rgba(137, 180, 250, 0.9);
|
||||
border: 1px solid rgba(137, 180, 250, 0.3);
|
||||
@@ -778,7 +778,7 @@ body.blog-page {
|
||||
.blog-post-peek-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 160px;
|
||||
min-width: 60px;`n max-width: 250px;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
overflow: visible;
|
||||
@@ -793,7 +793,7 @@ body.blog-page {
|
||||
}
|
||||
|
||||
.blog-post-peek {
|
||||
width: 160px;
|
||||
min-width: 60px;`n max-width: 250px;
|
||||
background: var(--node-bg);
|
||||
border: 1px solid var(--node-border);
|
||||
border-radius: 8px;
|
||||
@@ -981,7 +981,7 @@ body.blog-page {
|
||||
border: 1px solid rgba(137, 180, 250, 0.35);
|
||||
background: rgba(137, 180, 250, 0.12);
|
||||
color: var(--ctp-sky);
|
||||
padding: 3px 8px;
|
||||
padding: 0 4px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
@@ -1576,9 +1576,9 @@ body.blog-page {
|
||||
background: rgba(24, 24, 37, 0.85);
|
||||
border-radius: 6px;
|
||||
color: var(--ctp-text);
|
||||
padding: 3px 8px;
|
||||
padding: 0 4px;
|
||||
font-size: 0.85rem;
|
||||
width: 160px;
|
||||
min-width: 60px;`n max-width: 250px;
|
||||
}
|
||||
|
||||
.blog-comments-identity-input:focus {
|
||||
@@ -1586,6 +1586,30 @@ body.blog-page {
|
||||
border-color: var(--ctp-blue);
|
||||
}
|
||||
|
||||
.blog-comments-identity-name-input {
|
||||
border: 1px solid rgba(205, 214, 244, 0.25);
|
||||
background: rgba(24, 24, 37, 0.85);
|
||||
border-radius: 6px;
|
||||
color: var(--ctp-text);
|
||||
padding: 3px 8px;
|
||||
font-size: 0.85rem;
|
||||
min-width: 60px;
|
||||
max-width: 250px;
|
||||
vertical-align: baseline;
|
||||
transition: border-color 0.15s, background 0.15s, width 0.15s;
|
||||
}
|
||||
|
||||
.blog-comments-identity-name-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--ctp-blue);
|
||||
background: rgba(69, 71, 90, 0.6);
|
||||
}
|
||||
|
||||
.blog-comments-identity-name-input:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.blog-comments-identity-save-btn {
|
||||
background: rgba(137, 180, 250, 0.2);
|
||||
border: 1px solid rgba(137, 180, 250, 0.3);
|
||||
@@ -3067,7 +3091,7 @@ body.blog-page {
|
||||
color: rgba(243, 139, 168, 0.9);
|
||||
border: 1px solid rgba(243, 139, 168, 0.3);
|
||||
border-radius: 4px;
|
||||
padding: 3px 8px;
|
||||
padding: 0 4px;
|
||||
font-size: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
@@ -3124,7 +3148,7 @@ body.blog-page {
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
padding: 3px 8px;
|
||||
padding: 0 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user