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>}
|
* @returns {Promise<string>}
|
||||||
*/
|
*/
|
||||||
async function uploadRemainingBlobs(markdown) {
|
async function uploadRemainingBlobs(markdown) {
|
||||||
const blobMatches = [...markdown.matchAll(/!\[([^\]]*)\]\((blob:[^)]+)\)/g)];
|
const blobMatches = [...markdown.matchAll(/!\[([^\]]*)\]\((blob:[^\s)]+)/g)];
|
||||||
if (blobMatches.length === 0) return markdown;
|
if (blobMatches.length === 0) return markdown;
|
||||||
console.warn(`[Blog Editor] Found ${blobMatches.length} remaining blob URLs - uploading them`);
|
console.warn(`[Blog Editor] Found ${blobMatches.length} remaining blob URLs - uploading them`);
|
||||||
const uploads = blobMatches.map(async m => {
|
const uploads = blobMatches.map(async m => {
|
||||||
@@ -820,7 +820,8 @@
|
|||||||
let result = markdown;
|
let result = markdown;
|
||||||
for (const { blobUrl, relPath } of results) {
|
for (const { blobUrl, relPath } of results) {
|
||||||
if (relPath) {
|
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;
|
return result;
|
||||||
@@ -1574,7 +1575,7 @@
|
|||||||
|
|
||||||
const rawDoc = buildDocument();
|
const rawDoc = buildDocument();
|
||||||
console.log('[Blog Editor] savePost called, cleaning image paths...');
|
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)))];
|
const unknown = [...new Set(blobs.filter(b => !blobToRelative.has(b)))];
|
||||||
|
|
||||||
if (unknown.length > 0) {
|
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}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
@@ -244,50 +244,67 @@ export class BlogComments {
|
|||||||
label.className = "blog-comments-identity-label";
|
label.className = "blog-comments-identity-label";
|
||||||
label.textContent = "Commenting as ";
|
label.textContent = "Commenting as ";
|
||||||
|
|
||||||
const nameSpan = document.createElement("strong");
|
const nameInput = document.createElement("input");
|
||||||
nameSpan.className = "blog-comments-identity-name";
|
nameInput.type = "text";
|
||||||
nameSpan.textContent = this.#displayName;
|
nameInput.className = "blog-comments-identity-name-input";
|
||||||
|
nameInput.value = this.#displayName;
|
||||||
const editBtn = document.createElement("button");
|
nameInput.maxLength = 64;
|
||||||
editBtn.type = "button";
|
nameInput.setAttribute("aria-label", "Display name");
|
||||||
editBtn.className = "blog-comments-identity-edit-btn";
|
|
||||||
editBtn.setAttribute("aria-label", "Edit display name");
|
|
||||||
|
|
||||||
const remaining = this.#nickCooldownRemaining();
|
const remaining = this.#nickCooldownRemaining();
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
editBtn.disabled = true;
|
nameInput.disabled = true;
|
||||||
editBtn.title = `Wait ${remaining}s before changing name again`;
|
nameInput.title = `Wait ${remaining}s before changing name again`;
|
||||||
editBtn.textContent = `✏️ ${remaining}s`;
|
this.#startCooldownTick(nameInput);
|
||||||
this.#startCooldownTick(editBtn);
|
|
||||||
} else {
|
} else {
|
||||||
editBtn.title = "Edit display name";
|
nameInput.title = "Edit your display name";
|
||||||
editBtn.textContent = "✏️";
|
|
||||||
editBtn.addEventListener("click", () => this.#startEditName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
#startCooldownTick(editBtn) {
|
#startCooldownTick(nameInput) {
|
||||||
if (this.#nickCooldownTimer !== null) clearInterval(this.#nickCooldownTimer);
|
if (this.#nickCooldownTimer !== null) clearInterval(this.#nickCooldownTimer);
|
||||||
this.#nickCooldownTimer = setInterval(() => {
|
this.#nickCooldownTimer = setInterval(() => {
|
||||||
const remaining = this.#nickCooldownRemaining();
|
const remaining = this.#nickCooldownRemaining();
|
||||||
if (remaining <= 0) {
|
if (remaining <= 0) {
|
||||||
clearInterval(this.#nickCooldownTimer);
|
clearInterval(this.#nickCooldownTimer);
|
||||||
this.#nickCooldownTimer = null;
|
this.#nickCooldownTimer = null;
|
||||||
editBtn.disabled = false;
|
nameInput.disabled = false;
|
||||||
editBtn.title = "Edit display name";
|
nameInput.title = "Edit your display name";
|
||||||
editBtn.textContent = "✏️";
|
|
||||||
editBtn.addEventListener("click", () => this.#startEditName());
|
|
||||||
} else {
|
} else {
|
||||||
editBtn.textContent = `✏️ ${remaining}s`;
|
nameInput.title = `Wait ${remaining}s before changing name again`;
|
||||||
editBtn.title = `Wait ${remaining}s before changing name again`;
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ svg.world-image {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
padding: 3px 8px;
|
padding: 0 4px;
|
||||||
background: rgba(137, 180, 250, 0.15);
|
background: rgba(137, 180, 250, 0.15);
|
||||||
color: rgba(137, 180, 250, 0.9);
|
color: rgba(137, 180, 250, 0.9);
|
||||||
border: 1px solid rgba(137, 180, 250, 0.3);
|
border: 1px solid rgba(137, 180, 250, 0.3);
|
||||||
@@ -778,7 +778,7 @@ body.blog-page {
|
|||||||
.blog-post-peek-wrapper {
|
.blog-post-peek-wrapper {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 160px;
|
min-width: 60px;`n max-width: 250px;
|
||||||
height: 0;
|
height: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
@@ -793,7 +793,7 @@ body.blog-page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.blog-post-peek {
|
.blog-post-peek {
|
||||||
width: 160px;
|
min-width: 60px;`n max-width: 250px;
|
||||||
background: var(--node-bg);
|
background: var(--node-bg);
|
||||||
border: 1px solid var(--node-border);
|
border: 1px solid var(--node-border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -981,7 +981,7 @@ body.blog-page {
|
|||||||
border: 1px solid rgba(137, 180, 250, 0.35);
|
border: 1px solid rgba(137, 180, 250, 0.35);
|
||||||
background: rgba(137, 180, 250, 0.12);
|
background: rgba(137, 180, 250, 0.12);
|
||||||
color: var(--ctp-sky);
|
color: var(--ctp-sky);
|
||||||
padding: 3px 8px;
|
padding: 0 4px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
font-size: 0.78rem;
|
font-size: 0.78rem;
|
||||||
}
|
}
|
||||||
@@ -1576,9 +1576,9 @@ body.blog-page {
|
|||||||
background: rgba(24, 24, 37, 0.85);
|
background: rgba(24, 24, 37, 0.85);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
color: var(--ctp-text);
|
color: var(--ctp-text);
|
||||||
padding: 3px 8px;
|
padding: 0 4px;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
width: 160px;
|
min-width: 60px;`n max-width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-comments-identity-input:focus {
|
.blog-comments-identity-input:focus {
|
||||||
@@ -1586,6 +1586,30 @@ body.blog-page {
|
|||||||
border-color: var(--ctp-blue);
|
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 {
|
.blog-comments-identity-save-btn {
|
||||||
background: rgba(137, 180, 250, 0.2);
|
background: rgba(137, 180, 250, 0.2);
|
||||||
border: 1px solid rgba(137, 180, 250, 0.3);
|
border: 1px solid rgba(137, 180, 250, 0.3);
|
||||||
@@ -3067,7 +3091,7 @@ body.blog-page {
|
|||||||
color: rgba(243, 139, 168, 0.9);
|
color: rgba(243, 139, 168, 0.9);
|
||||||
border: 1px solid rgba(243, 139, 168, 0.3);
|
border: 1px solid rgba(243, 139, 168, 0.3);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 3px 8px;
|
padding: 0 4px;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.15s;
|
transition: all 0.15s;
|
||||||
@@ -3124,7 +3148,7 @@ body.blog-page {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
padding: 3px 8px;
|
padding: 0 4px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user