fish-station/Content.Client/MassMedia/Ui/ArticleEditorPanel.xaml.cs

259 lines
8.5 KiB
C#

using System.Numerics;
using Content.Client._Sunrise;
using Content.Client.Message;
using Content.Client.RichText;
using Content.Client.Stylesheets;
using Content.Shared.MassMedia.Systems;
using Robust.Client.AutoGenerated;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Utility;
namespace Content.Client.MassMedia.Ui;
[GenerateTypedNameReferences]
public sealed partial class ArticleEditorPanel : Control
{
[Dependency] private readonly NetTexturesManager _netTexturesManager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
public event Action? PublishButtonPressed;
public event Action<string, string, List<string>?>? ArticleDraftUpdated; // Sunrise-Edit
public event Action? RequestPhotosPressed; // Sunrise-Add
private bool _preview;
public List<string> PhotoPaths = new(); // Sunrise-Add
public ArticleEditorPanel()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
ButtonPublish.StyleClasses.Add(StyleClass.ButtonOpenLeft);
ButtonPublish.StyleClasses.Add(StyleClass.Positive);
ContentField.GetChild(0).Margin = new Thickness(9, 3);
// Customize scrollbar width and margin. This is not possible in xaml
var scrollbar = ContentField.GetChild(1);
scrollbar.SetWidth = 6f;
scrollbar.Margin = new Thickness(9, 0, 2 , 0);
RichTextInfoLabel.TooltipSupplier = sender =>
{
var label = new RichTextLabel();
label.SetMarkup(Loc.GetString("news-write-ui-richtext-tooltip"));
var tooltip = new Tooltip();
tooltip.GetChild(0).Children.Clear();
tooltip.GetChild(0).Children.Add(label);
return tooltip;
};
ButtonPreview.OnPressed += OnPreview;
ButtonCancel.OnPressed += OnCancel;
ButtonPublish.OnPressed += OnPublish;
ButtonSaveDraft.OnPressed += _ => OnDraftSaved();
ButtonAddPhoto.OnPressed += _ => RequestPhotosPressed?.Invoke(); // Sunrise-Add
TitleField.OnTextChanged += OnTitleChanged;
ContentField.OnTextChanged += OnContentChanged;
}
private void OnTextChanged(long length, Control control, long maxLength)
{
if (length > maxLength)
{
control.ModulateSelfOverride = Color.Red;
control.ToolTip = Loc.GetString("news-writer-text-length-exceeded");
ButtonPublish.Disabled = true;
ButtonPreview.Disabled = true;
}
else
{
control.ModulateSelfOverride = null;
control.ToolTip = string.Empty;
ButtonPublish.Disabled = false;
ButtonPreview.Disabled = false;
}
// save draft regardless; they can edit down the length later
ArticleDraftUpdated?.Invoke(TitleField.Text, Rope.Collapse(ContentField.TextRope), PhotoPaths); // Sunrise-Edit
}
private void OnPreview(BaseButton.ButtonEventArgs eventArgs)
{
_preview = !_preview;
TextEditPanel.Visible = !_preview;
PreviewPanel.Visible = _preview;
if (_preview)
{
var articleBody = Rope.Collapse(ContentField.TextRope);
PreviewLabel.SetMessage(FormattedMessage.FromMarkupPermissive(articleBody), UserFormattableTags.BaseAllowedTags);
ButtonPreview.Text = Loc.GetString("news-write-ui-write-text");
}
else
{
ButtonPreview.Text = Loc.GetString("news-write-ui-preview-text");
}
}
private void OnCancel(BaseButton.ButtonEventArgs eventArgs)
{
Reset();
Visible = false;
}
private void OnPublish(BaseButton.ButtonEventArgs eventArgs)
{
PublishButtonPressed?.Invoke();
Visible = false;
}
private void OnDraftSaved()
{
ArticleDraftUpdated?.Invoke(TitleField.Text, Rope.Collapse(ContentField.TextRope), PhotoPaths); // Sunrise-Edit
Visible = false;
}
private void OnTitleChanged(LineEdit.LineEditEventArgs args) => OnTextChanged(args.Text.Length, args.Control, SharedNewsSystem.MaxTitleLength);
private void OnContentChanged(TextEdit.TextEditEventArgs args) => OnTextChanged(Rope.CalcTotalLength(args.TextRope), args.Control, SharedNewsSystem.MaxContentLength);
private void Reset()
{
_preview = false;
TextEditPanel.Visible = true;
PreviewPanel.Visible = false;
PreviewLabel.SetMarkup("");
TitleField.Text = "";
ContentField.TextRope = Rope.Leaf.Empty;
// Sunrise-Start
PhotoPaths.Clear();
UpdatePhotosUI();
// Sunrise-End
ArticleDraftUpdated?.Invoke(string.Empty, string.Empty, null); // Sunrise-Edit
}
// Sunrise-Start
public void UpdatePhotosUI()
{
PhotosContainer.Children.Clear();
foreach (var path in PhotoPaths)
{
var photoControl = new SelectedPhotoControl(path, _netTexturesManager, _resourceCache);
photoControl.OnRemove += () =>
{
PhotoPaths.Remove(path);
UpdatePhotosUI();
ArticleDraftUpdated?.Invoke(TitleField.Text, Rope.Collapse(ContentField.TextRope), PhotoPaths);
};
PhotosContainer.AddChild(photoControl);
}
UpdatePhotoCountLabel();
}
private void UpdatePhotoCountLabel()
{
PhotoCountLabel.Text = $"{PhotoPaths.Count}/10";
ButtonAddPhoto.Disabled = PhotoPaths.Count >= 10;
PhotoCountLabel.ModulateSelfOverride = PhotoPaths.Count >= 10 ? Color.Red : null;
}
private sealed class SelectedPhotoControl : Control
{
public event Action? OnRemove;
private readonly string _path;
private readonly NetTexturesManager _netTextures;
private readonly IResourceCache _cache;
private readonly TextureRect _textureRect;
public SelectedPhotoControl(string path, NetTexturesManager netTextures, IResourceCache cache)
{
_path = path;
_netTextures = netTextures;
_cache = cache;
SetSize = new Vector2(100, 100);
_textureRect = new TextureRect
{
HorizontalExpand = true,
VerticalExpand = true,
Stretch = TextureRect.StretchMode.KeepAspectCentered
};
AddChild(_textureRect);
var removeButton = new Button
{
StyleClasses = { StyleClass.ButtonSmall },
HorizontalAlignment = HAlignment.Right,
VerticalAlignment = VAlignment.Top,
SetSize = new Vector2(24, 24),
Margin = new Thickness(0, 2, 2, 0),
};
removeButton.AddChild(
new Label
{
Text = "✖",
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center,
Margin = new Thickness(0, 0, 0, 2),
});
removeButton.OnPressed += _ => OnRemove?.Invoke();
AddChild(removeButton);
_netTextures.ResourceLoaded += OnResourceLoaded;
if (_netTextures.EnsureResource(path))
{
UpdateTexture();
}
}
private void OnResourceLoaded(string path)
{
if (path == _path)
UpdateTexture();
}
private void UpdateTexture()
{
var uploaded = _netTextures.GetUploadedPath(_path);
if (_cache.TryGetResource<TextureResource>(uploaded, out var tex))
_textureRect.Texture = tex.Texture;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_netTextures.ResourceLoaded -= OnResourceLoaded;
}
}
// Sunrise-End
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
ButtonPreview.OnPressed -= OnPreview;
ButtonCancel.OnPressed -= OnCancel;
ButtonPublish.OnPressed -= OnPublish;
ButtonSaveDraft.OnPressed -= _ => OnDraftSaved();
TitleField.OnTextChanged -= OnTitleChanged;
ContentField.OnTextChanged -= OnContentChanged;
}
}