- Implement `remove-inline-scripts.js` to externalize Next.js inline scripts, enhancing CSP compliance. - Add models for `Book`, `Character`, `Story`, `Editor`, `System`, and `BookSerie` with relevant properties and utilities. - Include macOS entitlements plist for app development with advanced permissions. - Add utility functions to handle script hashing, cookie management, and content formatting.
197 lines
5.9 KiB
TypeScript
197 lines
5.9 KiB
TypeScript
import {SelectBoxProps} from "@/shared/interface";
|
|
|
|
export interface ActChapter {
|
|
chapterInfoId: string;
|
|
chapterId: string;
|
|
title: string;
|
|
chapterOrder: number;
|
|
actId: number;
|
|
incidentId?: string;
|
|
plotPointId?: string;
|
|
summary: string;
|
|
goal: string;
|
|
}
|
|
|
|
export interface ChapterListProps {
|
|
chapterId: string;
|
|
title: string;
|
|
summary?: string;
|
|
chapterOrder?: number;
|
|
goal?: string;
|
|
}
|
|
|
|
export interface ChapterProps {
|
|
chapterId: string;
|
|
chapterOrder: number;
|
|
title: string;
|
|
chapterContent: ChapterContent;
|
|
}
|
|
|
|
export interface ChapterContent {
|
|
version: number;
|
|
content: string;
|
|
wordsCount: number;
|
|
}
|
|
|
|
export interface ChapterVersion {
|
|
value: number;
|
|
label: 'Invite' | 'Brouillon' | 'Perfectionnement' | 'Révision' | 'Finale';
|
|
}
|
|
|
|
export type TiptapNode = {
|
|
type: string;
|
|
content?: TiptapNode[];
|
|
text?: string;
|
|
attrs?: {
|
|
[key: string]: any;
|
|
};
|
|
};
|
|
|
|
|
|
export const chapterVersions: SelectBoxProps[] = [
|
|
{value: '1', label: 'chapterVersions.prompt'},
|
|
{value: '2', label: 'chapterVersions.draft'},
|
|
{value: '3', label: 'chapterVersions.refine'},
|
|
{value: '4', label: 'chapterVersions.review'},
|
|
{value: '5', label: 'chapterVersions.final'},
|
|
];
|
|
|
|
export default class Chapter {
|
|
public static getPageCount(text: string): number {
|
|
const charactersPerLine = 90;
|
|
const linesPerPage = 40;
|
|
|
|
const lines: string[] = text.split('\n');
|
|
let totalLines: number = 0;
|
|
|
|
lines.forEach((line: string) => {
|
|
const lineLength: number = line.length;
|
|
const estimatedLines: number = Math.ceil(lineLength / charactersPerLine);
|
|
totalLines += estimatedLines;
|
|
});
|
|
|
|
// Calcul du nombre de pages
|
|
return Math.ceil(totalLines / linesPerPage);
|
|
}
|
|
static convertTiptapToHTML(node: TiptapNode): string {
|
|
let html = '';
|
|
|
|
switch (node.type) {
|
|
case 'doc':
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'paragraph':
|
|
html += '<p>';
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
html += '</p>';
|
|
break;
|
|
|
|
case 'text':
|
|
let textContent = node.text || '';
|
|
|
|
// Apply attributes like bold, italic, etc.
|
|
if (node.attrs) {
|
|
if (node.attrs.bold) {
|
|
textContent = `<strong>${textContent}</strong>`;
|
|
}
|
|
if (node.attrs.italic) {
|
|
textContent = `<em>${textContent}</em>`;
|
|
}
|
|
if (node.attrs.underline) {
|
|
textContent = `<u>${textContent}</u>`;
|
|
}
|
|
if (node.attrs.strike) {
|
|
textContent = `<s>${textContent}</s>`;
|
|
}
|
|
if (node.attrs.link) {
|
|
textContent = `<a href="${node.attrs.link.href}">${textContent}</a>`;
|
|
}
|
|
}
|
|
|
|
html += textContent;
|
|
break;
|
|
|
|
case 'heading':
|
|
const level = node.attrs?.level || 1;
|
|
html += `<h${level}>`;
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
html += `</h${level}>`;
|
|
break;
|
|
|
|
case 'bulletList':
|
|
html += '<ul>';
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
html += '</ul>';
|
|
break;
|
|
|
|
case 'orderedList':
|
|
html += '<ol>';
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
html += '</ol>';
|
|
break;
|
|
|
|
case 'listItem':
|
|
html += '<li>';
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
html += '</li>';
|
|
break;
|
|
|
|
case 'blockquote':
|
|
html += '<blockquote>';
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
html += '</blockquote>';
|
|
break;
|
|
|
|
case 'codeBlock':
|
|
html += '<pre><code>';
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
html += '</code></pre>';
|
|
break;
|
|
|
|
default:
|
|
console.warn(`Unhandled node type: ${node.type}`);
|
|
if (node.content) {
|
|
node.content.forEach(childNode => {
|
|
html += this.convertTiptapToHTML(childNode);
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
|
|
return html;
|
|
}
|
|
}
|