Compare commits

..

2 Commits

Author SHA1 Message Date
gamer147
6fd76f6787 [FA-misc] Fixes file caching
All checks were successful
CI / build-backend (pull_request) Successful in 1m4s
CI / build-frontend (pull_request) Successful in 41s
2025-12-10 16:09:41 -05:00
gamer147
4fb34bdef7 [FA-misc] Should fix paragraph blocking
All checks were successful
CI / build-backend (pull_request) Successful in 1m21s
CI / build-frontend (pull_request) Successful in 39s
2025-12-10 13:40:33 -05:00
3 changed files with 43 additions and 6 deletions

View File

@@ -35,8 +35,16 @@ namespace FictionArchive.Service.FileService.Controllers
BucketName = _s3Configuration.Bucket,
Key = decodedPath
});
return new FileStreamResult(s3Response.ResponseStream, s3Response.Headers.ContentType);
Response.Headers.CacheControl = "public, max-age=604800"; // 7 days
Response.Headers.LastModified = s3Response.LastModified?.ToString("R");
if (!string.IsNullOrEmpty(s3Response.ETag))
{
Response.Headers.ETag = s3Response.ETag;
}
return File(s3Response.ResponseStream, s3Response.Headers.ContentType);
}
catch (AmazonS3Exception e)
{

View File

@@ -155,10 +155,9 @@
<Card>
<CardContent class="px-6 py-8 md:px-12">
<article
class="prose prose-lg dark:prose-invert mx-auto max-w-none whitespace-pre-line
prose-p:text-foreground prose-p:mb-4 prose-p:leading-relaxed
class="prose prose-lg dark:prose-invert mx-auto max-w-none
prose-headings:text-foreground
first:prose-p:mt-0 last:prose-p:mb-0"
[&>p]:text-foreground [&>p]:mb-6 [&>p]:leading-relaxed"
>
{@html sanitizedBody}
</article>

View File

@@ -1,12 +1,42 @@
import DOMPurify from 'isomorphic-dompurify';
/**
* Splits plain text into paragraphs based on newlines.
* Double newlines create new paragraphs, single newlines become <br>.
* If the content already contains HTML block elements, returns as-is.
*/
function wrapInParagraphs(text: string): string {
// Check if content already has block-level HTML elements
const hasBlockElements = /<(p|div|h[1-6]|ul|ol|blockquote|pre|table|hr)[>\s]/i.test(text);
if (hasBlockElements) {
return text;
}
// Split on double newlines (paragraph breaks)
const paragraphs = text.split(/\n\s*\n/);
return paragraphs
.map((para) => {
const trimmed = para.trim();
if (!trimmed) return '';
// Convert single newlines to <br> within paragraphs
const withBreaks = trimmed.replace(/\n/g, '<br>');
return `<p>${withBreaks}</p>`;
})
.filter(Boolean)
.join('\n');
}
/**
* Sanitizes chapter HTML content with extended allowed tags.
* More permissive than the description sanitizer to support
* formatted novel content including headings, lists, and images.
* Also wraps plain text in paragraph tags for better browser translate support.
*/
export function sanitizeChapterHtml(html: string): string {
return DOMPurify.sanitize(html, {
// First wrap in paragraphs if needed, then sanitize
const wrapped = wrapInParagraphs(html);
return DOMPurify.sanitize(wrapped, {
ALLOWED_TAGS: [
// Basic formatting
'b',