/// <summary> /// Reset all tracking variables. /// </summary> public void Reset() { VotesWithSupporters.Clear(); VoterMessageId.Clear(); RankedVotesWithSupporters.Clear(); RankedVoterMessageId.Clear(); PlanNames.Clear(); ReferenceVoters.Clear(); ReferenceVoterPosts.Clear(); ReferencePlanNames.Clear(); ReferencePlans.Clear(); FutureReferences.Clear(); UndoBuffer.Clear(); OrderedTaskList.Clear(); cleanVoteLookup.Clear(); cleanedKeys.Clear(); if (VotesWithSupporters.Comparer != Agnostic.StringComparer) { VotesWithSupporters = new Dictionary <string, HashSet <string> >(Agnostic.StringComparer); } if (RankedVotesWithSupporters.Comparer != Agnostic.StringComparer) { RankedVotesWithSupporters = new Dictionary <string, HashSet <string> >(Agnostic.StringComparer); } OnPropertyChanged("VoteCounter"); OnPropertyChanged("Tasks"); }
/// <summary> /// Determine if the requested plan name exists in the current list of plans. /// Applies the plan name marker character to the provided plan name, if it /// doesn't already exist. /// </summary> /// <param name="planName">The name of the plan to check for.</param> /// <returns>Returns whether the provided plan name exists in the current PlanNames hash set.</returns> public bool HasPlan(string planName) { if (string.IsNullOrEmpty(planName)) { return(false); } return(PlanNames.Contains(planName, Agnostic.StringComparer)); }
/// <summary> /// Add a collection of votes to the vote counter. /// </summary> /// <param name="voteParts">A string list of all the parts of the vote to be added.</param> /// <param name="voter">The voter for this vote.</param> /// <param name="postID">The post ID for this vote.</param> /// <param name="voteType">The type of vote being added.</param> public void AddVotes(IEnumerable <string> voteParts, string voter, string postID, VoteType voteType) { if (voteParts == null) { throw new ArgumentNullException(nameof(voteParts)); } if (string.IsNullOrEmpty(voter)) { throw new ArgumentNullException(nameof(voter)); } if (string.IsNullOrEmpty(postID)) { throw new ArgumentNullException(nameof(postID)); } if (!voteParts.Any()) { return; } // Store/update the post ID of the voter AddVoterPostID(voter, postID, voteType); // Track plan names if (voteType == VoteType.Plan) { PlanNames.Add(voter); } var votes = GetVotesCollection(voteType); // Remove the voter from any existing votes if (RemoveSupport(voter, voteType)) { OnPropertyChanged("Voters"); } // Add/update all segments of the provided vote foreach (var part in voteParts) { AddVote(part, voter, voteType); } // Cleanup any votes that no longer have any support if (CleanupEmptyVotes(voteType)) { OnPropertyChanged("Votes"); } }
/// <summary> /// Find all votes tied to a given vote line. /// The "plan name" (possibly user name) is checked with the /// standard and alternate extractions (adding a special marker character /// depending on whether the word "plan" is used, and whether it's /// standard or alt) in order to look up votes that said (possible) voter /// supports. /// </summary> /// <param name="voteLine">The vote line to be checked.</param> /// <param name="author">The author of the vote. Prevent circular references.</param> /// <returns>Returns a list of all votes supported by the user or plan /// specified in the vote line, if found. Otherwise returns an /// empty list.</returns> public List <string> GetVotesFromReference(string voteLine, string author) { if (voteLine == null) { throw new ArgumentNullException(nameof(voteLine)); } if (author == null) { throw new ArgumentNullException(nameof(author)); } List <string> results = new List <string>(); var referenceNames = VoteString.GetVoteReferenceNames(voteLine); if (!referenceNames[ReferenceType.Any].Any()) { return(results); } string proxyName = null; if (referenceNames[ReferenceType.Label].Any()) { // If there is a "plan" prefix, then if it's a user reference, // check for a ◈plan before checking for the user's base vote. // If the reference exists as a plan, use it. if (referenceNames[ReferenceType.Plan].Any() && HasPlan(referenceNames[ReferenceType.Plan].First())) { // If this is not a user name, get the plan name as the proxy reference. proxyName = PlanNames.First(p => referenceNames[ReferenceType.Plan] .Contains(VoteString.DeUrlContent(VoteString.RemoveBBCode(p)), Agnostic.StringComparer)); } else if (ReferenceVoters.Contains(referenceNames[ReferenceType.Voter].First(), Agnostic.StringComparer)) { // If it doesn't exist as a plan, then we can check for users. if (!AdvancedOptions.Instance.DisableProxyVotes) { proxyName = ReferenceVoters.First(n => referenceNames[ReferenceType.Voter].Contains(n, Agnostic.StringComparer)); if (proxyName == author) { proxyName = null; } } } } else { // If there is no "plan" prefix, and if the plan name is a user // reference, it may only refer to that user's vote as a whole. // If this matches a user name, get that user name as the proxy reference. if (ReferenceVoters.Contains(referenceNames[ReferenceType.Voter].First(), Agnostic.StringComparer)) { if (!AdvancedOptions.Instance.DisableProxyVotes) { proxyName = ReferenceVoters.First(n => referenceNames[ReferenceType.Voter].Contains(n, Agnostic.StringComparer)); if (proxyName == author) { proxyName = null; } } } else if (referenceNames[ReferenceType.Plan].Any() && HasPlan(referenceNames[ReferenceType.Plan].First())) { // If this is not a user name, get the plan name as the proxy reference. proxyName = PlanNames.First(p => referenceNames[ReferenceType.Plan].Contains(p, Agnostic.StringComparer)); } } if (!string.IsNullOrEmpty(proxyName)) { var planVotes = VotesWithSupporters.Where(v => v.Value.Contains(proxyName)); results.AddRange(planVotes.Select(v => v.Key)); } return(results); }