259 lines
8.5 KiB
C#
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;
|
|
}
|
|
}
|