private void InitializeEntities(TweetMode tweetMode) { // NOTE: The STREAMING API and REST API does not provide the same JSON structure based on the TweetMode used. // // * STREAMING API : Adds a new ExtendedTweet regardless of the TweetMode. To have some consistency with the REST API, // we decided that in COMPAT mode, the Entities will be restricted to what is available in the REST API. // * REST API : Adds FullText and additional properties if the TweetMode is extended. var isTweetComingFromStreamingAPI = _tweetDTO?.ExtendedTweet != null; var useStreamingApiExtendedTweetForEntities = tweetMode == TweetMode.Extended && isTweetComingFromStreamingAPI; // Get the entities and extended_entities for whichever Tweet DTO we're using var entities = useStreamingApiExtendedTweetForEntities ? _tweetDTO.ExtendedTweet.LegacyEntities : _tweetDTO?.LegacyEntities; var extendedEntities = useStreamingApiExtendedTweetForEntities ? _tweetDTO.ExtendedTweet.ExtendedEntities : _tweetDTO?.Entities; // Populate for each type of entity. Urls = entities?.Urls; UserMentions = entities?.UserMentions; Hashtags = entities?.Hashtags; Symbols = entities?.Symbols; // Media can also be in the extended_entities field. https://dev.twitter.com/overview/api/entities-in-twitter-objects#extended_entities // If that's populated, we must use it instead or risk missing media Medias = extendedEntities?.Medias ?? entities?.Medias ?? new List <IMediaEntity>(); // If this is a retweet, it's also now possible for an entity to get cut off of the end of the tweet entirely. // If the same Tweet is fetched over the REST API, these entities get excluded, so lets do the same. if (_tweetDTO?.RetweetedTweetDTO != null) { Urls = Urls?.Where(e => e.Indices[0] != e.Indices[1]).ToList(); UserMentions = UserMentions?.Where(e => e.Indices[0] != e.Indices[1]).ToList(); Hashtags = Hashtags?.Where(e => e.Indices[0] != e.Indices[1]).ToList(); Symbols = Symbols?.Where(e => e.Indices[0] != e.Indices[1]).ToList(); Medias = Medias?.Where(e => e.Indices[0] != e.Indices[1]).ToList(); } }
private void textBox1_TextChanged(object sender, TextChangedEventArgs e) { if (ReplacingNow) { return; } if (!WordStart) { foreach (TextChange change in e.Changes) { if (change.AddedLength > 0) { switch (textBoxContent.Text.Substring(change.Offset, 1)) { case " ": case ",": case ".": case ":": case ";": case "(": case ")": case "!": case "?": case "\"": WordStart = true; UsernameStarted = false; HashtagStarted = false; break; default: WordStart = false; break; } if (WordStart) { break; } } } } if (UsernameStarted || HashtagStarted) { foreach (TextChange change in e.Changes) { if (change.AddedLength > 0) { switch (textBoxContent.Text.Substring(change.Offset, 1)) { case " ": case ",": case ".": case ":": case ";": case "(": case ")": case "!": case "?": case "\"": WordStart = true; UsernameStarted = false; HashtagStarted = false; break; default: WordStart = false; break; } if (WordStart) { break; } } } } if (WordStart && (!UsernameStarted && !HashtagStarted)) { foreach (TextChange change in e.Changes) { if (change.AddedLength > 0) { if (textBoxContent.Text.Substring(change.Offset, 1) == " ") { WordStart = true; continue; } else { WordStart = false; } if (textBoxContent.Text.Substring(change.Offset, 1) == "@") { UsernameStarted = true; StartPosition = change.Offset; CurrentText = ""; } else if (textBoxContent.Text.Substring(change.Offset, 1) == "#") { HashtagStarted = true; StartPosition = change.Offset; CurrentText = ""; } } } } if (UsernameStarted) { foreach (TextChange change in e.Changes) { if (change.AddedLength > 0) { CurrentText += textBoxContent.Text.Substring(change.Offset, change.AddedLength); } else if (change.RemovedLength > 0) { if (change.RemovedLength >= CurrentText.Length) { UsernameStarted = false; CurrentText = ""; MatchingTexts.Clear(); popupMatchingUsernames.IsOpen = false; return; } else if (change.RemovedLength == CurrentText.Length) { WordStart = true; CurrentText = ""; popupMatchingUsernames.IsOpen = false; MatchingTexts.Clear(); } else { CurrentText = CurrentText.Substring(0, CurrentText.Length - change.RemovedLength); } } } if (Usernames.Where(name => name.ToLower().StartsWith(CurrentText.ToLower())).Count() > 0) { MatchingTexts.Clear(); foreach (string username in Usernames.Where(name => name.ToLower().StartsWith(CurrentText.ToLower()))) { MatchingTexts.Add(username); if (MatchingTexts.Count >= Properties.Settings.Default.MaxNumberOfEntriesInAutocomplete) { break; } } popupMatchingUsernames.PlacementRectangle = textBoxContent.GetRectFromCharacterIndex(textBoxContent.CaretIndex, true); popupMatchingUsernames.IsOpen = true; } else { MatchingTexts.Clear(); popupMatchingUsernames.IsOpen = false; } } else if (HashtagStarted) { foreach (TextChange change in e.Changes) { if (change.AddedLength > 0) { CurrentText += textBoxContent.Text.Substring(change.Offset, change.AddedLength); } else if (change.RemovedLength > 0) { if (change.RemovedLength >= CurrentText.Length) { HashtagStarted = false; CurrentText = ""; MatchingTexts.Clear(); popupMatchingUsernames.IsOpen = false; return; } else if (change.RemovedLength == CurrentText.Length) { WordStart = true; CurrentText = ""; popupMatchingUsernames.IsOpen = false; MatchingTexts.Clear(); } else { CurrentText = CurrentText.Substring(0, CurrentText.Length - change.RemovedLength); } } } if (Hashtags.Where(tag => tag.ToLower().StartsWith(CurrentText.ToLower())).Count() > 0) { MatchingTexts.Clear(); foreach (string hashtag in Hashtags.Where(tag => tag.ToLower().StartsWith(CurrentText.ToLower()))) { MatchingTexts.Add(hashtag); if (MatchingTexts.Count >= Properties.Settings.Default.MaxNumberOfEntriesInAutocomplete) { break; } } popupMatchingUsernames.PlacementRectangle = textBoxContent.GetRectFromCharacterIndex(textBoxContent.CaretIndex, true); popupMatchingUsernames.IsOpen = true; } else { MatchingTexts.Clear(); popupMatchingUsernames.IsOpen = false; } } }