From 69cd96a37ca2d84fc1e18c685ccd1b04bcde55f1 Mon Sep 17 00:00:00 2001 From: chylex <contact@chylex.com> Date: Tue, 22 Aug 2017 11:59:34 +0200 Subject: [PATCH] Add 'View detail' context menu item in notifications (currently loaded tweets only) --- Core/Bridge/TweetDeckBridge.cs | 4 +-- Core/FormBrowser.cs | 25 +++++++++++++++++++ Core/Handling/ContextMenuNotification.cs | 17 ++++++++----- Core/Notification/FormNotificationBase.cs | 21 +++++++++++----- .../FormNotificationScreenshotable.cs | 2 +- .../Screenshot/TweetScreenshotManager.cs | 2 +- Core/Notification/TweetNotification.cs | 16 ++++++++---- Resources/Scripts/code.js | 16 +++++++++++- 8 files changed, 81 insertions(+), 22 deletions(-) diff --git a/Core/Bridge/TweetDeckBridge.cs b/Core/Bridge/TweetDeckBridge.cs index ca141234..36409889 100644 --- a/Core/Bridge/TweetDeckBridge.cs +++ b/Core/Bridge/TweetDeckBridge.cs @@ -77,10 +77,10 @@ public void OpenContextMenu(){ form.InvokeAsyncSafe(form.OpenContextMenu); } - public void OnTweetPopup(string columnName, string tweetHtml, int tweetCharacters, string tweetUrl, string quoteUrl){ + public void OnTweetPopup(string columnKey, string chirpId, string columnName, string tweetHtml, int tweetCharacters, string tweetUrl, string quoteUrl){ notification.InvokeAsyncSafe(() => { form.OnTweetNotification(); - notification.ShowNotification(new TweetNotification(columnName, tweetHtml, tweetCharacters, tweetUrl, quoteUrl)); + notification.ShowNotification(new TweetNotification(columnKey, chirpId, columnName, tweetHtml, tweetCharacters, tweetUrl, quoteUrl)); }); } diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs index b13cb46c..eb4a57b1 100644 --- a/Core/FormBrowser.cs +++ b/Core/FormBrowser.cs @@ -542,6 +542,31 @@ public void HideVideoOverlay(){ browser.ExecuteScriptAsync("$('#td-video-player-overlay').remove()"); } + public void ShowTweetDetail(string columnKey, string chirpId){ + Activate(); + + using(IFrame frame = browser.GetBrowser().MainFrame){ + if (!TwitterUtils.IsTweetDeckWebsite(frame)){ + FormMessage.Error("View Tweet Detail", "TweetDeck is not currently loaded.", FormMessage.OK); + return; + } + } + + browser.EvaluateScriptAsync("window.TDGF_showTweetDetail", columnKey, chirpId).ContinueWith(task => { + JavascriptResponse response = task.Result; + + if (response.Success){ + switch(response.Result as int? ?? -1){ + case 0: this.InvokeAsyncSafe(notification.FinishCurrentNotification); return; + case 1: FormMessage.Error("View Tweet Detail", "The column which contained the tweet no longer exists.", FormMessage.OK); return; + case 2: FormMessage.Error("View Tweet Detail", "The tweet has been unloaded.", FormMessage.OK); return; // TODO load the tweet + } + } + + FormMessage.Error("View Tweet Detail", "An unknown error occurred when trying to view tweet detail.", FormMessage.OK); + }); + } + public void OnTweetScreenshotReady(string html, int width, int height){ if (notificationScreenshotManager == null){ notificationScreenshotManager = new TweetScreenshotManager(this, plugins); diff --git a/Core/Handling/ContextMenuNotification.cs b/Core/Handling/ContextMenuNotification.cs index 9d9f0071..a28cc789 100644 --- a/Core/Handling/ContextMenuNotification.cs +++ b/Core/Handling/ContextMenuNotification.cs @@ -4,10 +4,11 @@ namespace TweetDuck.Core.Handling{ class ContextMenuNotification : ContextMenuBase{ - private const int MenuSkipTweet = 26600; - private const int MenuFreeze = 26601; - private const int MenuCopyTweetUrl = 26602; - private const int MenuCopyQuotedTweetUrl = 26603; + 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 readonly FormNotificationBase form; private readonly bool enableCustomMenu; @@ -28,6 +29,7 @@ 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); @@ -39,12 +41,11 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br if (!string.IsNullOrEmpty(form.CurrentQuoteUrl)){ model.AddItem((CefMenuCommand)MenuCopyQuotedTweetUrl, "Copy quoted tweet address"); } - - model.AddSeparator(); } } if (HasDevTools){ + model.AddSeparator(); AddDebugMenuItems(model); } @@ -67,6 +68,10 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b form.InvokeAsyncSafe(() => form.FreezeTimer = !form.FreezeTimer); return true; + case MenuViewDetail: + form.InvokeSafe(() => form.ShowTweetDetail()); + return true; + case MenuCopyTweetUrl: SetClipboardText(form.CurrentTweetUrl); return true; diff --git a/Core/Notification/FormNotificationBase.cs b/Core/Notification/FormNotificationBase.cs index 3bbd29a4..fd1fd3f2 100644 --- a/Core/Notification/FormNotificationBase.cs +++ b/Core/Notification/FormNotificationBase.cs @@ -73,13 +73,15 @@ public bool CanResizeWindow{ protected double SizeScale => dpiScale*Program.UserConfig.ZoomMultiplier; - protected readonly Form owner; + protected readonly FormBrowser owner; protected readonly ChromiumWebBrowser browser; private readonly ResourceHandlerNotification resourceHandler = new ResourceHandlerNotification(); private readonly float dpiScale; - private string currentColumn; + private string currentColumnKey; + private string currentChirpId; + private string currentColumnTitle; private int pauseCounter; public bool IsPaused => pauseCounter > 0; @@ -91,7 +93,7 @@ public bool CanResizeWindow{ public event EventHandler Initialized; - public FormNotificationBase(Form owner, bool enableContextMenu){ + public FormNotificationBase(FormBrowser owner, bool enableContextMenu){ InitializeComponent(); this.owner = owner; @@ -158,7 +160,7 @@ public virtual void HideNotification(bool loadBlank){ } Location = ControlExtensions.InvisibleLocation; - currentColumn = null; + currentColumnTitle = null; } public virtual void FinishCurrentNotification(){} @@ -183,7 +185,10 @@ protected virtual string GetTweetHTML(TweetNotification tweet){ protected virtual void LoadTweet(TweetNotification tweet){ CurrentTweetUrl = tweet.TweetUrl; CurrentQuoteUrl = tweet.QuoteUrl; - currentColumn = tweet.Column; + + currentColumnKey = tweet.ColumnKey; + currentChirpId = tweet.ChirpId; + currentColumnTitle = tweet.ColumnTitle; resourceHandler.SetHTML(GetTweetHTML(tweet)); browser.Load(TwitterUtils.TweetDeckURL); @@ -198,7 +203,11 @@ protected virtual void OnNotificationReady(){ } protected virtual void UpdateTitle(){ - Text = string.IsNullOrEmpty(currentColumn) || !Program.UserConfig.DisplayNotificationColumn ? Program.BrandName : Program.BrandName+" - "+currentColumn; + Text = string.IsNullOrEmpty(currentColumnTitle) || !Program.UserConfig.DisplayNotificationColumn ? Program.BrandName : Program.BrandName+" - "+currentColumnTitle; + } + + public void ShowTweetDetail(){ + owner.ShowTweetDetail(currentColumnKey, currentChirpId); } public void MoveToVisibleLocation(){ diff --git a/Core/Notification/Screenshot/FormNotificationScreenshotable.cs b/Core/Notification/Screenshot/FormNotificationScreenshotable.cs index 18946020..423632c7 100644 --- a/Core/Notification/Screenshot/FormNotificationScreenshotable.cs +++ b/Core/Notification/Screenshot/FormNotificationScreenshotable.cs @@ -14,7 +14,7 @@ namespace TweetDuck.Core.Notification.Screenshot{ sealed class FormNotificationScreenshotable : FormNotificationBase{ private readonly PluginManager plugins; - public FormNotificationScreenshotable(Action callback, Form owner, PluginManager pluginManager) : base(owner, false){ + public FormNotificationScreenshotable(Action callback, FormBrowser owner, PluginManager pluginManager) : base(owner, false){ this.plugins = pluginManager; browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new CallbackBridge(this, callback)); diff --git a/Core/Notification/Screenshot/TweetScreenshotManager.cs b/Core/Notification/Screenshot/TweetScreenshotManager.cs index f6d6aafd..0aed4661 100644 --- a/Core/Notification/Screenshot/TweetScreenshotManager.cs +++ b/Core/Notification/Screenshot/TweetScreenshotManager.cs @@ -46,7 +46,7 @@ public void Trigger(string html, int width, int height){ CanMoveWindow = () => false }; - screenshot.LoadNotificationForScreenshot(new TweetNotification(string.Empty, html, 0, string.Empty, string.Empty), width, height); + screenshot.LoadNotificationForScreenshot(new TweetNotification(string.Empty, string.Empty, string.Empty, html, 0, string.Empty, string.Empty), width, height); screenshot.Show(); timeout.Start(); diff --git a/Core/Notification/TweetNotification.cs b/Core/Notification/TweetNotification.cs index ade3f23e..f48206d1 100644 --- a/Core/Notification/TweetNotification.cs +++ b/Core/Notification/TweetNotification.cs @@ -35,7 +35,7 @@ public static TweetNotification ExampleTweet{ #endif } - return new TweetNotification("Home", ExampleTweetHTML, 95, string.Empty, string.Empty, true); + return new TweetNotification(string.Empty, string.Empty, "Home", ExampleTweetHTML, 95, string.Empty, string.Empty, true); } } @@ -55,7 +55,10 @@ public enum Size{ Auto, Custom } - public string Column { get; } + public string ColumnKey { get; } + public string ChirpId { get; } + + public string ColumnTitle { get; } public string TweetUrl { get; } public string QuoteUrl { get; } @@ -63,10 +66,13 @@ public enum Size{ private readonly int characters; private readonly bool isExample; - public TweetNotification(string column, string html, int characters, string tweetUrl, string quoteUrl) : this(column, html, characters, tweetUrl, quoteUrl, false){} + public TweetNotification(string columnKey, string chirpId, string title, string html, int characters, string tweetUrl, string quoteUrl) : this(columnKey, chirpId, title, html, characters, tweetUrl, quoteUrl, false){} - private TweetNotification(string column, string html, int characters, string tweetUrl, string quoteUrl, bool isExample){ - this.Column = column; + private TweetNotification(string columnKey, string chirpId, string title, string html, int characters, string tweetUrl, string quoteUrl, bool isExample){ + this.ColumnKey = columnKey; + this.ChirpId = chirpId; + + this.ColumnTitle = title; this.TweetUrl = tweetUrl; this.QuoteUrl = quoteUrl; diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js index c9d7a110..e38fa045 100644 --- a/Resources/Scripts/code.js +++ b/Resources/Scripts/code.js @@ -199,7 +199,7 @@ let tweetUrl = source ? source.getChirpURL() : ""; let quoteUrl = source && source.quotedTweet ? source.quotedTweet.getChirpURL() : ""; - $TD.onTweetPopup(columnTypes[column.getColumnType()] || "", html.html(), duration, tweetUrl, quoteUrl); + $TD.onTweetPopup(column.model.privateState.key, tweet.id, columnTypes[column.getColumnType()] || "", html.html(), duration, tweetUrl, quoteUrl); } if (column.model.getHasSound()){ @@ -208,6 +208,20 @@ }; })(); + window.TDGF_showTweetDetail = function(columnKey, tweetId){ + let column = TD.controller.columnManager.get(columnKey); + return 1 if !column; // column no longer exists + + let chirp = column.findMostInterestingChirp(tweetId); + return 2 if !chirp; // TODO figure out -- tweet is no longer in cache + + TD.ui.updates.showDetailView(column, chirp, column.findChirp(chirp)); + TD.controller.columnManager.showColumn(columnKey); + + $(document).trigger("uiGridClearSelection"); + return 0; + }; + // // Function: Retrieves the tags to be put into <head> for notification HTML code. //