mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-14 03:15:49 +02:00
Refactor context menu handling and make adding new types of context easier
This commit is contained in:
parent
588bb9a093
commit
442d74d0cb
Core
Resources/Scripts
@ -3,6 +3,7 @@
|
||||
using System.Windows.Forms;
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Handling;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Utils;
|
||||
@ -10,8 +11,6 @@
|
||||
|
||||
namespace TweetDuck.Core.Bridge{
|
||||
sealed class TweetDeckBridge{
|
||||
public static string LastRightClickedLink = string.Empty;
|
||||
public static string LastRightClickedImage = string.Empty;
|
||||
public static string LastHighlightedTweet = string.Empty;
|
||||
public static string LastHighlightedQuotedTweet = string.Empty;
|
||||
public static string LastHighlightedTweetAuthor = string.Empty;
|
||||
@ -19,7 +18,7 @@ sealed class TweetDeckBridge{
|
||||
public static Dictionary<string, string> SessionData = new Dictionary<string, string>(2);
|
||||
|
||||
public static void ResetStaticProperties(){
|
||||
LastRightClickedLink = LastRightClickedImage = LastHighlightedTweet = LastHighlightedQuotedTweet = LastHighlightedTweetAuthor = string.Empty;
|
||||
LastHighlightedTweet = LastHighlightedQuotedTweet = LastHighlightedTweetAuthor = string.Empty;
|
||||
LastHighlightedTweetImages = StringUtils.EmptyArray;
|
||||
}
|
||||
|
||||
@ -56,12 +55,8 @@ public void LoadNotificationHeadContents(string headContents){
|
||||
});
|
||||
}
|
||||
|
||||
public void SetLastRightClickedLink(string link){
|
||||
form.InvokeAsyncSafe(() => LastRightClickedLink = link);
|
||||
}
|
||||
|
||||
public void SetLastRightClickedImage(string link){
|
||||
form.InvokeAsyncSafe(() => LastRightClickedImage = link);
|
||||
public void SetLastRightClickInfo(string type, string link){
|
||||
form.InvokeAsyncSafe(() => ContextMenuBase.SetContextInfo(type, link));
|
||||
}
|
||||
|
||||
public void SetLastHighlightedTweet(string link, string quotedLink, string author, string imageList){
|
||||
|
@ -6,29 +6,35 @@
|
||||
using TweetDuck.Core.Bridge;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Utils;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
abstract class ContextMenuBase : IContextMenuHandler{
|
||||
protected static readonly bool HasDevTools = File.Exists(Path.Combine(Program.ProgramPath, "devtools_resources.pak"));
|
||||
|
||||
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";
|
||||
|
||||
private static string GetLink(IContextMenuParams parameters){
|
||||
return string.IsNullOrEmpty(TweetDeckBridge.LastRightClickedLink) ? parameters.UnfilteredLinkUrl : TweetDeckBridge.LastRightClickedLink;
|
||||
public static void SetContextInfo(string type, string link){
|
||||
ContextInfo = new KeyValuePair<string, string>(string.IsNullOrEmpty(link) ? null : type, link);
|
||||
}
|
||||
|
||||
private static string GetImage(IContextMenuParams parameters){
|
||||
return string.IsNullOrEmpty(TweetDeckBridge.LastRightClickedImage) ? parameters.SourceUrl : TweetDeckBridge.LastRightClickedImage;
|
||||
private static string GetMediaLink(IContextMenuParams parameters){
|
||||
return IsImage || IsVideo ? ContextInfo.Value : parameters.SourceUrl;
|
||||
}
|
||||
|
||||
private const int MenuOpenLinkUrl = 26500;
|
||||
private const int MenuCopyLinkUrl = 26501;
|
||||
private const int MenuCopyUsername = 26502;
|
||||
private const int MenuOpenImageUrl = 26503;
|
||||
private const int MenuCopyImageUrl = 26504;
|
||||
private const int MenuSaveImage = 26505;
|
||||
private const int MenuSaveAllImages = 26506;
|
||||
private const int MenuOpenDevTools = 26599;
|
||||
private const CefMenuCommand MenuOpenLinkUrl = (CefMenuCommand)26500;
|
||||
private const CefMenuCommand MenuCopyLinkUrl = (CefMenuCommand)26501;
|
||||
private const CefMenuCommand MenuCopyUsername = (CefMenuCommand)26502;
|
||||
private const CefMenuCommand MenuOpenMediaUrl = (CefMenuCommand)26503;
|
||||
private const CefMenuCommand MenuCopyMediaUrl = (CefMenuCommand)26504;
|
||||
private const CefMenuCommand MenuSaveMedia = (CefMenuCommand)26505;
|
||||
private const CefMenuCommand MenuSaveTweetImages = (CefMenuCommand)26506;
|
||||
private const CefMenuCommand MenuOpenDevTools = (CefMenuCommand)26599;
|
||||
|
||||
private readonly Form form;
|
||||
|
||||
@ -40,36 +46,46 @@ protected ContextMenuBase(Form form){
|
||||
}
|
||||
|
||||
public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
bool hasTweetImage = !string.IsNullOrEmpty(TweetDeckBridge.LastRightClickedImage);
|
||||
lastHighlightedTweetAuthor = TweetDeckBridge.LastHighlightedTweetAuthor;
|
||||
lastHighlightedTweetImageList = TweetDeckBridge.LastHighlightedTweetImages;
|
||||
|
||||
if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
|
||||
lastHighlightedTweetAuthor = string.Empty;
|
||||
lastHighlightedTweetImageList = StringUtils.EmptyArray;
|
||||
ContextInfo = default(KeyValuePair<string, string>);
|
||||
}
|
||||
else{
|
||||
lastHighlightedTweetAuthor = TweetDeckBridge.LastHighlightedTweetAuthor;
|
||||
lastHighlightedTweetImageList = TweetDeckBridge.LastHighlightedTweetImages;
|
||||
}
|
||||
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Link) && !parameters.UnfilteredLinkUrl.EndsWith("tweetdeck.twitter.com/#", StringComparison.Ordinal) && !hasTweetImage){
|
||||
bool hasTweetImage = IsImage;
|
||||
bool hasTweetVideo = IsVideo;
|
||||
|
||||
string TextOpen(string name) => "Open "+name+" in browser";
|
||||
string TextCopy(string name) => "Copy "+name+" address";
|
||||
string TextSave(string name) => "Save "+name+" as...";
|
||||
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Link) && !parameters.UnfilteredLinkUrl.EndsWith("tweetdeck.twitter.com/#", StringComparison.Ordinal) && !hasTweetImage && !hasTweetVideo){
|
||||
if (TwitterUtils.RegexAccount.IsMatch(parameters.UnfilteredLinkUrl)){
|
||||
model.AddItem((CefMenuCommand)MenuOpenLinkUrl, "Open account in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyLinkUrl, "Copy account address");
|
||||
model.AddItem((CefMenuCommand)MenuCopyUsername, "Copy account username");
|
||||
model.AddItem(MenuOpenLinkUrl, TextOpen("account"));
|
||||
model.AddItem(MenuCopyLinkUrl, TextCopy("account"));
|
||||
model.AddItem(MenuCopyUsername, "Copy account username");
|
||||
}
|
||||
else{
|
||||
model.AddItem((CefMenuCommand)MenuOpenLinkUrl, "Open link in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyLinkUrl, "Copy link address");
|
||||
model.AddItem(MenuOpenLinkUrl, TextOpen("link"));
|
||||
model.AddItem(MenuCopyLinkUrl, TextCopy("link"));
|
||||
}
|
||||
|
||||
model.AddSeparator();
|
||||
}
|
||||
|
||||
if ((parameters.TypeFlags.HasFlag(ContextMenuType.Media) && parameters.HasImageContents) || hasTweetImage){
|
||||
model.AddItem((CefMenuCommand)MenuOpenImageUrl, "Open image in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyImageUrl, "Copy image address");
|
||||
model.AddItem((CefMenuCommand)MenuSaveImage, "Save image as...");
|
||||
if (hasTweetVideo){
|
||||
}
|
||||
else if ((parameters.TypeFlags.HasFlag(ContextMenuType.Media) && parameters.HasImageContents) || hasTweetImage){
|
||||
model.AddItem(MenuOpenMediaUrl, TextOpen("image"));
|
||||
model.AddItem(MenuCopyMediaUrl, TextCopy("image"));
|
||||
model.AddItem(MenuSaveMedia, TextSave("image"));
|
||||
|
||||
if (lastHighlightedTweetImageList.Length > 1){
|
||||
model.AddItem((CefMenuCommand)MenuSaveAllImages, "Save all images as...");
|
||||
model.AddItem(MenuSaveTweetImages, TextSave("all images"));
|
||||
}
|
||||
|
||||
model.AddSeparator();
|
||||
@ -77,35 +93,36 @@ public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser bro
|
||||
}
|
||||
|
||||
public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags){
|
||||
switch((int)commandId){
|
||||
switch(commandId){
|
||||
case MenuOpenLinkUrl:
|
||||
BrowserUtils.OpenExternalBrowser(parameters.LinkUrl);
|
||||
break;
|
||||
|
||||
case MenuCopyLinkUrl:
|
||||
SetClipboardText(GetLink(parameters));
|
||||
break;
|
||||
|
||||
case MenuOpenImageUrl:
|
||||
BrowserUtils.OpenExternalBrowser(TwitterUtils.GetImageLink(GetImage(parameters), ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuSaveImage:
|
||||
TwitterUtils.DownloadImage(GetImage(parameters), lastHighlightedTweetAuthor, ImageQuality);
|
||||
break;
|
||||
|
||||
case MenuSaveAllImages:
|
||||
TwitterUtils.DownloadImages(lastHighlightedTweetImageList, lastHighlightedTweetAuthor, ImageQuality);
|
||||
break;
|
||||
|
||||
case MenuCopyImageUrl:
|
||||
SetClipboardText(TwitterUtils.GetImageLink(GetImage(parameters), ImageQuality));
|
||||
SetClipboardText(IsLink ? ContextInfo.Value : parameters.UnfilteredLinkUrl);
|
||||
break;
|
||||
|
||||
case MenuCopyUsername:
|
||||
Match match = TwitterUtils.RegexAccount.Match(parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(match.Success ? match.Groups[1].Value : parameters.UnfilteredLinkUrl);
|
||||
break;
|
||||
|
||||
case MenuOpenMediaUrl:
|
||||
BrowserUtils.OpenExternalBrowser(TwitterUtils.GetImageLink(GetMediaLink(parameters), ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuCopyMediaUrl:
|
||||
SetClipboardText(TwitterUtils.GetImageLink(GetMediaLink(parameters), ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuSaveMedia:
|
||||
TwitterUtils.DownloadImage(GetMediaLink(parameters), lastHighlightedTweetAuthor, ImageQuality);
|
||||
|
||||
break;
|
||||
|
||||
case MenuSaveTweetImages:
|
||||
TwitterUtils.DownloadImages(lastHighlightedTweetImageList, lastHighlightedTweetAuthor, ImageQuality);
|
||||
break;
|
||||
|
||||
case MenuOpenDevTools:
|
||||
browserControl.ShowDevTools();
|
||||
@ -116,8 +133,7 @@ public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser br
|
||||
}
|
||||
|
||||
public virtual void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame){
|
||||
TweetDeckBridge.LastRightClickedLink = string.Empty;
|
||||
TweetDeckBridge.LastRightClickedImage = string.Empty;
|
||||
ContextInfo = default(KeyValuePair<string, string>);
|
||||
}
|
||||
|
||||
public virtual bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback){
|
||||
@ -129,7 +145,7 @@ protected void SetClipboardText(string text){
|
||||
}
|
||||
|
||||
protected static void AddDebugMenuItems(IMenuModel model){
|
||||
model.AddItem((CefMenuCommand)MenuOpenDevTools, "Open dev tools");
|
||||
model.AddItem(MenuOpenDevTools, "Open dev tools");
|
||||
}
|
||||
|
||||
protected static void RemoveSeparatorIfLast(IMenuModel model){
|
||||
|
@ -6,17 +6,17 @@
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class ContextMenuBrowser : ContextMenuBase{
|
||||
private const int MenuGlobal = 26600;
|
||||
private const int MenuMute = 26601;
|
||||
private const int MenuSettings = 26602;
|
||||
private const int MenuPlugins = 26003;
|
||||
private const int MenuAbout = 26604;
|
||||
private const CefMenuCommand MenuGlobal = (CefMenuCommand)26600;
|
||||
private const CefMenuCommand MenuMute = (CefMenuCommand)26601;
|
||||
private const CefMenuCommand MenuSettings = (CefMenuCommand)26602;
|
||||
private const CefMenuCommand MenuPlugins = (CefMenuCommand)26003;
|
||||
private const CefMenuCommand MenuAbout = (CefMenuCommand)26604;
|
||||
|
||||
private const int MenuOpenTweetUrl = 26610;
|
||||
private const int MenuCopyTweetUrl = 26611;
|
||||
private const int MenuOpenQuotedTweetUrl = 26612;
|
||||
private const int MenuCopyQuotedTweetUrl = 26613;
|
||||
private const int MenuScreenshotTweet = 26614;
|
||||
private const CefMenuCommand MenuOpenTweetUrl = (CefMenuCommand)26610;
|
||||
private const CefMenuCommand MenuCopyTweetUrl = (CefMenuCommand)26611;
|
||||
private const CefMenuCommand MenuOpenQuotedTweetUrl = (CefMenuCommand)26612;
|
||||
private const CefMenuCommand MenuCopyQuotedTweetUrl = (CefMenuCommand)26613;
|
||||
private const CefMenuCommand MenuScreenshotTweet = (CefMenuCommand)26614;
|
||||
|
||||
private const string TitleReloadBrowser = "Reload browser";
|
||||
private const string TitleMuteNotifications = "Mute notifications";
|
||||
@ -55,14 +55,14 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(lastHighlightedTweet) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
||||
model.AddItem((CefMenuCommand)MenuOpenTweetUrl, "Open tweet in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
||||
model.AddItem((CefMenuCommand)MenuScreenshotTweet, "Screenshot tweet to clipboard");
|
||||
model.AddItem(MenuOpenTweetUrl, "Open tweet in browser");
|
||||
model.AddItem(MenuCopyTweetUrl, "Copy tweet address");
|
||||
model.AddItem(MenuScreenshotTweet, "Screenshot tweet to clipboard");
|
||||
|
||||
if (!string.IsNullOrEmpty(lastHighlightedQuotedTweet)){
|
||||
model.AddSeparator();
|
||||
model.AddItem((CefMenuCommand)MenuOpenQuotedTweetUrl, "Open quoted tweet in browser");
|
||||
model.AddItem((CefMenuCommand)MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||
model.AddItem(MenuOpenQuotedTweetUrl, "Open quoted tweet in browser");
|
||||
model.AddItem(MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||
}
|
||||
|
||||
model.AddSeparator();
|
||||
@ -71,16 +71,16 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
|
||||
if ((parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
||||
AddSeparator(model);
|
||||
|
||||
IMenuModel globalMenu = model.Count == 0 ? model : model.AddSubMenu((CefMenuCommand)MenuGlobal, Program.BrandName);
|
||||
IMenuModel globalMenu = model.Count == 0 ? model : model.AddSubMenu(MenuGlobal, Program.BrandName);
|
||||
|
||||
globalMenu.AddItem(CefMenuCommand.Reload, TitleReloadBrowser);
|
||||
globalMenu.AddCheckItem((CefMenuCommand)MenuMute, TitleMuteNotifications);
|
||||
globalMenu.SetChecked((CefMenuCommand)MenuMute, Program.UserConfig.MuteNotifications);
|
||||
globalMenu.AddCheckItem(MenuMute, TitleMuteNotifications);
|
||||
globalMenu.SetChecked(MenuMute, Program.UserConfig.MuteNotifications);
|
||||
globalMenu.AddSeparator();
|
||||
|
||||
globalMenu.AddItem((CefMenuCommand)MenuSettings, TitleSettings);
|
||||
globalMenu.AddItem((CefMenuCommand)MenuPlugins, TitlePlugins);
|
||||
globalMenu.AddItem((CefMenuCommand)MenuAbout, TitleAboutProgram);
|
||||
globalMenu.AddItem(MenuSettings, TitleSettings);
|
||||
globalMenu.AddItem(MenuPlugins, TitlePlugins);
|
||||
globalMenu.AddItem(MenuAbout, TitleAboutProgram);
|
||||
|
||||
if (HasDevTools){
|
||||
globalMenu.AddSeparator();
|
||||
@ -96,8 +96,8 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
|
||||
return true;
|
||||
}
|
||||
|
||||
switch((int)commandId){
|
||||
case (int)CefMenuCommand.Reload:
|
||||
switch(commandId){
|
||||
case CefMenuCommand.Reload:
|
||||
form.InvokeAsyncSafe(form.ReloadToTweetDeck);
|
||||
return true;
|
||||
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
class ContextMenuNotification : ContextMenuBase{
|
||||
private const int MenuViewDetail = 26600;
|
||||
private const int MenuSkipTweet = 26601;
|
||||
private const int MenuFreeze = 26602;
|
||||
private const int MenuCopyTweetUrl = 26603;
|
||||
private const int MenuCopyQuotedTweetUrl = 26604;
|
||||
private const CefMenuCommand MenuViewDetail = (CefMenuCommand)26600;
|
||||
private const CefMenuCommand MenuSkipTweet = (CefMenuCommand)26601;
|
||||
private const CefMenuCommand MenuFreeze = (CefMenuCommand)26602;
|
||||
private const CefMenuCommand MenuCopyTweetUrl = (CefMenuCommand)26603;
|
||||
private const CefMenuCommand MenuCopyQuotedTweetUrl = (CefMenuCommand)26604;
|
||||
|
||||
private readonly FormNotificationBase form;
|
||||
private readonly bool enableCustomMenu;
|
||||
@ -29,17 +29,17 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
|
||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||
|
||||
if (enableCustomMenu){
|
||||
model.AddItem((CefMenuCommand)MenuViewDetail, "View detail");
|
||||
model.AddItem((CefMenuCommand)MenuSkipTweet, "Skip tweet");
|
||||
model.AddCheckItem((CefMenuCommand)MenuFreeze, "Freeze");
|
||||
model.SetChecked((CefMenuCommand)MenuFreeze, form.FreezeTimer);
|
||||
model.AddSeparator();
|
||||
model.AddItem(MenuViewDetail, "View detail");
|
||||
model.AddItem(MenuSkipTweet, "Skip tweet");
|
||||
model.AddCheckItem(MenuFreeze, "Freeze");
|
||||
model.SetChecked(MenuFreeze, form.FreezeTimer);
|
||||
|
||||
if (!string.IsNullOrEmpty(form.CurrentTweetUrl)){
|
||||
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
||||
model.AddSeparator();
|
||||
model.AddItem(MenuCopyTweetUrl, "Copy tweet address");
|
||||
|
||||
if (!string.IsNullOrEmpty(form.CurrentQuoteUrl)){
|
||||
model.AddItem((CefMenuCommand)MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||
model.AddItem(MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
|
||||
return true;
|
||||
}
|
||||
|
||||
switch((int)commandId){
|
||||
switch(commandId){
|
||||
case MenuSkipTweet:
|
||||
form.InvokeAsyncSafe(form.FinishCurrentNotification);
|
||||
return true;
|
||||
|
@ -376,17 +376,16 @@
|
||||
// Block: Allow bypassing of t.co and include media previews in context menus.
|
||||
//
|
||||
$(document.body).delegate("a", "contextmenu", function(){
|
||||
$TD.setLastRightClickedLink($(this).attr("data-full-url") || "");
|
||||
});
|
||||
|
||||
$(document.body).delegate("a.js-media-image-link", "contextmenu", function(){
|
||||
let me = $(this)[0];
|
||||
|
||||
if (me.firstElementChild){
|
||||
$TD.setLastRightClickedImage(me.firstElementChild.getAttribute("src"));
|
||||
if (me.classList.contains("js-media-image-link") && highlightedTweetObj){
|
||||
let media = (highlightedTweetObj.quotedTweet || highlightedTweetObj).getMedia().find(media => media.mediaId === me.getAttribute("data-media-entity-id"));
|
||||
|
||||
$TD.setLastRightClickInfo("image", media.large());
|
||||
}
|
||||
}
|
||||
else{
|
||||
$TD.setLastRightClickedImage(me.style.backgroundImage.replace(/url\(['"]?(.*?)['"]?\)/, "$1"));
|
||||
$TD.setLastRightClickInfo("link", me.getAttribute("data-full-url"));
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user