diff --git a/src/PostIt/PostIt.Tests/MD/le-chant-1.md b/src/PostIt/PostIt.Tests/MD/le-chant-1.md
new file mode 100644
index 000000000..f4a7506fe
--- /dev/null
+++ b/src/PostIt/PostIt.Tests/MD/le-chant-1.md
@@ -0,0 +1,34 @@
+
+ Loin vers l'infini s'étendent
+ Les grands prés marécageux .
+ Pas un seul oiseau ne chante
+ Sur les arbres secs et creux !
+
+*(Refrain)*
+
+ Ô terre de détresse,
+ Où nous devons sans cesse,
+ Piocher, piocher .
+
+ Dans ce camp morne et sauvage
+ Entouré de murs de fer,
+ Il nous semble vivre en cage
+ Au milieu d'un grand désert .
+
+ Bruit des pas et bruit des armes,
+ Sentinelles jours et nuits,
+ Et du sang, et des cris, des larmes,
+ La mort pour celui qui fuit .
+
+ Mais un jour dans notre vie,
+ Le printemps refleurira .
+ Liberté, liberté chérie
+ Je dirai : « Tu es à moi ! »
+
+*(Dernier refrain)*
+
+ Ô terre d'allégresse,
+ Où nous pourrons sans cesse,
+ Aimer, aimer !
+
+[audio : Mario Hacquard - Youtube](https://www.youtube.com/watch?v=ogw_mgk1pFs)
diff --git a/src/PostIt/PostIt/Controls/MarkdownEditorControl.axaml b/src/PostIt/PostIt/Controls/MarkdownEditorControl.axaml
new file mode 100644
index 000000000..9e8df6dd1
--- /dev/null
+++ b/src/PostIt/PostIt/Controls/MarkdownEditorControl.axaml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/PostIt/PostIt/Controls/MarkdownEditorControl.axaml.cs b/src/PostIt/PostIt/Controls/MarkdownEditorControl.axaml.cs
new file mode 100644
index 000000000..0431b726e
--- /dev/null
+++ b/src/PostIt/PostIt/Controls/MarkdownEditorControl.axaml.cs
@@ -0,0 +1,88 @@
+using System;
+using Avalonia;
+using Avalonia.Controls;
+using AvaloniaEdit.Document;
+
+namespace PostIt.Controls;
+
+public partial class MarkdownEditorControl : UserControl
+{
+ public static readonly StyledProperty MarkdownTextProperty =
+ AvaloniaProperty.Register(nameof(MarkdownText));
+
+ public static readonly StyledProperty DocumentProperty =
+ AvaloniaProperty.Register(nameof(Document));
+
+ public static readonly StyledProperty IsPreviewVisibleProperty =
+ AvaloniaProperty.Register(nameof(IsPreviewVisible), false);
+
+ public string? MarkdownText
+ {
+ get => GetValue(MarkdownTextProperty);
+ set => SetValue(MarkdownTextProperty, value);
+ }
+
+ public TextDocument? Document
+ {
+ get => GetValue(DocumentProperty);
+ set => SetValue(DocumentProperty, value);
+ }
+
+ public bool IsPreviewVisible
+ {
+ get => GetValue(IsPreviewVisibleProperty);
+ set => SetValue(IsPreviewVisibleProperty, value);
+ }
+
+ public MarkdownEditorControl()
+ {
+ InitializeComponent();
+ PropertyChanged += OnPropertyChanged;
+ SizeChanged += OnSizeChanged;
+ UpdateEditorLimits();
+ }
+
+ private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
+ {
+ if (e.Property == MarkdownTextProperty)
+ {
+ var text = e.NewValue as string ?? string.Empty;
+ if (Document is null || !string.Equals(Document.Text, text, StringComparison.Ordinal))
+ {
+ Document = new TextDocument(text);
+ }
+ }
+ else if (e.Property == DocumentProperty)
+ {
+ var newDocument = e.NewValue as TextDocument;
+ var text = newDocument?.Text ?? string.Empty;
+ if (!string.Equals(MarkdownText, text, StringComparison.Ordinal))
+ {
+ MarkdownText = text;
+ }
+ }
+ }
+
+ private void OnSizeChanged(object? sender, SizeChangedEventArgs e)
+ {
+ UpdateEditorLimits();
+ }
+
+ private void UpdateEditorLimits()
+ {
+ var visibleHeight = Bounds.Height > 0 ? Bounds.Height - 24 : 260;
+ visibleHeight = Math.Max(visibleHeight, 80);
+
+ if (SourceEditor is not null)
+ {
+ SourceEditor.MaxHeight = visibleHeight;
+ SourceEditor.Height = double.NaN;
+ }
+
+ if (PreviewViewer is not null)
+ {
+ PreviewViewer.MaxHeight = visibleHeight;
+ PreviewViewer.Height = double.NaN;
+ }
+ }
+}
diff --git a/src/PostIt/PostIt/ViewModels/Blogs/BlogsViewModel.cs b/src/PostIt/PostIt/ViewModels/Blogs/BlogsViewModel.cs
index 6fe6eccc9..9de63c24c 100644
--- a/src/PostIt/PostIt/ViewModels/Blogs/BlogsViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/Blogs/BlogsViewModel.cs
@@ -39,18 +39,56 @@ public partial class BlogsViewModel : ViewModelBase, IActionStatusViewModel
/// Editor buffer for the post body. Same pattern as
/// .
- public string DraftArticle
+ public string? DraftArticle
{
- get => DraftArticleDocument.Text;
- set {
+ get => DraftArticleDocument?.Text ?? null;
+ set
+ {
+ var currentText = DraftArticleDocument?.Text;
+ if (string.Equals(currentText, value, StringComparison.Ordinal))
+ {
+ OnPropertyChanged(nameof(DraftArticle));
+ return;
+ }
+
OnPropertyChanging(nameof(DraftArticle));
- DraftArticleDocument = new TextDocument(value);
- this.OnPropertyChanged(nameof(DraftArticle));
+ DraftArticleDocument = value is not null ? new TextDocument(value) : null;
+ OnPropertyChanged(nameof(DraftArticle));
}
}
- [ObservableProperty]
- public partial TextDocument DraftArticleDocument {get; set;}
+ private TextDocument? _draftArticleDocument;
+
+ public TextDocument? DraftArticleDocument
+ {
+ get => _draftArticleDocument;
+ set
+ {
+ if (ReferenceEquals(_draftArticleDocument, value))
+ {
+ return;
+ }
+
+ if (_draftArticleDocument is not null)
+ {
+ _draftArticleDocument.TextChanged -= DraftArticleDocument_TextChanged;
+ }
+
+ _draftArticleDocument = value;
+
+ if (_draftArticleDocument is not null)
+ {
+ _draftArticleDocument.TextChanged += DraftArticleDocument_TextChanged;
+ }
+
+ OnPropertyChanged(nameof(DraftArticleDocument));
+ }
+ }
+
+ private void DraftArticleDocument_TextChanged(object? sender, EventArgs e)
+ {
+ OnPropertyChanged(nameof(DraftArticle));
+ }
/// Editor buffer for the post's publication state.
/// Reflects the server-side IsPublished flag (the
diff --git a/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml b/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml
index 90397f09d..5c926bdee 100644
--- a/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml
+++ b/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml
@@ -17,10 +17,14 @@
-
-
+
+
-
+
@@ -103,7 +107,7 @@
-
+
@@ -137,90 +141,61 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+ IsPreviewVisible="{Binding IsMarkdownViewerVisible, Mode=TwoWay}"
+ MarkdownText="{Binding DraftArticle, Mode=TwoWay}"
+ Document="{Binding DraftArticleDocument, Mode=TwoWay}" />
-
-
-
-
-
-
-
-
-
-
-
+ VerticalAlignment="Stretch">
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml.cs b/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml.cs
index 629727870..b40021276 100644
--- a/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml.cs
+++ b/src/PostIt/PostIt/Views/Blogs/BlogsPage.axaml.cs
@@ -4,69 +4,16 @@ using Avalonia.Controls;
using Avalonia.Platform.Storage;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
-using Avalonia.Controls.Platform;
namespace PostIt.Views.Blogs;
public partial class BlogsPage : ContentPage
{
- private IInputPane? _inputPane;
-
public BlogsPage()
{
InitializeComponent();
}
- protected override void OnLoaded(RoutedEventArgs e)
- {
- base.OnLoaded(e);
-
- // Récupère l'accès au TopLevel de la fenêtre/application
- var topLevel = TopLevel.GetTopLevel(this);
- if (topLevel != null)
- {
- _inputPane = topLevel!.InputPane;
- if (_inputPane != null)
- {
- // S'abonne aux changements d'état du clavier virtuel
- _inputPane.StateChanged += OnInputPaneStateChanged;
-
- // Applique la configuration initiale si le clavier est déjà présent
- UpdateLayoutForKeyboard(_inputPane.OccludedRect.Height);
- }
- }
- }
-
- protected override void OnUnloaded(RoutedEventArgs e)
- {
- if (_inputPane != null)
- {
- _inputPane.StateChanged -= OnInputPaneStateChanged;
- }
- base.OnUnloaded(e);
- }
-
-
- private void UpdateLayoutForKeyboard(double keyboardHeight)
- {
- double visibleHeight = this.Bounds.Height - keyboardHeight;
- if (keyboardHeight > 0)
- {
- DraftArticleTextEditor.MaxHeight = visibleHeight;
- }
- else
- {
- DraftArticleTextEditor.MaxHeight = double.PositiveInfinity;
- }
- }
-
- private void OnInputPaneStateChanged(object? sender, InputPaneStateEventArgs e)
- {
- // e.EndRect contient le rectangle final du clavier virtuel
- // e.EndRect.Height vous donne sa hauteur exacte en pixels indépendants du périphérique (pixels logiques)
- UpdateLayoutForKeyboard(e.EndRect.Height);
- }
-
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
diff --git a/src/Yavsc.Org/wwwroot/css/site.css b/src/Yavsc.Org/wwwroot/css/site.css
index bafc2d571..2e4720ff3 100644
--- a/src/Yavsc.Org/wwwroot/css/site.css
+++ b/src/Yavsc.Org/wwwroot/css/site.css
@@ -1,4 +1 @@
-.user-icon {
- max-width: 1.5em;
- max-height: 1.5em;
-}
+.user-icon{max-width:1.5em;max-height:1.5em}.card{padding:.5em}
diff --git a/src/Yavsc.Org/wwwroot/css/site.scss b/src/Yavsc.Org/wwwroot/css/site.scss
index 1bf7a4d34..546aac220 100644
--- a/src/Yavsc.Org/wwwroot/css/site.scss
+++ b/src/Yavsc.Org/wwwroot/css/site.scss
@@ -1,4 +1,7 @@
-user-icon {
+.user-icon {
max-width: 1.5em;
max-height: 1.5em;
}
+.card {
+ padding: .5em;
+}