diff --git a/Core/Data/Result/ConciseModel.cs b/Core/Data/Result/ConciseModel.cs
index 220c01e..a12cf59 100644
--- a/Core/Data/Result/ConciseModel.cs
+++ b/Core/Data/Result/ConciseModel.cs
@@ -4,6 +4,7 @@
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
+using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
@@ -20,32 +21,32 @@ namespace Trivial.Data;
public interface IConciseModel
{
///
- /// Gets or sets the identifier.
+ /// Gets the identifier.
///
string Id { get; }
///
- /// Gets or sets the title.
+ /// Gets the title.
///
string Title { get; }
///
- /// Gets or sets the description.
+ /// Gets the description.
///
string Description { get; }
///
- /// Gets or sets the image URI (thumbnail or avatar).
+ /// Gets the image URI (thumbnail or avatar).
///
Uri ImageUri { get; }
///
- /// Gets or sets the link.
+ /// Gets the link.
///
string Link { get; }
///
- /// Gets or sets the keywords.
+ /// Gets the keywords.
///
public IReadOnlyList Keywords { get; }
}
@@ -88,7 +89,71 @@ public ConciseModel(string id, string title, string link = null, string descript
Title = title;
Link = link;
Description = description;
- Keywords = keywords as ObservableCollection ?? new(keywords);
+ if (keywords != null) Keywords = keywords as ObservableCollection ?? new(keywords);
+ }
+
+ ///
+ /// Initializes a new instance of the ConciseModel class.
+ ///
+ /// The identifier of the video.
+ /// The title of the video.
+ /// The URL of the video to play.
+ /// The video description.
+ /// The keywords of the video.
+ public ConciseModel(Guid id, string title, string link = null, string description = null, IEnumerable keywords = null)
+ : this(id.ToString("N"), title, link, description, keywords)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the ConciseModel class.
+ ///
+ /// The identifier of the video.
+ /// The title of the video.
+ /// The keywords of the video.
+ /// The URL of the video to play.
+ public ConciseModel(string id, string title, IEnumerable keywords, string link = null)
+ : this(id, title, link, null, keywords)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the ConciseModel class.
+ ///
+ /// The identifier of the video.
+ /// The title of the video.
+ /// The keywords of the video.
+ /// The URL of the video to play.
+ public ConciseModel(Guid id, string title, IEnumerable keywords, string link = null)
+ : this(id.ToString("N"), title, link, null, keywords)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the ConciseModel class.
+ ///
+ /// The model to copy.
+ public ConciseModel(IConciseModel copy)
+ {
+ if (copy == null) return;
+ Id = copy.Id;
+ Title = copy.Title;
+ Link = copy.Link;
+ Description = copy.Description;
+ ImageUri = copy.ImageUri;
+ var keywords = copy.Keywords;
+ if (keywords != null)
+ {
+ Keywords = new();
+ foreach (var keyword in keywords)
+ {
+ Keywords.Add(keyword);
+ }
+ }
+
+ if (copy is not ConciseModel model) return;
+ Raw = model.Raw;
+ Tag = model.Tag;
}
///
@@ -178,6 +243,19 @@ public ObservableCollection Keywords
[JsonIgnore]
IReadOnlyList IConciseModel.Keywords => Keywords;
+ ///
+ /// Gets the count of keywords.
+ ///
+ [JsonIgnore]
+ public int KeywordCount
+ {
+ get
+ {
+ var keywords = Keywords;
+ return keywords == null ? 0 : keywords.Count;
+ }
+ }
+
///
/// Gets or sets the raw data.
///
@@ -244,6 +322,47 @@ public bool RemoveKeyword(string value)
return keywords.Remove(value);
}
+ ///
+ /// Tests if contains the specific keyword.
+ ///
+ /// The keyword to test.
+ /// One of the enumeration values that specifies how the strings will be compared.
+ /// true if contains; otherwise, false.
+ public bool ContainKeyword(string value, StringComparison comparison)
+ {
+ var keywords = Keywords;
+ if (keywords == null || string.IsNullOrEmpty(value)) return false;
+ value = value.Trim();
+ foreach (var keyword in keywords)
+ {
+ if (string.IsNullOrEmpty(keyword)) continue;
+ if (keyword.Trim().Equals(value, comparison)) return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Tests if contains the specific keyword.
+ ///
+ /// The keyword to test.
+ /// true if case insensitve; otherwise, false.
+ /// true if contains; otherwise, false.
+ public bool ContainKeyword(string value, bool ignoreCase = false)
+ {
+ var keywords = Keywords;
+ if (keywords == null || string.IsNullOrEmpty(value)) return false;
+ if (!ignoreCase) return keywords.Contains(value);
+ value = value.Trim();
+ foreach (var keyword in keywords)
+ {
+ if (string.IsNullOrEmpty(keyword)) continue;
+ if (keyword.Trim().Equals(value, StringComparison.OrdinalIgnoreCase)) return true;
+ }
+
+ return false;
+ }
+
///
/// Returns a string that represents the current model.
///