Rename root folders

This commit is contained in:
2024-11-12 21:25:02 +01:00
parent f4c21edca0
commit fb1c9a499f
101 changed files with 11 additions and 11 deletions

View File

@@ -0,0 +1,67 @@
export const API_BASE_URL = window.API_BASE_URL;
export const THEMES = {
LIGHT: 'light',
DARK: 'dark',
};
export const FILE_ACTIONS = {
CREATE: 'create',
DELETE: 'delete',
RENAME: 'rename',
};
export const MODAL_TYPES = {
NEW_FILE: 'newFile',
DELETE_FILE: 'deleteFile',
COMMIT_MESSAGE: 'commitMessage',
};
export const IMAGE_EXTENSIONS = [
'.jpg',
'.jpeg',
'.png',
'.gif',
'.webp',
'.svg',
];
// Renamed from DEFAULT_SETTINGS to be more specific
export const DEFAULT_WORKSPACE_SETTINGS = {
theme: THEMES.LIGHT,
autoSave: false,
gitEnabled: false,
gitUrl: '',
gitUser: '',
gitToken: '',
gitAutoCommit: false,
gitCommitMsgTemplate: '${action} ${filename}',
};
// Template for creating new workspaces
export const DEFAULT_WORKSPACE = {
name: '',
...DEFAULT_WORKSPACE_SETTINGS,
};
export const DEFAULT_FILE = {
name: 'New File.md',
path: 'New File.md',
content: '# Welcome to NovaMD\n\nStart editing here!',
};
export const MARKDOWN_REGEX = {
WIKILINK: /(!?)\[\[(.*?)\]\]/g,
};
// List of element types that can contain inline content
export const INLINE_CONTAINER_TYPES = new Set([
'paragraph',
'listItem',
'tableCell',
'blockquote',
'heading',
'emphasis',
'strong',
'delete',
]);

View File

@@ -0,0 +1,5 @@
import { IMAGE_EXTENSIONS } from './constants';
export const isImageFile = (filePath) => {
return IMAGE_EXTENSIONS.some((ext) => filePath.toLowerCase().endsWith(ext));
};

View File

@@ -0,0 +1,10 @@
export const formatBytes = (bytes) => {
const units = ['B', 'KB', 'MB', 'GB'];
let size = bytes;
let unitIndex = 0;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${size.toFixed(1)} ${units[unitIndex]}`;
};

View File

@@ -0,0 +1,177 @@
import { visit } from 'unist-util-visit';
import { lookupFileByName, getFileUrl } from '../services/api';
import { INLINE_CONTAINER_TYPES, MARKDOWN_REGEX } from './constants';
function createNotFoundLink(fileName, displayText, baseUrl) {
return {
type: 'link',
url: `${baseUrl}/notfound/${encodeURIComponent(fileName)}`,
children: [{ type: 'text', value: displayText }],
data: {
hProperties: { style: { color: 'red', textDecoration: 'underline' } },
},
};
}
function createFileLink(filePath, displayText, heading, baseUrl) {
const url = heading
? `${baseUrl}/internal/${encodeURIComponent(filePath)}#${encodeURIComponent(
heading
)}`
: `${baseUrl}/internal/${encodeURIComponent(filePath)}`;
return {
type: 'link',
url,
children: [{ type: 'text', value: displayText }],
};
}
function createImageNode(workspaceName, filePath, displayText) {
return {
type: 'image',
url: getFileUrl(workspaceName, filePath),
alt: displayText,
title: displayText,
};
}
function addMarkdownExtension(fileName) {
if (fileName.includes('.')) {
return fileName;
}
return `${fileName}.md`;
}
export function remarkWikiLinks(workspaceName) {
return async function transformer(tree) {
if (!workspaceName) {
console.warn('No workspace ID provided to remarkWikiLinks plugin');
return;
}
const baseUrl = window.API_BASE_URL;
const replacements = new Map();
// Find all wiki links
visit(tree, 'text', function (node, index, parent) {
const regex = MARKDOWN_REGEX.WIKILINK;
let match;
const matches = [];
while ((match = regex.exec(node.value)) !== null) {
const [fullMatch, isImage, innerContent] = match;
let fileName, displayText, heading;
const pipeIndex = innerContent.indexOf('|');
const hashIndex = innerContent.indexOf('#');
if (pipeIndex !== -1) {
displayText = innerContent.slice(pipeIndex + 1).trim();
fileName = innerContent.slice(0, pipeIndex).trim();
} else {
displayText = innerContent;
fileName = innerContent;
}
if (hashIndex !== -1 && (pipeIndex === -1 || hashIndex < pipeIndex)) {
heading = fileName.slice(hashIndex + 1).trim();
fileName = fileName.slice(0, hashIndex).trim();
}
matches.push({
fullMatch,
isImage,
fileName,
displayText,
heading,
index: match.index,
});
}
if (matches.length > 0) {
replacements.set(node, { matches, parent, index });
}
});
// Process all matches
for (const [node, { matches, parent }] of replacements) {
const newNodes = [];
let lastIndex = 0;
for (const match of matches) {
// Add text before the match
if (match.index > lastIndex) {
newNodes.push({
type: 'text',
value: node.value.slice(lastIndex, match.index),
});
}
try {
const lookupFileName = match.isImage
? match.fileName
: addMarkdownExtension(match.fileName);
const paths = await lookupFileByName(workspaceName, lookupFileName);
if (paths && paths.length > 0) {
const filePath = paths[0];
if (match.isImage) {
newNodes.push(
createImageNode(workspaceName, filePath, match.displayText)
);
} else {
newNodes.push(
createFileLink(
filePath,
match.displayText,
match.heading,
baseUrl
)
);
}
} else {
newNodes.push(
createNotFoundLink(match.fileName, match.displayText, baseUrl)
);
}
} catch (error) {
console.debug('File lookup failed:', match.fileName, error);
newNodes.push(
createNotFoundLink(match.fileName, match.displayText, baseUrl)
);
}
lastIndex = match.index + match.fullMatch.length;
}
// Add any remaining text
if (lastIndex < node.value.length) {
newNodes.push({
type: 'text',
value: node.value.slice(lastIndex),
});
}
// If the parent is a container that can have inline content,
// replace the text node directly with the new nodes
if (parent && INLINE_CONTAINER_TYPES.has(parent.type)) {
const nodeIndex = parent.children.indexOf(node);
if (nodeIndex !== -1) {
parent.children.splice(nodeIndex, 1, ...newNodes);
}
} else {
// For other types of parents, wrap the nodes in a paragraph
const paragraph = {
type: 'paragraph',
children: newNodes,
};
const nodeIndex = parent.children.indexOf(node);
if (nodeIndex !== -1) {
parent.children.splice(nodeIndex, 1, paragraph);
}
}
}
};
}