mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-10 17:34:07 +02:00
Finish refactoring context menu structures & fix bugs from previous commits
This commit is contained in:
parent
a7d90dc708
commit
9088b8cd07
Core
@ -32,8 +32,7 @@ abstract class ContextMenuBase : IContextMenuHandler{
|
||||
private const CefMenuCommand MenuReadApplyROT13 = (CefMenuCommand)26509;
|
||||
private const CefMenuCommand MenuOpenDevTools = (CefMenuCommand)26599;
|
||||
|
||||
protected ContextInfo.LinkInfo LastLink { get; private set; }
|
||||
protected ContextInfo.ChirpInfo LastChirp { get; private set; }
|
||||
protected ContextInfo.ContextData Context { get; private set; }
|
||||
|
||||
private readonly AnalyticsFile.IProvider analytics;
|
||||
|
||||
@ -41,23 +40,12 @@ protected ContextMenuBase(AnalyticsFile.IProvider 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){
|
||||
if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
|
||||
ResetContextInfo();
|
||||
Context = TweetDeckBridge.ContextInfo.Reset();
|
||||
}
|
||||
else{
|
||||
LastLink = TweetDeckBridge.ContextInfo.Link;
|
||||
LastChirp = TweetDeckBridge.ContextInfo.Chirp;
|
||||
|
||||
if (LastLink.Type == ContextInfo.LinkType.Unknown){
|
||||
LastLink = new ContextInfo.LinkInfo(parameters);
|
||||
}
|
||||
Context = TweetDeckBridge.ContextInfo.Create(parameters);
|
||||
}
|
||||
|
||||
if (parameters.TypeFlags.HasFlag(ContextMenuType.Selection) && !parameters.TypeFlags.HasFlag(ContextMenuType.Editable)){
|
||||
@ -70,11 +58,9 @@ public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser bro
|
||||
string TextOpen(string name) => "Open "+name+" in browser";
|
||||
string TextCopy(string name) => "Copy "+name+" address";
|
||||
string TextSave(string name) => "Save "+name+" as...";
|
||||
|
||||
ContextInfo.LinkType type = LastLink.Type;
|
||||
|
||||
if (type == ContextInfo.LinkType.Generic && !LastLink.UnsafeUrl.EndsWith("tweetdeck.twitter.com/#", StringComparison.Ordinal)){
|
||||
if (TwitterUtils.RegexAccount.IsMatch(LastLink.UnsafeUrl)){
|
||||
if (Context.Types.HasFlag(ContextInfo.ContextType.Link) && !Context.UnsafeLinkUrl.EndsWith("tweetdeck.twitter.com/#", StringComparison.Ordinal)){
|
||||
if (TwitterUtils.RegexAccount.IsMatch(Context.UnsafeLinkUrl)){
|
||||
model.AddItem(MenuOpenLinkUrl, TextOpen("account"));
|
||||
model.AddItem(MenuCopyLinkUrl, TextCopy("account"));
|
||||
model.AddItem(MenuCopyUsername, "Copy account username");
|
||||
@ -86,19 +72,20 @@ public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser bro
|
||||
|
||||
model.AddSeparator();
|
||||
}
|
||||
else if (type == ContextInfo.LinkType.Video){
|
||||
|
||||
if (Context.Types.HasFlag(ContextInfo.ContextType.Video)){
|
||||
model.AddItem(MenuOpenMediaUrl, TextOpen("video"));
|
||||
model.AddItem(MenuCopyMediaUrl, TextCopy("video"));
|
||||
model.AddItem(MenuSaveMedia, TextSave("video"));
|
||||
model.AddSeparator();
|
||||
}
|
||||
else if (type == ContextInfo.LinkType.Image && LastLink.Url != TweetNotification.AppLogo.Url){
|
||||
else if (Context.Types.HasFlag(ContextInfo.ContextType.Image) && Context.MediaUrl != TweetNotification.AppLogo.Url){
|
||||
model.AddItem(MenuViewImage, "View image in photo viewer");
|
||||
model.AddItem(MenuOpenMediaUrl, TextOpen("image"));
|
||||
model.AddItem(MenuCopyMediaUrl, TextCopy("image"));
|
||||
model.AddItem(MenuSaveMedia, TextSave("image"));
|
||||
|
||||
if (LastChirp.Images.Length > 1){
|
||||
if (Context.Chirp.Images.Length > 1){
|
||||
model.AddItem(MenuSaveTweetImages, TextSave("all images"));
|
||||
}
|
||||
|
||||
@ -111,15 +98,15 @@ public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser br
|
||||
|
||||
switch(commandId){
|
||||
case MenuOpenLinkUrl:
|
||||
OpenBrowser(control, LastLink.Url);
|
||||
OpenBrowser(control, Context.LinkUrl);
|
||||
break;
|
||||
|
||||
case MenuCopyLinkUrl:
|
||||
SetClipboardText(control, LastLink.UnsafeUrl);
|
||||
SetClipboardText(control, Context.UnsafeLinkUrl);
|
||||
break;
|
||||
|
||||
case MenuCopyUsername: {
|
||||
string url = LastLink.UnsafeUrl;
|
||||
string url = Context.UnsafeLinkUrl;
|
||||
Match match = TwitterUtils.RegexAccount.Match(url);
|
||||
|
||||
SetClipboardText(control, match.Success ? match.Groups[1].Value : url);
|
||||
@ -128,11 +115,11 @@ public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser br
|
||||
}
|
||||
|
||||
case MenuOpenMediaUrl:
|
||||
OpenBrowser(control, TwitterUtils.GetMediaLink(LastLink.Url, ImageQuality));
|
||||
OpenBrowser(control, TwitterUtils.GetMediaLink(Context.MediaUrl, ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuCopyMediaUrl:
|
||||
SetClipboardText(control, TwitterUtils.GetMediaLink(LastLink.Url, ImageQuality));
|
||||
SetClipboardText(control, TwitterUtils.GetMediaLink(Context.MediaUrl, ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuViewImage: {
|
||||
@ -147,7 +134,7 @@ void ViewImage(string path){
|
||||
}
|
||||
}
|
||||
|
||||
string url = LastLink.Url;
|
||||
string url = Context.MediaUrl;
|
||||
string file = Path.Combine(BrowserCache.CacheFolder, TwitterUtils.GetImageFileName(url) ?? Path.GetRandomFileName());
|
||||
|
||||
control.InvokeAsyncSafe(() => {
|
||||
@ -169,9 +156,9 @@ void ViewImage(string path){
|
||||
}
|
||||
|
||||
case MenuSaveMedia: {
|
||||
bool isVideo = LastLink.Type == ContextInfo.LinkType.Video;
|
||||
string url = LastLink.Url;
|
||||
string username = LastChirp.Authors.LastOrDefault();
|
||||
bool isVideo = Context.Types.HasFlag(ContextInfo.ContextType.Video);
|
||||
string url = Context.MediaUrl;
|
||||
string username = Context.Chirp.Authors.LastOrDefault();
|
||||
|
||||
control.InvokeAsyncSafe(() => {
|
||||
if (isVideo){
|
||||
@ -188,8 +175,8 @@ void ViewImage(string path){
|
||||
}
|
||||
|
||||
case MenuSaveTweetImages: {
|
||||
string[] urls = LastChirp.Images;
|
||||
string username = LastChirp.Authors.LastOrDefault();
|
||||
string[] urls = Context.Chirp.Images;
|
||||
string username = Context.Chirp.Authors.LastOrDefault();
|
||||
|
||||
control.InvokeAsyncSafe(() => {
|
||||
TwitterUtils.DownloadImages(urls, username, ImageQuality);
|
||||
@ -220,7 +207,7 @@ void ViewImage(string path){
|
||||
}
|
||||
|
||||
public virtual void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame){
|
||||
ResetContextInfo();
|
||||
Context = TweetDeckBridge.ContextInfo.Reset();
|
||||
}
|
||||
|
||||
public virtual bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback){
|
||||
|
@ -1,6 +1,7 @@
|
||||
using CefSharp;
|
||||
using System.Windows.Forms;
|
||||
using TweetDuck.Core.Controls;
|
||||
using TweetDuck.Core.Management;
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
@ -56,12 +57,12 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
|
||||
InsertSelectionSearchItem(model, MenuSearchInColumn, "Search in a column");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(LastChirp.TweetUrl) && !isSelecting && !isEditing){
|
||||
if (Context.Types.HasFlag(ContextInfo.ContextType.Chirp) && !isSelecting && !isEditing){
|
||||
model.AddItem(MenuOpenTweetUrl, "Open tweet in browser");
|
||||
model.AddItem(MenuCopyTweetUrl, "Copy tweet address");
|
||||
model.AddItem(MenuScreenshotTweet, "Screenshot tweet to clipboard");
|
||||
|
||||
if (!string.IsNullOrEmpty(LastChirp.QuoteUrl)){
|
||||
if (!string.IsNullOrEmpty(Context.Chirp.QuoteUrl)){
|
||||
model.AddSeparator();
|
||||
model.AddItem(MenuOpenQuotedTweetUrl, "Open quoted tweet in browser");
|
||||
model.AddItem(MenuCopyQuotedTweetUrl, "Copy quoted tweet address");
|
||||
@ -119,11 +120,11 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
|
||||
return true;
|
||||
|
||||
case MenuOpenTweetUrl:
|
||||
OpenBrowser(form, LastChirp.TweetUrl);
|
||||
OpenBrowser(form, Context.Chirp.TweetUrl);
|
||||
return true;
|
||||
|
||||
case MenuCopyTweetUrl:
|
||||
SetClipboardText(form, LastChirp.TweetUrl);
|
||||
SetClipboardText(form, Context.Chirp.TweetUrl);
|
||||
return true;
|
||||
|
||||
case MenuScreenshotTweet:
|
||||
@ -131,11 +132,11 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
|
||||
return true;
|
||||
|
||||
case MenuOpenQuotedTweetUrl:
|
||||
OpenBrowser(form, LastChirp.QuoteUrl);
|
||||
OpenBrowser(form, Context.Chirp.QuoteUrl);
|
||||
return true;
|
||||
|
||||
case MenuCopyQuotedTweetUrl:
|
||||
SetClipboardText(form, LastChirp.QuoteUrl);
|
||||
SetClipboardText(form, Context.Chirp.QuoteUrl);
|
||||
return true;
|
||||
|
||||
case MenuWriteApplyROT13:
|
||||
|
@ -1,70 +1,54 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
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; }
|
||||
private LinkInfo link;
|
||||
private ChirpInfo? chirp;
|
||||
|
||||
public ContextInfo(){
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void SetLink(string type, string url){
|
||||
Link = string.IsNullOrEmpty(url) ? new LinkInfo() : new LinkInfo(type, url);
|
||||
link = string.IsNullOrEmpty(url) ? null : new LinkInfo(type, url);
|
||||
}
|
||||
|
||||
public void SetChirp(string tweetUrl, string quoteUrl, string chirpAuthors, string chirpImages){
|
||||
Chirp = new ChirpInfo(tweetUrl, quoteUrl, chirpAuthors, chirpImages);
|
||||
chirp = string.IsNullOrEmpty(tweetUrl) ? (ChirpInfo?)null : new ChirpInfo(tweetUrl, quoteUrl, chirpAuthors, chirpImages);
|
||||
}
|
||||
|
||||
public void Reset(){
|
||||
Link = new LinkInfo();
|
||||
Chirp = new ChirpInfo();
|
||||
public ContextData Reset(){
|
||||
link = null;
|
||||
chirp = null;
|
||||
return ContextData.Empty;
|
||||
}
|
||||
|
||||
public ContextData Create(IContextMenuParams parameters){
|
||||
ContextData.Builder builder = new ContextData.Builder();
|
||||
builder.AddContext(parameters);
|
||||
|
||||
if (link != null){
|
||||
builder.AddOverride(link.Type, link.Url);
|
||||
}
|
||||
|
||||
if (chirp.HasValue){
|
||||
builder.AddChirp(chirp.Value);
|
||||
}
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
// Data structures
|
||||
|
||||
public enum LinkType{
|
||||
Unknown, Generic, Image, Video
|
||||
}
|
||||
|
||||
public struct LinkInfo{
|
||||
public LinkType Type { get; }
|
||||
|
||||
private sealed class LinkInfo{
|
||||
public string Type { get; }
|
||||
public string Url { get; }
|
||||
public string UnsafeUrl { get; }
|
||||
|
||||
public LinkInfo(string type, string url){
|
||||
switch(type){
|
||||
case "link": Type = LinkType.Generic; break;
|
||||
case "image": Type = LinkType.Image; break;
|
||||
case "video": Type = LinkType.Video; break;
|
||||
default: Type = LinkType.Unknown; break;
|
||||
}
|
||||
|
||||
Url = url;
|
||||
UnsafeUrl = url;
|
||||
}
|
||||
|
||||
public LinkInfo(IContextMenuParams parameters){
|
||||
ContextMenuType type = parameters.TypeFlags;
|
||||
|
||||
if (type.HasFlag(ContextMenuType.Media) && parameters.HasImageContents){
|
||||
Type = LinkType.Image;
|
||||
Url = parameters.SourceUrl;
|
||||
UnsafeUrl = parameters.SourceUrl;
|
||||
}
|
||||
else if (type.HasFlag(ContextMenuType.Link)){
|
||||
Type = LinkType.Generic;
|
||||
Url = parameters.LinkUrl;
|
||||
UnsafeUrl = parameters.UnfilteredLinkUrl;
|
||||
}
|
||||
else{
|
||||
Type = LinkType.Unknown;
|
||||
Url = string.Empty;
|
||||
UnsafeUrl = string.Empty;
|
||||
}
|
||||
this.Type = type;
|
||||
this.Url = url;
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,5 +69,93 @@ public ChirpInfo(string tweetUrl, string quoteUrl, string chirpAuthors, string c
|
||||
this.chirpImages = chirpImages;
|
||||
}
|
||||
}
|
||||
|
||||
// Constructed context
|
||||
|
||||
[Flags]
|
||||
public enum ContextType{
|
||||
Unknown = 0,
|
||||
Link = 0b0001,
|
||||
Image = 0b0010,
|
||||
Video = 0b0100,
|
||||
Chirp = 0b1000
|
||||
}
|
||||
|
||||
public sealed class ContextData{
|
||||
public static readonly ContextData Empty = new Builder().Build();
|
||||
|
||||
public ContextType Types { get; }
|
||||
|
||||
public string LinkUrl { get; }
|
||||
public string UnsafeLinkUrl { get; }
|
||||
public string MediaUrl { get; }
|
||||
|
||||
public ChirpInfo Chirp { get; }
|
||||
|
||||
public ContextData(ContextType types, string linkUrl, string unsafeLinkUrl, string mediaUrl, ChirpInfo chirp){
|
||||
Types = types;
|
||||
LinkUrl = linkUrl;
|
||||
UnsafeLinkUrl = unsafeLinkUrl;
|
||||
MediaUrl = mediaUrl;
|
||||
Chirp = chirp;
|
||||
}
|
||||
|
||||
public sealed class Builder{
|
||||
private ContextType types = ContextType.Unknown;
|
||||
|
||||
private string linkUrl = string.Empty;
|
||||
private string unsafeLinkUrl = string.Empty;
|
||||
private string mediaUrl = string.Empty;
|
||||
|
||||
private ChirpInfo chirp = default(ChirpInfo);
|
||||
|
||||
public void AddContext(IContextMenuParams parameters){
|
||||
ContextMenuType flags = parameters.TypeFlags;
|
||||
|
||||
if (flags.HasFlag(ContextMenuType.Media) && parameters.HasImageContents){
|
||||
types |= ContextType.Image;
|
||||
types &= ~ContextType.Video;
|
||||
mediaUrl = parameters.SourceUrl;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(ContextMenuType.Link)){
|
||||
types |= ContextType.Link;
|
||||
linkUrl = parameters.LinkUrl;
|
||||
unsafeLinkUrl = parameters.UnfilteredLinkUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOverride(string type, string url){
|
||||
switch(type){
|
||||
case "link":
|
||||
types |= ContextType.Link;
|
||||
linkUrl = url;
|
||||
unsafeLinkUrl = url;
|
||||
break;
|
||||
|
||||
case "image":
|
||||
types |= ContextType.Image;
|
||||
types &= ~(ContextType.Video | ContextType.Link);
|
||||
mediaUrl = url;
|
||||
break;
|
||||
|
||||
case "video":
|
||||
types |= ContextType.Video;
|
||||
types &= ~(ContextType.Image | ContextType.Link);
|
||||
mediaUrl = url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddChirp(ChirpInfo chirp){
|
||||
this.types |= ContextType.Chirp;
|
||||
this.chirp = chirp;
|
||||
}
|
||||
|
||||
public ContextData Build(){
|
||||
return new ContextData(types, linkUrl, unsafeLinkUrl, mediaUrl, chirp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user