fix: post creation working again, also slugs

This commit is contained in:
2026-02-10 16:50:45 +01:00
parent 3f0c767809
commit 5c10ed3fd5
7 changed files with 106 additions and 17 deletions

View File

@@ -232,7 +232,7 @@ export class PostEngine extends EventEmitter {
const post: PostData = {
id,
projectId: data.projectId || this.currentProjectId,
title: data.title || 'Untitled',
title: data.title ?? '',
slug,
excerpt: data.excerpt,
content: data.content || '',
@@ -303,11 +303,18 @@ export class PostEngine extends EventEmitter {
newStatus = 'draft';
}
// Auto-update slug when title changes, but only if post was never published
let newSlug = data.slug ?? existing.slug;
if (data.title !== undefined && data.title !== existing.title && !existing.publishedAt) {
newSlug = await this.generateUniqueSlug(data.title || 'untitled', id);
}
const updated: PostData = {
...existing,
...data,
id, // Ensure ID doesn't change
projectId: existing.projectId, // Ensure projectId doesn't change
slug: newSlug,
status: newStatus as 'draft' | 'published' | 'archived',
updatedAt: new Date(),
};

View File

@@ -44,8 +44,14 @@ function createWindow(): void {
}
// Forward events to renderer
ipcMain.on('forward-to-renderer', (_event, eventName: string, ...args: unknown[]) => {
if (mainWindow && !mainWindow.isDestroyed()) {
// Note: ipcMain.emit() (used by forwardEvent in handlers) is a raw EventEmitter emit,
// so the first arg is NOT an IpcMainEvent — it's the event name string directly.
ipcMain.on('forward-to-renderer', (eventNameOrEvent: any, ...args: unknown[]) => {
// When called via ipcMain.emit(), first arg is the channel string directly
const eventName: string = typeof eventNameOrEvent === 'string'
? eventNameOrEvent
: args.shift() as string;
if (mainWindow && !mainWindow.isDestroyed() && typeof eventName === 'string') {
mainWindow.webContents.send(eventName, ...args);
}
});

View File

@@ -170,8 +170,8 @@ const App: React.FC = () => {
unsubscribers.push(
window.electronAPI?.on('menu:newPost', async () => {
const post = await window.electronAPI?.posts.create({
title: 'New Post',
content: '# New Post\n\nStart writing...',
title: '',
content: '',
});
if (post) {
setSelectedPost((post as PostData).id);

View File

@@ -373,7 +373,7 @@ const PostEditor: React.FC<PostEditorProps> = ({ post }) => {
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Post title"
placeholder="Untitled"
/>
</div>
<div className="editor-field">
@@ -667,18 +667,17 @@ const MediaEditor: React.FC<{ mediaId: string }> = ({ mediaId }) => {
};
const WelcomeScreen: React.FC = () => {
const { addPost, setSelectedPost } = useAppStore();
const { setSelectedPost } = useAppStore();
const handleNewPost = async () => {
try {
const newPost = await window.electronAPI?.posts.create({
title: 'Untitled',
title: '',
content: '',
tags: [],
categories: [],
});
if (newPost) {
addPost(newPost as PostData);
setSelectedPost(newPost.id);
}
} catch (error) {

View File

@@ -324,15 +324,14 @@ const PostsList: React.FC = () => {
const handleCreatePost = async () => {
// Create a real post immediately in the database with default empty content
try {
const { addPost, setSelectedPost: selectPost } = useAppStore.getState();
const { setSelectedPost: selectPost } = useAppStore.getState();
const newPost = await window.electronAPI?.posts.create({
title: 'Untitled',
title: '',
content: '',
tags: [],
categories: [],
});
if (newPost) {
addPost(newPost as PostData);
selectPost(newPost.id);
}
} catch (error) {
@@ -434,7 +433,7 @@ const PostsList: React.FC = () => {
>
<span className="post-type-icon" title={postType.type}>{postType.icon}</span>
<div className="sidebar-item-content">
<div className="sidebar-item-title">{post.title}</div>
<div className="sidebar-item-title">{post.title || 'Untitled'}</div>
<div className="sidebar-item-meta">{formatDate(post.updatedAt)}</div>
</div>
</div>
@@ -461,7 +460,7 @@ const PostsList: React.FC = () => {
>
<span className="post-type-icon" title={postType.type}>{postType.icon}</span>
<div className="sidebar-item-content">
<div className="sidebar-item-title">{post.title}</div>
<div className="sidebar-item-title">{post.title || 'Untitled'}</div>
<div className="sidebar-item-meta">{formatDate(post.publishedAt || post.updatedAt)}</div>
</div>
</div>
@@ -488,7 +487,7 @@ const PostsList: React.FC = () => {
>
<span className="post-type-icon" title={postType.type}>{postType.icon}</span>
<div className="sidebar-item-content">
<div className="sidebar-item-title">{post.title}</div>
<div className="sidebar-item-title">{post.title || 'Untitled'}</div>
<div className="sidebar-item-meta">{formatDate(post.updatedAt)}</div>
</div>
</div>