1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-05-05 11:34:07 +02:00

Refactor & optimize context menu, send last tweet info only on right-click

This commit is contained in:
chylex 2018-03-02 05:24:45 +01:00
parent d5bf8ec558
commit 8fbb639430
6 changed files with 132 additions and 101 deletions

View File

@ -3,7 +3,7 @@
using System.Windows.Forms; using System.Windows.Forms;
using CefSharp; using CefSharp;
using TweetDuck.Core.Controls; using TweetDuck.Core.Controls;
using TweetDuck.Core.Handling; using TweetDuck.Core.Management;
using TweetDuck.Core.Notification; using TweetDuck.Core.Notification;
using TweetDuck.Core.Other; using TweetDuck.Core.Other;
using TweetDuck.Core.Utils; using TweetDuck.Core.Utils;
@ -13,20 +13,12 @@ namespace TweetDuck.Core.Bridge{
class TweetDeckBridge{ class TweetDeckBridge{
public static string FontSize { get; private set; } public static string FontSize { get; private set; }
public static string NotificationHeadLayout { get; private set; } public static string NotificationHeadLayout { get; private set; }
public static readonly ContextInfo ContextInfo = new ContextInfo();
public static string LastHighlightedTweetUrl = string.Empty;
public static string LastHighlightedQuoteUrl = string.Empty;
private static string LastHighlightedTweetAuthors = string.Empty;
private static string LastHighlightedTweetImages = string.Empty;
public static string[] LastHighlightedTweetAuthorsArray => LastHighlightedTweetAuthors.Split(';');
public static string[] LastHighlightedTweetImagesArray => LastHighlightedTweetImages.Split(';');
private static readonly Dictionary<string, string> SessionData = new Dictionary<string, string>(2); private static readonly Dictionary<string, string> SessionData = new Dictionary<string, string>(2);
public static void ResetStaticProperties(){ public static void ResetStaticProperties(){
FontSize = NotificationHeadLayout = null; FontSize = NotificationHeadLayout = null;
LastHighlightedTweetUrl = LastHighlightedQuoteUrl = LastHighlightedTweetAuthors = LastHighlightedTweetImages = string.Empty;
} }
public static void RestoreSessionData(IFrame frame){ public static void RestoreSessionData(IFrame frame){
@ -72,13 +64,8 @@ public void LoadNotificationLayout(string fontSize, string headLayout){
}); });
} }
public void SetLastHighlightedTweet(string tweetUrl, string quoteUrl, string authors, string imageList){ public void SetRightClickedChirp(string tweetUrl, string quoteUrl, string chirpAuthors, string chirpImages){
form.InvokeAsyncSafe(() => { ContextInfo.SetChirp(tweetUrl, quoteUrl, chirpAuthors, chirpImages);
LastHighlightedTweetUrl = tweetUrl;
LastHighlightedQuoteUrl = quoteUrl;
LastHighlightedTweetAuthors = authors;
LastHighlightedTweetImages = imageList;
});
} }
public void DisplayTooltip(string text){ public void DisplayTooltip(string text){
@ -112,8 +99,8 @@ public void ShowTweetDetail(){
// Global // Global
public void SetLastRightClickInfo(string type, string link){ public void SetLastRightClickInfo(string type, string url){
form.InvokeAsyncSafe(() => ContextMenuBase.SetContextInfo(type, link)); ContextInfo.SetLink(type, url);
} }
public void OnTweetPopup(string columnId, string chirpId, string columnName, string tweetHtml, int tweetCharacters, string tweetUrl, string quoteUrl){ public void OnTweetPopup(string columnId, string chirpId, string columnName, string tweetHtml, int tweetCharacters, string tweetUrl, string quoteUrl){

View File

@ -3,11 +3,10 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Forms; using System.Windows.Forms;
using CefSharp; using CefSharp;
using TweetDuck.Core.Bridge;
using TweetDuck.Core.Controls; using TweetDuck.Core.Controls;
using TweetDuck.Core.Utils; using TweetDuck.Core.Utils;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using TweetDuck.Core.Bridge;
using TweetDuck.Core.Management; using TweetDuck.Core.Management;
using TweetDuck.Core.Notification; using TweetDuck.Core.Notification;
using TweetDuck.Core.Other; using TweetDuck.Core.Other;
@ -18,19 +17,6 @@ abstract class ContextMenuBase : IContextMenuHandler{
public static readonly bool HasDevTools = File.Exists(Path.Combine(Program.ProgramPath, "devtools_resources.pak")); public static readonly bool HasDevTools = File.Exists(Path.Combine(Program.ProgramPath, "devtools_resources.pak"));
private static TwitterUtils.ImageQuality ImageQuality => Program.UserConfig.TwitterImageQuality; private static TwitterUtils.ImageQuality ImageQuality => Program.UserConfig.TwitterImageQuality;
private static KeyValuePair<string, string> ContextInfo;
private static bool IsLink => ContextInfo.Key == "link";
private static bool IsImage => ContextInfo.Key == "image";
private static bool IsVideo => ContextInfo.Key == "video";
public static void SetContextInfo(string type, string link){
ContextInfo = new KeyValuePair<string, string>(string.IsNullOrEmpty(link) ? null : type, link);
}
private static string GetMediaLink(IContextMenuParams parameters){
return IsImage || IsVideo ? ContextInfo.Value : parameters.SourceUrl;
}
private const CefMenuCommand MenuOpenLinkUrl = (CefMenuCommand)26500; private const CefMenuCommand MenuOpenLinkUrl = (CefMenuCommand)26500;
private const CefMenuCommand MenuCopyLinkUrl = (CefMenuCommand)26501; private const CefMenuCommand MenuCopyLinkUrl = (CefMenuCommand)26501;
@ -42,8 +28,8 @@ private static string GetMediaLink(IContextMenuParams parameters){
private const CefMenuCommand MenuSaveTweetImages = (CefMenuCommand)26507; private const CefMenuCommand MenuSaveTweetImages = (CefMenuCommand)26507;
private const CefMenuCommand MenuOpenDevTools = (CefMenuCommand)26599; private const CefMenuCommand MenuOpenDevTools = (CefMenuCommand)26599;
private string[] lastHighlightedTweetAuthors; protected ContextInfo.LinkInfo LastLink { get; private set; }
private string[] lastHighlightedTweetImageList; protected ContextInfo.ChirpInfo LastChirp { get; private set; }
private readonly AnalyticsFile.IProvider analytics; private readonly AnalyticsFile.IProvider analytics;
@ -51,19 +37,23 @@ protected ContextMenuBase(AnalyticsFile.IProvider analytics){
this.analytics = analytics; this.analytics = analytics;
} }
private void ResetContextInfo(){
LastLink = default(ContextInfo.LinkInfo);
LastChirp = default(ContextInfo.ChirpInfo);
TweetDeckBridge.ContextInfo.Reset();
}
public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){ public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){ if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
lastHighlightedTweetAuthors = StringUtils.EmptyArray; ResetContextInfo();
lastHighlightedTweetImageList = StringUtils.EmptyArray;
ContextInfo = default(KeyValuePair<string, string>);
} }
else{ else{
lastHighlightedTweetAuthors = TweetDeckBridge.LastHighlightedTweetAuthorsArray; LastLink = TweetDeckBridge.ContextInfo.Link;
lastHighlightedTweetImageList = TweetDeckBridge.LastHighlightedTweetImagesArray; LastChirp = TweetDeckBridge.ContextInfo.Chirp;
} }
bool hasTweetImage = IsImage; bool hasTweetImage = LastLink.IsImage;
bool hasTweetVideo = IsVideo; bool hasTweetVideo = LastLink.IsVideo;
string TextOpen(string name) => "Open "+name+" in browser"; string TextOpen(string name) => "Open "+name+" in browser";
string TextCopy(string name) => "Copy "+name+" address"; string TextCopy(string name) => "Copy "+name+" address";
@ -95,7 +85,7 @@ public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser bro
model.AddItem(MenuCopyMediaUrl, TextCopy("image")); model.AddItem(MenuCopyMediaUrl, TextCopy("image"));
model.AddItem(MenuSaveMedia, TextSave("image")); model.AddItem(MenuSaveMedia, TextSave("image"));
if (lastHighlightedTweetImageList.Length > 1){ if (LastChirp.Images.Length > 1){
model.AddItem(MenuSaveTweetImages, TextSave("all images")); model.AddItem(MenuSaveTweetImages, TextSave("all images"));
} }
@ -108,11 +98,11 @@ public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser br
switch(commandId){ switch(commandId){
case MenuOpenLinkUrl: case MenuOpenLinkUrl:
OpenBrowser(control, IsLink ? ContextInfo.Value : parameters.LinkUrl); OpenBrowser(control, LastLink.GetUrl(parameters, true));
break; break;
case MenuCopyLinkUrl: case MenuCopyLinkUrl:
SetClipboardText(control, IsLink ? ContextInfo.Value : parameters.UnfilteredLinkUrl); SetClipboardText(control, LastLink.GetUrl(parameters, false));
break; break;
case MenuCopyUsername: case MenuCopyUsername:
@ -122,35 +112,37 @@ public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser br
break; break;
case MenuOpenMediaUrl: case MenuOpenMediaUrl:
OpenBrowser(control, TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality)); OpenBrowser(control, TwitterUtils.GetMediaLink(LastLink.GetMediaSource(parameters), ImageQuality));
break; break;
case MenuCopyMediaUrl: case MenuCopyMediaUrl:
SetClipboardText(control, TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality)); SetClipboardText(control, TwitterUtils.GetMediaLink(LastLink.GetMediaSource(parameters), ImageQuality));
break; break;
case MenuViewImage: case MenuViewImage:
string url = GetMediaLink(parameters); void ViewImage(string path){
string file = Path.Combine(BrowserCache.CacheFolder, TwitterUtils.GetImageFileName(url)); string ext = Path.GetExtension(path);
void ViewFile(){
string ext = Path.GetExtension(file);
if (TwitterUtils.ValidImageExtensions.Contains(ext)){ if (TwitterUtils.ValidImageExtensions.Contains(ext)){
WindowsUtils.OpenAssociatedProgram(file); WindowsUtils.OpenAssociatedProgram(path);
} }
else{ else{
FormMessage.Error("Image Download", "Invalid file extension "+ext, FormMessage.OK); FormMessage.Error("Image Download", "Invalid file extension "+ext, FormMessage.OK);
} }
} }
string url = LastLink.GetMediaSource(parameters);
string file = Path.Combine(BrowserCache.CacheFolder, TwitterUtils.GetImageFileName(url));
if (File.Exists(file)){ if (File.Exists(file)){
ViewFile(); ViewImage(file);
} }
else{ else{
control.InvokeAsyncSafe(analytics.AnalyticsFile.ViewedImages.Trigger); control.InvokeAsyncSafe(analytics.AnalyticsFile.ViewedImages.Trigger);
BrowserUtils.DownloadFileAsync(TwitterUtils.GetMediaLink(url, ImageQuality), file, ViewFile, ex => { BrowserUtils.DownloadFileAsync(TwitterUtils.GetMediaLink(url, ImageQuality), file, () => {
ViewImage(file);
}, ex => {
FormMessage.Error("Image Download", "An error occurred while downloading the image: "+ex.Message, FormMessage.OK); FormMessage.Error("Image Download", "An error occurred while downloading the image: "+ex.Message, FormMessage.OK);
}); });
} }
@ -158,20 +150,20 @@ void ViewFile(){
break; break;
case MenuSaveMedia: case MenuSaveMedia:
if (IsVideo){ if (LastLink.IsVideo){
control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedVideos.Trigger); control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedVideos.Trigger);
TwitterUtils.DownloadVideo(GetMediaLink(parameters), lastHighlightedTweetAuthors.LastOrDefault()); TwitterUtils.DownloadVideo(LastLink.GetMediaSource(parameters), LastChirp.Authors.LastOrDefault());
} }
else{ else{
control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedImages.Trigger); control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedImages.Trigger);
TwitterUtils.DownloadImage(GetMediaLink(parameters), lastHighlightedTweetAuthors.LastOrDefault(), ImageQuality); TwitterUtils.DownloadImage(LastLink.GetMediaSource(parameters), LastChirp.Authors.LastOrDefault(), ImageQuality);
} }
break; break;
case MenuSaveTweetImages: case MenuSaveTweetImages:
control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedImages.Trigger); control.InvokeAsyncSafe(analytics.AnalyticsFile.DownloadedImages.Trigger);
TwitterUtils.DownloadImages(lastHighlightedTweetImageList, lastHighlightedTweetAuthors.LastOrDefault(), ImageQuality); TwitterUtils.DownloadImages(LastChirp.Images, LastChirp.Authors.LastOrDefault(), ImageQuality);
break; break;
case MenuOpenDevTools: case MenuOpenDevTools:
@ -183,7 +175,7 @@ void ViewFile(){
} }
public virtual void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame){ public virtual void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame){
ContextInfo = default(KeyValuePair<string, string>); ResetContextInfo();
} }
public virtual bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback){ public virtual bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback){

View File

@ -1,8 +1,6 @@
using CefSharp; using CefSharp;
using System.Windows.Forms; using System.Windows.Forms;
using TweetDuck.Core.Bridge;
using TweetDuck.Core.Controls; using TweetDuck.Core.Controls;
using TweetDuck.Core.Utils;
namespace TweetDuck.Core.Handling{ namespace TweetDuck.Core.Handling{
sealed class ContextMenuBrowser : ContextMenuBase{ sealed class ContextMenuBrowser : ContextMenuBase{
@ -26,10 +24,7 @@ sealed class ContextMenuBrowser : ContextMenuBase{
private const string TitleAboutProgram = "About "+Program.BrandName; private const string TitleAboutProgram = "About "+Program.BrandName;
private readonly FormBrowser form; private readonly FormBrowser form;
private string lastHighlightedTweetUrl;
private string lastHighlightedQuoteUrl;
public ContextMenuBrowser(FormBrowser form) : base(form){ public ContextMenuBrowser(FormBrowser form) : base(form){
this.form = form; this.form = form;
} }
@ -52,20 +47,12 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model); base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
lastHighlightedTweetUrl = TweetDeckBridge.LastHighlightedTweetUrl; if (!string.IsNullOrEmpty(LastChirp.TweetUrl) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
lastHighlightedQuoteUrl = TweetDeckBridge.LastHighlightedQuoteUrl;
if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
lastHighlightedTweetUrl = string.Empty;
lastHighlightedQuoteUrl = string.Empty;
}
if (!string.IsNullOrEmpty(lastHighlightedTweetUrl) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
model.AddItem(MenuOpenTweetUrl, "Open tweet in browser"); model.AddItem(MenuOpenTweetUrl, "Open tweet in browser");
model.AddItem(MenuCopyTweetUrl, "Copy tweet address"); model.AddItem(MenuCopyTweetUrl, "Copy tweet address");
model.AddItem(MenuScreenshotTweet, "Screenshot tweet to clipboard"); model.AddItem(MenuScreenshotTweet, "Screenshot tweet to clipboard");
if (!string.IsNullOrEmpty(lastHighlightedQuoteUrl)){ if (!string.IsNullOrEmpty(LastChirp.QuoteUrl)){
model.AddSeparator(); model.AddSeparator();
model.AddItem(MenuOpenQuotedTweetUrl, "Open quoted tweet in browser"); model.AddItem(MenuOpenQuotedTweetUrl, "Open quoted tweet in browser");
model.AddItem(MenuCopyQuotedTweetUrl, "Copy quoted tweet address"); model.AddItem(MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
@ -126,11 +113,11 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
return true; return true;
case MenuOpenTweetUrl: case MenuOpenTweetUrl:
OpenBrowser(form, lastHighlightedTweetUrl); OpenBrowser(form, LastChirp.TweetUrl);
return true; return true;
case MenuCopyTweetUrl: case MenuCopyTweetUrl:
SetClipboardText(form, lastHighlightedTweetUrl); SetClipboardText(form, LastChirp.TweetUrl);
return true; return true;
case MenuScreenshotTweet: case MenuScreenshotTweet:
@ -138,11 +125,11 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
return true; return true;
case MenuOpenQuotedTweetUrl: case MenuOpenQuotedTweetUrl:
OpenBrowser(form, lastHighlightedQuoteUrl); OpenBrowser(form, LastChirp.QuoteUrl);
return true; return true;
case MenuCopyQuotedTweetUrl: case MenuCopyQuotedTweetUrl:
SetClipboardText(form, lastHighlightedQuoteUrl); SetClipboardText(form, LastChirp.QuoteUrl);
return true; return true;
case MenuInputApplyROT13: case MenuInputApplyROT13:

View File

@ -0,0 +1,68 @@
using CefSharp;
using TweetDuck.Core.Utils;
namespace TweetDuck.Core.Management{
sealed class ContextInfo{
public LinkInfo Link { get; private set; }
public ChirpInfo Chirp { get; private set; }
public ContextInfo(){
Reset();
}
public void SetLink(string type, string url){
Link = new LinkInfo(string.IsNullOrEmpty(type) ? null : type, url);
}
public void SetChirp(string tweetUrl, string quoteUrl, string chirpAuthors, string chirpImages){
Chirp = new ChirpInfo(tweetUrl, quoteUrl, chirpAuthors, chirpImages);
}
public void Reset(){
Link = new LinkInfo();
Chirp = new ChirpInfo();
}
// Data structures
public struct LinkInfo{
public bool IsLink => type == "link";
public bool IsImage => type == "image";
public bool IsVideo => type == "video";
public string GetUrl(IContextMenuParams parameters, bool safe){
return IsLink ? url : (safe ? parameters.LinkUrl : parameters.UnfilteredLinkUrl);
}
public string GetMediaSource(IContextMenuParams parameters){
return IsImage || IsVideo ? url : parameters.SourceUrl;
}
private readonly string type;
private readonly string url;
public LinkInfo(string type, string url){
this.type = type;
this.url = url;
}
}
public struct ChirpInfo{
public string TweetUrl { get; }
public string QuoteUrl { get; }
public string[] Authors => chirpAuthors?.Split(';') ?? StringUtils.EmptyArray;
public string[] Images => chirpImages?.Split(';') ?? StringUtils.EmptyArray;
private readonly string chirpAuthors;
private readonly string chirpImages;
public ChirpInfo(string tweetUrl, string quoteUrl, string chirpAuthors, string chirpImages){
this.TweetUrl = tweetUrl;
this.QuoteUrl = quoteUrl;
this.chirpAuthors = chirpAuthors;
this.chirpImages = chirpImages;
}
}
}
}

View File

@ -595,22 +595,15 @@
// Block: Update highlighted column and tweet for context menu and other functionality. // Block: Update highlighted column and tweet for context menu and other functionality.
// //
(function(){ (function(){
var lastTweet = "";
const updateHighlightedColumn = function(ele){ const updateHighlightedColumn = function(ele){
highlightedColumnEle = ele; highlightedColumnEle = ele;
highlightedColumnObj = ele ? TD.controller.columnManager.get(ele.attr("data-column")) : null; highlightedColumnObj = ele ? TD.controller.columnManager.get(ele.attr("data-column")) : null;
return !!highlightedColumnObj; return !!highlightedColumnObj;
}; };
const updateHighlightedTweet = function(ele, obj, tweetUrl, quoteUrl, authors, imageList){ const updateHighlightedTweet = function(ele, obj){
highlightedTweetEle = ele; highlightedTweetEle = ele;
highlightedTweetObj = obj; highlightedTweetObj = obj;
if (lastTweet !== tweetUrl){
$TD.setLastHighlightedTweet(tweetUrl, quoteUrl, authors, imageList);
lastTweet = tweetUrl;
}
}; };
const processMedia = function(chirp){ const processMedia = function(chirp){
@ -626,6 +619,19 @@
mouseleave: function(){ mouseleave: function(){
updateHighlightedColumn(null); updateHighlightedColumn(null);
},
contextmenu: function(){
let tweet = highlightedTweetObj;
if (tweet && tweet.chirpType === TD.services.ChirpBase.TWEET){
let tweetUrl = tweet.getChirpURL();
let quoteUrl = tweet.quotedTweet ? tweet.quotedTweet.getChirpURL() : "";
let chirpAuthors = tweet.quotedTweet ? [ tweet.getMainUser().screenName, tweet.quotedTweet.getMainUser().screenName ].join(";") : tweet.getMainUser().screenName;
let chirpImages = tweet.hasImage() ? processMedia(tweet) : tweet.quotedTweet && tweet.quotedTweet.hasImage() ? processMedia(tweet.quotedTweet) : "";
$TD.setRightClickedChirp(tweetUrl || "", quoteUrl || "", chirpAuthors, chirpImages);
}
} }
}); });
@ -637,21 +643,11 @@
let tweet = highlightedColumnObj.findChirp(me.attr("data-tweet-id")) || highlightedColumnObj.findChirp(me.attr("data-key")); let tweet = highlightedColumnObj.findChirp(me.attr("data-tweet-id")) || highlightedColumnObj.findChirp(me.attr("data-key"));
return if !tweet; return if !tweet;
if (tweet.chirpType === TD.services.ChirpBase.TWEET){ updateHighlightedTweet(me, tweet);
let tweetUrl = tweet.getChirpURL();
let quoteUrl = tweet.quotedTweet ? tweet.quotedTweet.getChirpURL() : "";
let authors = tweet.quotedTweet ? [ tweet.getMainUser().screenName, tweet.quotedTweet.getMainUser().screenName ].join(";") : tweet.getMainUser().screenName;
let imageList = tweet.hasImage() ? processMedia(tweet) : tweet.quotedTweet && tweet.quotedTweet.hasImage() ? processMedia(tweet.quotedTweet) : "";
updateHighlightedTweet(me, tweet, tweetUrl || "", quoteUrl || "", authors, imageList);
}
else{
updateHighlightedTweet(me, tweet, "", "", "", "");
}
}, },
mouseleave: function(){ mouseleave: function(){
updateHighlightedTweet(null, null, "", "", "", ""); updateHighlightedTweet(null, null);
} }
}); });
})(); })();

View File

@ -108,6 +108,7 @@
<Compile Include="Core\Handling\RequestHandlerBrowser.cs" /> <Compile Include="Core\Handling\RequestHandlerBrowser.cs" />
<Compile Include="Core\Handling\ResourceHandlerNotification.cs" /> <Compile Include="Core\Handling\ResourceHandlerNotification.cs" />
<Compile Include="Core\ITweetDeckBrowser.cs" /> <Compile Include="Core\ITweetDeckBrowser.cs" />
<Compile Include="Core\Management\ContextInfo.cs" />
<Compile Include="Core\Notification\Example\FormNotificationExample.cs"> <Compile Include="Core\Notification\Example\FormNotificationExample.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>