using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Jellyfin.Plugin.WatchedTogether.Configuration; /// /// The association between one shared account and the members who may unlock it. /// /// /// Membership is stored as GUIDs rather than being parsed out of the shared account's username. /// The default separator ('+') is itself a legal username character, so a name like "alice+bob" /// is ambiguous between the group [alice, bob] and a single user literally called "alice+bob". /// GUIDs remove that ambiguity and support any number of members. /// public class SharedGroup { /// /// Gets or sets the identifier of the shared account that members log into collectively. /// public Guid SharedUserId { get; set; } /// /// Gets or sets the identifiers of the members whose passwords unlock the shared account, /// and whose own accounts receive its watched state. A usable group has at least two. /// [SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Plugin configuration is round-tripped by the XML serializer, which requires a settable List.")] [SuppressMessage("Design", "CA1002:Do not expose generic lists", Justification = "Plugin configuration is round-tripped by the XML serializer, which requires a settable List.")] public List MemberUserIds { get; set; } = new(); /// /// Gets or sets a value indicating whether marking something unwatched on the shared account /// also marks it unwatched for every member. When false, only the transition to watched /// propagates. /// public bool SyncUnwatched { get; set; } = true; /// /// Gets or sets a value indicating whether a member's play count is raised to at least one /// when an item becomes watched. Play counts are never decremented. /// public bool SyncPlayCount { get; set; } /// /// Gets or sets a value indicating whether the shared account's parental rating cap is the /// strictest member's. When false, is used instead. /// /// /// Groups created at the login screen always inherit; choosing a cap is a dashboard-only /// action so nobody can widen access from the login screen. Unrated-item blocks and tag rules /// are always the strictest member's - they have no meaningful "level" to choose. /// public bool InheritParentalRating { get; set; } = true; /// /// Gets or sets the parental rating cap, as Jellyfin's numeric score, to use when /// is false. null means no cap. /// /// /// Kept within the range spanned by the members' own caps whenever it is applied: no lower than /// the strictest member (that would just be inheriting) and no looser than the loosest member /// (nobody could unlock the account past that, since a member may only unlock an account at /// least as restricted as they are). Wherever it sits in that range, members stricter than it /// can no longer unlock the account - that is the whole point of choosing one. /// public int? ParentalRatingCap { get; set; } /// /// Gets or sets a value indicating whether this group is suspended. A group drops out of both /// authentication and sync while disabled - set automatically if it falls below two members. /// public bool IsDisabled { get; set; } }