upload
This commit is contained in:
147
Views/ArticleEditorWindow.xaml.cs
Normal file
147
Views/ArticleEditorWindow.xaml.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SimpleWiki.Data;
|
||||
using SimpleWiki.Models;
|
||||
using SimpleWiki.Services;
|
||||
|
||||
namespace SimpleWiki.Views;
|
||||
|
||||
public partial class ArticleEditorWindow : Window
|
||||
{
|
||||
private readonly User _currentUser;
|
||||
private readonly int? _articleId;
|
||||
private bool _isPreviewBrowserReady;
|
||||
private string _pendingPreviewHtml = string.Empty;
|
||||
|
||||
public ArticleEditorWindow(User currentUser, int? articleId = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
_currentUser = currentUser;
|
||||
_articleId = articleId;
|
||||
_pendingPreviewHtml = MarkdownService.ToHtmlDocument("Предпросмотр", "# Предпросмотр\n\nПодготовка предпросмотра...");
|
||||
Loaded += ArticleEditorWindow_Loaded;
|
||||
ContentRendered += ArticleEditorWindow_ContentRendered;
|
||||
}
|
||||
|
||||
|
||||
private void ArticleEditorWindow_ContentRendered(object? sender, EventArgs e)
|
||||
{
|
||||
_isPreviewBrowserReady = true;
|
||||
Dispatcher.BeginInvoke(RenderPreviewIfReady, DispatcherPriority.ApplicationIdle);
|
||||
}
|
||||
|
||||
private void ArticleEditorWindow_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_articleId.HasValue)
|
||||
{
|
||||
using var db = new AppDbContext();
|
||||
var article = db.Articles.AsNoTracking().FirstOrDefault(x => x.Id == _articleId.Value);
|
||||
if (article is not null)
|
||||
{
|
||||
TitleTextBox.Text = article.Title;
|
||||
SummaryTextBox.Text = article.Summary;
|
||||
MarkdownTextBox.Text = article.MarkdownContent;
|
||||
}
|
||||
}
|
||||
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
private void AnyInput_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
private void UpdatePreview()
|
||||
{
|
||||
var title = string.IsNullOrWhiteSpace(TitleTextBox.Text) ? "Новая статья" : TitleTextBox.Text.Trim();
|
||||
var content = string.IsNullOrWhiteSpace(MarkdownTextBox.Text)
|
||||
? "# Предпросмотр\n\nЗдесь появится отрендеренный markdown."
|
||||
: MarkdownTextBox.Text;
|
||||
|
||||
_pendingPreviewHtml = MarkdownService.ToHtmlDocument(title, content);
|
||||
RenderPreviewIfReady();
|
||||
}
|
||||
|
||||
private void RenderPreviewIfReady()
|
||||
{
|
||||
if (!_isPreviewBrowserReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PreviewBrowser.NavigateToString(_pendingPreviewHtml);
|
||||
}
|
||||
|
||||
private void SaveButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var titleError = InputValidator.ValidateArticleTitle(TitleTextBox.Text);
|
||||
var summaryError = InputValidator.ValidateArticleSummary(SummaryTextBox.Text);
|
||||
var markdownError = InputValidator.ValidateArticleMarkdown(MarkdownTextBox.Text);
|
||||
var errors = InputValidator.JoinErrors(titleError, summaryError, markdownError);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(errors))
|
||||
{
|
||||
MessageBox.Show(errors, "Ошибка валидации", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
using var db = new AppDbContext();
|
||||
var slug = SlugHelper.Generate(TitleTextBox.Text);
|
||||
|
||||
if (_articleId.HasValue)
|
||||
{
|
||||
var article = db.Articles.FirstOrDefault(x => x.Id == _articleId.Value);
|
||||
if (article is null)
|
||||
{
|
||||
MessageBox.Show("Статья не найдена.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var duplicate = db.Articles.AsNoTracking().Any(x => x.Slug == slug && x.Id != article.Id);
|
||||
if (duplicate)
|
||||
{
|
||||
MessageBox.Show("Статья с таким заголовком уже существует.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
article.Title = TitleTextBox.Text.Trim();
|
||||
article.Summary = SummaryTextBox.Text.Trim();
|
||||
article.MarkdownContent = MarkdownTextBox.Text.Trim();
|
||||
article.Slug = slug;
|
||||
article.UpdatedAt = DateTime.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
var duplicate = db.Articles.AsNoTracking().Any(x => x.Slug == slug);
|
||||
if (duplicate)
|
||||
{
|
||||
MessageBox.Show("Статья с таким заголовком уже существует.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var article = new Article
|
||||
{
|
||||
Title = TitleTextBox.Text.Trim(),
|
||||
Summary = SummaryTextBox.Text.Trim(),
|
||||
MarkdownContent = MarkdownTextBox.Text.Trim(),
|
||||
Slug = slug,
|
||||
AuthorId = _currentUser.Id,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
db.Articles.Add(article);
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void CancelButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user