mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-28 18:15:47 +02:00
Merge pull request #85 from chylex/screenshot
Add tweet screenshot functionality & update CEF
This commit is contained in:
commit
da83d73ba6
Configuration
Core
README.mdResources/Scripts
TweetDck.csproj@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<packages xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<package id="cef.redist.x64" version="3.2785.1478" targetFramework="net452" />
|
<package id="cef.redist.x64" version="3.2785.1486" targetFramework="net452" />
|
||||||
<package id="cef.redist.x86" version="3.2785.1478" targetFramework="net452" />
|
<package id="cef.redist.x86" version="3.2785.1486" targetFramework="net452" />
|
||||||
<package id="CefSharp.Common" version="53.0.0-pre01" targetFramework="net452" />
|
<package id="CefSharp.Common" version="53.0.1" targetFramework="net452" />
|
||||||
<package id="CefSharp.WinForms" version="53.0.0-pre01" targetFramework="net452" />
|
<package id="CefSharp.WinForms" version="53.0.1" targetFramework="net452" />
|
||||||
<package id="Microsoft.VC120.CRT.JetBrains" version="12.0.21005.2" targetFramework="net452" />
|
<package id="Microsoft.VC120.CRT.JetBrains" version="12.0.21005.2" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
@ -9,6 +9,7 @@
|
|||||||
using TweetDck.Core.Controls;
|
using TweetDck.Core.Controls;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using TweetDck.Core.Utils;
|
using TweetDck.Core.Utils;
|
||||||
|
using TweetDck.Core.Utils.Notification;
|
||||||
using TweetDck.Updates;
|
using TweetDck.Updates;
|
||||||
using TweetDck.Plugins;
|
using TweetDck.Plugins;
|
||||||
using TweetDck.Plugins.Enums;
|
using TweetDck.Plugins.Enums;
|
||||||
@ -27,6 +28,7 @@ private static UserConfig Config{
|
|||||||
private readonly ChromiumWebBrowser browser;
|
private readonly ChromiumWebBrowser browser;
|
||||||
private readonly PluginManager plugins;
|
private readonly PluginManager plugins;
|
||||||
private readonly UpdateHandler updates;
|
private readonly UpdateHandler updates;
|
||||||
|
private readonly FormNotification notification;
|
||||||
|
|
||||||
private FormSettings currentFormSettings;
|
private FormSettings currentFormSettings;
|
||||||
private FormAbout currentFormAbout;
|
private FormAbout currentFormAbout;
|
||||||
@ -44,9 +46,9 @@ public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings)
|
|||||||
this.plugins.Reloaded += plugins_Reloaded;
|
this.plugins.Reloaded += plugins_Reloaded;
|
||||||
this.plugins.PluginChangedState += plugins_PluginChangedState;
|
this.plugins.PluginChangedState += plugins_PluginChangedState;
|
||||||
|
|
||||||
FormNotification notification = CreateNotificationForm(true);
|
this.notification = CreateNotificationForm(NotificationFlags.AutoHide);
|
||||||
notification.CanMoveWindow = () => false;
|
this.notification.CanMoveWindow = () => false;
|
||||||
notification.Show();
|
this.notification.Show();
|
||||||
|
|
||||||
this.browser = new ChromiumWebBrowser("https://tweetdeck.twitter.com/"){
|
this.browser = new ChromiumWebBrowser("https://tweetdeck.twitter.com/"){
|
||||||
MenuHandler = new ContextMenuBrowser(this),
|
MenuHandler = new ContextMenuBrowser(this),
|
||||||
@ -87,8 +89,8 @@ public void ForceClose(){
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FormNotification CreateNotificationForm(bool autoHide){
|
public FormNotification CreateNotificationForm(NotificationFlags flags){
|
||||||
return new FormNotification(this, plugins, autoHide);
|
return new FormNotification(this, plugins, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// window setup
|
// window setup
|
||||||
@ -291,6 +293,36 @@ public void OnTweetNotification(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnTweetScreenshotReady(string html, int width, int height){
|
||||||
|
FormNotification dummyWindow = CreateNotificationForm(NotificationFlags.DisableScripts | NotificationFlags.DisableContextMenu);
|
||||||
|
|
||||||
|
dummyWindow.ShowNotificationForScreenshot(new TweetNotification(html, string.Empty, 0), width, height, () => {
|
||||||
|
Point? prevNotificationLocation = null;
|
||||||
|
bool prevFreezeTimer = false;
|
||||||
|
|
||||||
|
if (notification.IsNotificationVisible){
|
||||||
|
prevNotificationLocation = notification.Location;
|
||||||
|
prevFreezeTimer = notification.FreezeTimer;
|
||||||
|
|
||||||
|
notification.Location = new Point(-32000, -32000);
|
||||||
|
notification.FreezeTimer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dummyWindow.TakeScreenshot();
|
||||||
|
dummyWindow.Hide();
|
||||||
|
dummyWindow.Close();
|
||||||
|
// dummyWindow.Dispose(); // TODO something freezes the program sometimes
|
||||||
|
|
||||||
|
if (prevNotificationLocation.HasValue){
|
||||||
|
notification.Location = prevNotificationLocation.Value;
|
||||||
|
notification.FreezeTimer = prevFreezeTimer;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dummyWindow.CanMoveWindow = () => false;
|
||||||
|
dummyWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
public void DisplayTooltip(string text){
|
public void DisplayTooltip(string text){
|
||||||
if (string.IsNullOrEmpty(text)){
|
if (string.IsNullOrEmpty(text)){
|
||||||
toolTip.Hide(this);
|
toolTip.Hide(this);
|
||||||
@ -310,6 +342,10 @@ public void OnImagePastedFinish(){
|
|||||||
browser.ExecuteScriptAsync("TDGF_tryPasteImageFinish()");
|
browser.ExecuteScriptAsync("TDGF_tryPasteImageFinish()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TriggerTweetScreenshot(){
|
||||||
|
browser.ExecuteScriptAsync("TDGF_triggerScreenshot()");
|
||||||
|
}
|
||||||
|
|
||||||
public void ReloadBrowser(){
|
public void ReloadBrowser(){
|
||||||
browser.ExecuteScriptAsync("window.location.reload()");
|
browser.ExecuteScriptAsync("window.location.reload()");
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
using TweetDck.Core.Handling;
|
using TweetDck.Core.Handling;
|
||||||
using TweetDck.Resources;
|
using TweetDck.Resources;
|
||||||
using TweetDck.Core.Utils;
|
using TweetDck.Core.Utils;
|
||||||
|
using TweetDck.Core.Utils.Notification;
|
||||||
using TweetDck.Plugins;
|
using TweetDck.Plugins;
|
||||||
using TweetDck.Plugins.Enums;
|
using TweetDck.Plugins.Enums;
|
||||||
|
|
||||||
@ -20,12 +21,18 @@ sealed partial class FormNotification : Form{
|
|||||||
|
|
||||||
public Func<bool> CanMoveWindow = () => true;
|
public Func<bool> CanMoveWindow = () => true;
|
||||||
|
|
||||||
|
public bool IsNotificationVisible{
|
||||||
|
get{
|
||||||
|
return Location.X != -32000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly Form owner;
|
private readonly Form owner;
|
||||||
private readonly PluginManager plugins;
|
private readonly PluginManager plugins;
|
||||||
private readonly ChromiumWebBrowser browser;
|
private readonly ChromiumWebBrowser browser;
|
||||||
|
private readonly NotificationFlags flags;
|
||||||
|
|
||||||
private readonly Queue<TweetNotification> tweetQueue = new Queue<TweetNotification>(4);
|
private readonly Queue<TweetNotification> tweetQueue = new Queue<TweetNotification>(4);
|
||||||
private readonly bool autoHide;
|
|
||||||
private int timeLeft, totalTime;
|
private int timeLeft, totalTime;
|
||||||
|
|
||||||
private readonly NativeMethods.HookProc mouseHookDelegate;
|
private readonly NativeMethods.HookProc mouseHookDelegate;
|
||||||
@ -82,22 +89,24 @@ private static int BaseClientHeight{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FormNotification(FormBrowser owner, PluginManager pluginManager, bool autoHide){
|
public FormNotification(FormBrowser owner, PluginManager pluginManager, NotificationFlags flags){
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
Text = Program.BrandName;
|
Text = Program.BrandName;
|
||||||
|
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.plugins = pluginManager;
|
this.plugins = pluginManager;
|
||||||
this.autoHide = autoHide;
|
this.flags = flags;
|
||||||
|
|
||||||
owner.FormClosed += (sender, args) => Close();
|
owner.FormClosed += (sender, args) => Close();
|
||||||
|
|
||||||
notificationJS = ScriptLoader.LoadResource(NotificationScriptFile);
|
if (!flags.HasFlag(NotificationFlags.DisableScripts)){
|
||||||
pluginJS = ScriptLoader.LoadResource(PluginManager.PluginNotificationScriptFile);
|
notificationJS = ScriptLoader.LoadResource(NotificationScriptFile);
|
||||||
|
pluginJS = ScriptLoader.LoadResource(PluginManager.PluginNotificationScriptFile);
|
||||||
|
}
|
||||||
|
|
||||||
browser = new ChromiumWebBrowser("about:blank"){
|
browser = new ChromiumWebBrowser("about:blank"){
|
||||||
MenuHandler = new ContextMenuNotification(this, autoHide),
|
MenuHandler = new ContextMenuNotification(this, !flags.HasFlag(NotificationFlags.DisableContextMenu)),
|
||||||
LifeSpanHandler = new LifeSpanHandler()
|
LifeSpanHandler = new LifeSpanHandler()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,7 +121,7 @@ public FormNotification(FormBrowser owner, PluginManager pluginManager, bool aut
|
|||||||
|
|
||||||
panelBrowser.Controls.Add(browser);
|
panelBrowser.Controls.Add(browser);
|
||||||
|
|
||||||
if (autoHide){
|
if (flags.HasFlag(NotificationFlags.AutoHide)){
|
||||||
Program.UserConfig.MuteToggled += Config_MuteToggled;
|
Program.UserConfig.MuteToggled += Config_MuteToggled;
|
||||||
Disposed += (sender, args) => Program.UserConfig.MuteToggled -= Config_MuteToggled;
|
Disposed += (sender, args) => Program.UserConfig.MuteToggled -= Config_MuteToggled;
|
||||||
}
|
}
|
||||||
@ -197,7 +206,7 @@ private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
|||||||
Initialized(this, new EventArgs());
|
Initialized(this, new EventArgs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (notificationJS != null && browser.Address != "about:blank"){
|
else if (notificationJS != null && browser.Address != "about:blank" && !flags.HasFlag(NotificationFlags.DisableScripts)){
|
||||||
ScriptLoader.ExecuteScript(e.Frame, notificationJS, NotificationScriptIdentifier);
|
ScriptLoader.ExecuteScript(e.Frame, notificationJS, NotificationScriptIdentifier);
|
||||||
|
|
||||||
if (plugins.HasAnyPlugin(PluginEnvironment.Notification)){
|
if (plugins.HasAnyPlugin(PluginEnvironment.Notification)){
|
||||||
@ -242,10 +251,35 @@ public void ShowNotificationForSettings(bool reset){
|
|||||||
LoadTweet(TweetNotification.ExampleTweet);
|
LoadTweet(TweetNotification.ExampleTweet);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
MoveToVisibleLocation();
|
PrepareAndDisplayWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ShowNotificationForScreenshot(TweetNotification tweet, int width, int height, Action callback){
|
||||||
|
browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new CallbackBridge(this, callback));
|
||||||
|
|
||||||
|
browser.FrameLoadEnd += (sender, args) => {
|
||||||
|
if (args.Frame.IsMain){
|
||||||
|
ScriptLoader.ExecuteScript(args.Frame, "window.setTimeout(() => $TD_NotificationScreenshot.trigger(), 25)", "gen:screenshot");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
browser.LoadHtml(tweet.GenerateHtml(false), "http://tweetdeck.twitter.com/?"+DateTime.Now.Ticks);
|
||||||
|
|
||||||
|
Location = new Point(-32000, -32000);
|
||||||
|
ClientSize = new Size(width, height);
|
||||||
|
progressBarTimer.Visible = false;
|
||||||
|
panelBrowser.Height = height;
|
||||||
|
|
||||||
|
// TODO start a timer on 10 seconds to close the window if anything fails or takes too long
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TakeScreenshot(){
|
||||||
|
MoveToVisibleLocation();
|
||||||
|
Activate();
|
||||||
|
SendKeys.SendWait("%{PRTSC}");
|
||||||
|
}
|
||||||
|
|
||||||
public void HideNotification(bool loadBlank){
|
public void HideNotification(bool loadBlank){
|
||||||
if (loadBlank || Program.UserConfig.NotificationLegacyLoad){
|
if (loadBlank || Program.UserConfig.NotificationLegacyLoad){
|
||||||
browser.LoadHtml("", "about:blank");
|
browser.LoadHtml("", "about:blank");
|
||||||
@ -261,7 +295,7 @@ public void HideNotification(bool loadBlank){
|
|||||||
|
|
||||||
public void OnNotificationReady(){
|
public void OnNotificationReady(){
|
||||||
UpdateTitle();
|
UpdateTitle();
|
||||||
MoveToVisibleLocation();
|
PrepareAndDisplayWindow();
|
||||||
timerProgress.Start();
|
timerProgress.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +303,7 @@ public void FinishCurrentTweet(){
|
|||||||
if (tweetQueue.Count > 0){
|
if (tweetQueue.Count > 0){
|
||||||
LoadNextNotification();
|
LoadNextNotification();
|
||||||
}
|
}
|
||||||
else if (autoHide){
|
else if (flags.HasFlag(NotificationFlags.AutoHide)){
|
||||||
HideNotification(true);
|
HideNotification(true);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -299,21 +333,6 @@ private void LoadTweet(TweetNotification tweet){
|
|||||||
private void MoveToVisibleLocation(){
|
private void MoveToVisibleLocation(){
|
||||||
UserConfig config = Program.UserConfig;
|
UserConfig config = Program.UserConfig;
|
||||||
|
|
||||||
if (RequiresResize){
|
|
||||||
RequiresResize = false;
|
|
||||||
|
|
||||||
if (config.DisplayNotificationTimer){
|
|
||||||
ClientSize = new Size(BaseClientWidth, BaseClientHeight+4);
|
|
||||||
progressBarTimer.Visible = true;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ClientSize = new Size(BaseClientWidth, BaseClientHeight);
|
|
||||||
progressBarTimer.Visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
panelBrowser.Height = BaseClientHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
Screen screen = Screen.FromControl(owner);
|
Screen screen = Screen.FromControl(owner);
|
||||||
|
|
||||||
if (config.NotificationDisplay > 0 && config.NotificationDisplay <= Screen.AllScreens.Length){
|
if (config.NotificationDisplay > 0 && config.NotificationDisplay <= Screen.AllScreens.Length){
|
||||||
@ -353,7 +372,25 @@ private void MoveToVisibleLocation(){
|
|||||||
if (needsReactivating){
|
if (needsReactivating){
|
||||||
NativeMethods.SetFormPos(this, NativeMethods.HWND_TOPMOST, NativeMethods.SWP_NOACTIVATE);
|
NativeMethods.SetFormPos(this, NativeMethods.HWND_TOPMOST, NativeMethods.SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrepareAndDisplayWindow(){
|
||||||
|
if (RequiresResize){
|
||||||
|
RequiresResize = false;
|
||||||
|
|
||||||
|
if (Program.UserConfig.DisplayNotificationTimer){
|
||||||
|
ClientSize = new Size(BaseClientWidth, BaseClientHeight+4);
|
||||||
|
progressBarTimer.Visible = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ClientSize = new Size(BaseClientWidth, BaseClientHeight);
|
||||||
|
progressBarTimer.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
panelBrowser.Height = BaseClientHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveToVisibleLocation();
|
||||||
StartMouseHook();
|
StartMouseHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ class ContextMenuBrowser : ContextMenuBase{
|
|||||||
private const int MenuCopyTweetUrl = 26611;
|
private const int MenuCopyTweetUrl = 26611;
|
||||||
private const int MenuOpenQuotedTweetUrl = 26612;
|
private const int MenuOpenQuotedTweetUrl = 26612;
|
||||||
private const int MenuCopyQuotedTweetUrl = 26613;
|
private const int MenuCopyQuotedTweetUrl = 26613;
|
||||||
|
private const int MenuScreenshotTweet = 26614;
|
||||||
|
|
||||||
private readonly FormBrowser form;
|
private readonly FormBrowser form;
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser br
|
|||||||
if (!string.IsNullOrEmpty(lastHighlightedTweet) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
if (!string.IsNullOrEmpty(lastHighlightedTweet) && (parameters.TypeFlags & (ContextMenuType.Editable | ContextMenuType.Selection)) == 0){
|
||||||
model.AddItem((CefMenuCommand)MenuOpenTweetUrl, "Open tweet in browser");
|
model.AddItem((CefMenuCommand)MenuOpenTweetUrl, "Open tweet in browser");
|
||||||
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
model.AddItem((CefMenuCommand)MenuCopyTweetUrl, "Copy tweet address");
|
||||||
|
model.AddItem((CefMenuCommand)MenuScreenshotTweet, "Screenshot tweet to clipboard");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(lastHighlightedQuotedTweet)){
|
if (!string.IsNullOrEmpty(lastHighlightedQuotedTweet)){
|
||||||
model.AddSeparator();
|
model.AddSeparator();
|
||||||
@ -109,6 +111,10 @@ public override bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser b
|
|||||||
Clipboard.SetText(lastHighlightedTweet, TextDataFormat.UnicodeText);
|
Clipboard.SetText(lastHighlightedTweet, TextDataFormat.UnicodeText);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case MenuScreenshotTweet:
|
||||||
|
form.InvokeSafe(form.TriggerTweetScreenshot);
|
||||||
|
return true;
|
||||||
|
|
||||||
case MenuOpenQuotedTweetUrl:
|
case MenuOpenQuotedTweetUrl:
|
||||||
BrowserUtils.OpenExternalBrowser(lastHighlightedQuotedTweet);
|
BrowserUtils.OpenExternalBrowser(lastHighlightedQuotedTweet);
|
||||||
return true;
|
return true;
|
||||||
|
@ -154,6 +154,10 @@ public void ClickUploadImage(int offsetX, int offsetY){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ScreenshotTweet(string html, int width, int height){
|
||||||
|
form.InvokeSafe(() => form.OnTweetScreenshotReady(html, width, height));
|
||||||
|
}
|
||||||
|
|
||||||
public void OpenBrowser(string url){
|
public void OpenBrowser(string url){
|
||||||
BrowserUtils.OpenExternalBrowser(url);
|
BrowserUtils.OpenExternalBrowser(url);
|
||||||
}
|
}
|
||||||
|
@ -99,16 +99,20 @@ public int GetDisplayDuration(int value){
|
|||||||
return 2000+Math.Max(1000, value*characters);
|
return 2000+Math.Max(1000, value*characters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateHtml(){
|
public string GenerateHtml(bool enableCustomCSS = true){
|
||||||
StringBuilder build = new StringBuilder();
|
StringBuilder build = new StringBuilder();
|
||||||
build.Append("<!DOCTYPE html>");
|
build.Append("<!DOCTYPE html>");
|
||||||
build.Append("<html class='os-windows txt-base-").Append(FontSizeClass ?? DefaultFontSizeClass).Append("'>");
|
build.Append("<html class='os-windows txt-base-").Append(FontSizeClass ?? DefaultFontSizeClass).Append("'>");
|
||||||
build.Append("<head>").Append(HeadTag ?? DefaultHeadTag).Append("<style type='text/css'>").Append(CustomCSS).Append("</style>");
|
build.Append("<head>").Append(HeadTag ?? DefaultHeadTag);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Program.UserConfig.CustomNotificationCSS)){
|
if (enableCustomCSS){
|
||||||
build.Append("<style type='text/css'>").Append(Program.UserConfig.CustomNotificationCSS).Append("</style>");
|
build.Append("<style type='text/css'>").Append(CustomCSS).Append("</style>");
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(Program.UserConfig.CustomNotificationCSS)){
|
||||||
|
build.Append("<style type='text/css'>").Append(Program.UserConfig.CustomNotificationCSS).Append("</style>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
build.Append("</head>");
|
build.Append("</head>");
|
||||||
build.Append("<body class='hearty'").Append(isExample ? " td-example-notification" : "").Append("><div class='app-columns-container'><div class='column scroll-styled-v' style='width:100%;overflow-y:auto'>");
|
build.Append("<body class='hearty'").Append(isExample ? " td-example-notification" : "").Append("><div class='app-columns-container'><div class='column scroll-styled-v' style='width:100%;overflow-y:auto'>");
|
||||||
build.Append(html);
|
build.Append(html);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using TweetDck.Core.Other.Settings;
|
using TweetDck.Core.Other.Settings;
|
||||||
|
using TweetDck.Core.Utils.Notification;
|
||||||
using TweetDck.Plugins;
|
using TweetDck.Plugins;
|
||||||
using TweetDck.Updates;
|
using TweetDck.Updates;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ public FormSettings(FormBrowser browserForm, PluginManager plugins, UpdateHandle
|
|||||||
|
|
||||||
this.tabPanel.SetupTabPanel(100);
|
this.tabPanel.SetupTabPanel(100);
|
||||||
this.tabPanel.AddButton("General", SelectTab<TabSettingsGeneral>);
|
this.tabPanel.AddButton("General", SelectTab<TabSettingsGeneral>);
|
||||||
this.tabPanel.AddButton("Notifications", () => SelectTab(() => new TabSettingsNotifications(browserForm.CreateNotificationForm(false))));
|
this.tabPanel.AddButton("Notifications", () => SelectTab(() => new TabSettingsNotifications(browserForm.CreateNotificationForm(NotificationFlags.DisableContextMenu))));
|
||||||
this.tabPanel.AddButton("Updates", () => SelectTab(() => new TabSettingsUpdates(updates)));
|
this.tabPanel.AddButton("Updates", () => SelectTab(() => new TabSettingsUpdates(updates)));
|
||||||
this.tabPanel.AddButton("Advanced", () => SelectTab(() => new TabSettingsAdvanced(browserForm.ReloadBrowser, plugins)));
|
this.tabPanel.AddButton("Advanced", () => SelectTab(() => new TabSettingsAdvanced(browserForm.ReloadBrowser, plugins)));
|
||||||
this.tabPanel.SelectTab(tabPanel.Buttons.First());
|
this.tabPanel.SelectTab(tabPanel.Buttons.First());
|
||||||
|
19
Core/Utils/Notification/CallbackBridge.cs
Normal file
19
Core/Utils/Notification/CallbackBridge.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using TweetDck.Core.Controls;
|
||||||
|
|
||||||
|
namespace TweetDck.Core.Utils.Notification{
|
||||||
|
sealed class CallbackBridge{
|
||||||
|
private readonly Control owner;
|
||||||
|
private readonly Action safeCallback;
|
||||||
|
|
||||||
|
public CallbackBridge(Control owner, Action safeCallback){
|
||||||
|
this.owner = owner;
|
||||||
|
this.safeCallback = safeCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Trigger(){
|
||||||
|
owner.InvokeSafe(safeCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Core/Utils/Notification/NotificationFlags.cs
Normal file
11
Core/Utils/Notification/NotificationFlags.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TweetDck.Core.Utils.Notification{
|
||||||
|
[Flags]
|
||||||
|
public enum NotificationFlags{
|
||||||
|
None = 0,
|
||||||
|
AutoHide = 1,
|
||||||
|
DisableScripts = 2,
|
||||||
|
DisableContextMenu = 4
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The program was build using Visual Studio 2013. After opening the solution, make sure you have **CefSharp.WinForms** and **Microsoft.VC120.CRT.JetBrains** included - if not, download them using NuGet. For **CefSharp**, you will need version 53 or newer currently available as a pre-release.
|
The program was build using Visual Studio 2013. After opening the solution, make sure you have **CefSharp.WinForms** and **Microsoft.VC120.CRT.JetBrains** included - if not, download them using NuGet. For **CefSharp**, you will need version 53 or newer currently available as a pre-release.
|
||||||
```
|
```
|
||||||
PM> Install-Package CefSharp.WinForms -Pre -Version 53.0.0-pre01
|
PM> Install-Package CefSharp.WinForms -Version 53.0.1
|
||||||
PM> Install-Package Microsoft.VC120.CRT.JetBrains
|
PM> Install-Package Microsoft.VC120.CRT.JetBrains
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -304,6 +304,30 @@
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Block: Screenshot tweet to clipboard.
|
||||||
|
//
|
||||||
|
(function(){
|
||||||
|
var selectedTweet;
|
||||||
|
|
||||||
|
app.delegate("article.js-stream-item", "contextmenu", function(){
|
||||||
|
selectedTweet = $(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.TDGF_triggerScreenshot = function(){
|
||||||
|
if (selectedTweet){
|
||||||
|
var realWidth = selectedTweet.width();
|
||||||
|
var realHeight = selectedTweet.height()-selectedTweet.find("footer").last().height();
|
||||||
|
|
||||||
|
selectedTweet = selectedTweet.clone();
|
||||||
|
selectedTweet.children().first().addClass($(document.documentElement).attr("class"));
|
||||||
|
selectedTweet.find("footer").last().remove();
|
||||||
|
|
||||||
|
$TD.screenshotTweet(selectedTweet.html(), realWidth, realHeight);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Block: Paste images when tweeting.
|
// Block: Paste images when tweeting.
|
||||||
//
|
//
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.props" Condition="Exists('packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.props')" />
|
<Import Project="packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.props" Condition="Exists('packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.props')" />
|
||||||
<Import Project="packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.props" Condition="Exists('packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.props')" />
|
<Import Project="packages\CefSharp.Common.53.0.1\build\CefSharp.Common.props" Condition="Exists('packages\CefSharp.Common.53.0.1\build\CefSharp.Common.props')" />
|
||||||
<Import Project="packages\CefSharp.WinForms.49.0.0-pre02\build\CefSharp.WinForms.props" Condition="Exists('packages\CefSharp.WinForms.49.0.0-pre02\build\CefSharp.WinForms.props')" />
|
|
||||||
<Import Project="packages\CefSharp.Common.49.0.0-pre02\build\CefSharp.Common.props" Condition="Exists('packages\CefSharp.Common.49.0.0-pre02\build\CefSharp.Common.props')" />
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@ -16,7 +14,7 @@
|
|||||||
<AssemblyName Condition=" '$(Configuration)' == 'Release' ">TweetDuck</AssemblyName>
|
<AssemblyName Condition=" '$(Configuration)' == 'Release' ">TweetDuck</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<NuGetPackageImportStamp>e83161d1</NuGetPackageImportStamp>
|
<NuGetPackageImportStamp>783c0e30</NuGetPackageImportStamp>
|
||||||
<TargetFrameworkProfile>
|
<TargetFrameworkProfile>
|
||||||
</TargetFrameworkProfile>
|
</TargetFrameworkProfile>
|
||||||
<PublishUrl>publish\</PublishUrl>
|
<PublishUrl>publish\</PublishUrl>
|
||||||
@ -176,8 +174,10 @@
|
|||||||
<Compile Include="Core\Other\Settings\TabSettingsUpdates.Designer.cs">
|
<Compile Include="Core\Other\Settings\TabSettingsUpdates.Designer.cs">
|
||||||
<DependentUpon>TabSettingsUpdates.cs</DependentUpon>
|
<DependentUpon>TabSettingsUpdates.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Core\Utils\Notification\CallbackBridge.cs" />
|
||||||
<Compile Include="Core\Utils\CommandLineArgs.cs" />
|
<Compile Include="Core\Utils\CommandLineArgs.cs" />
|
||||||
<Compile Include="Core\Utils\CommandLineArgsParser.cs" />
|
<Compile Include="Core\Utils\CommandLineArgsParser.cs" />
|
||||||
|
<Compile Include="Core\Utils\Notification\NotificationFlags.cs" />
|
||||||
<Compile Include="Core\Utils\WindowState.cs" />
|
<Compile Include="Core\Utils\WindowState.cs" />
|
||||||
<Compile Include="Core\Utils\WindowsUtils.cs" />
|
<Compile Include="Core\Utils\WindowsUtils.cs" />
|
||||||
<Compile Include="Core\Handling\TweetDeckBridge.cs" />
|
<Compile Include="Core\Handling\TweetDeckBridge.cs" />
|
||||||
@ -305,12 +305,12 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('packages\cef.redist.x86.3.2785.1478\build\cef.redist.x86.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cef.redist.x86.3.2785.1478\build\cef.redist.x86.targets'))" />
|
<Error Condition="!Exists('packages\cef.redist.x86.3.2785.1486\build\cef.redist.x86.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cef.redist.x86.3.2785.1486\build\cef.redist.x86.targets'))" />
|
||||||
<Error Condition="!Exists('packages\cef.redist.x64.3.2785.1478\build\cef.redist.x64.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cef.redist.x64.3.2785.1478\build\cef.redist.x64.targets'))" />
|
<Error Condition="!Exists('packages\cef.redist.x64.3.2785.1486\build\cef.redist.x64.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\cef.redist.x64.3.2785.1486\build\cef.redist.x64.targets'))" />
|
||||||
<Error Condition="!Exists('packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.props'))" />
|
<Error Condition="!Exists('packages\CefSharp.Common.53.0.1\build\CefSharp.Common.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.Common.53.0.1\build\CefSharp.Common.props'))" />
|
||||||
<Error Condition="!Exists('packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.targets'))" />
|
<Error Condition="!Exists('packages\CefSharp.Common.53.0.1\build\CefSharp.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.Common.53.0.1\build\CefSharp.Common.targets'))" />
|
||||||
<Error Condition="!Exists('packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.props'))" />
|
<Error Condition="!Exists('packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.props'))" />
|
||||||
<Error Condition="!Exists('packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.targets'))" />
|
<Error Condition="!Exists('packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>del "$(TargetPath).config"
|
<PostBuildEvent>del "$(TargetPath).config"
|
||||||
@ -331,10 +331,10 @@ xcopy "$(ProjectDir)Resources\Plugins\*" "$(TargetDir)plugins\official\" /E /Y
|
|||||||
rmdir "$(ProjectDir)\bin\Debug"
|
rmdir "$(ProjectDir)\bin\Debug"
|
||||||
rmdir "$(ProjectDir)\bin\Release"</PostBuildEvent>
|
rmdir "$(ProjectDir)\bin\Release"</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="packages\cef.redist.x86.3.2785.1478\build\cef.redist.x86.targets" Condition="Exists('packages\cef.redist.x86.3.2785.1478\build\cef.redist.x86.targets')" />
|
<Import Project="packages\cef.redist.x86.3.2785.1486\build\cef.redist.x86.targets" Condition="Exists('packages\cef.redist.x86.3.2785.1486\build\cef.redist.x86.targets')" />
|
||||||
<Import Project="packages\cef.redist.x64.3.2785.1478\build\cef.redist.x64.targets" Condition="Exists('packages\cef.redist.x64.3.2785.1478\build\cef.redist.x64.targets')" />
|
<Import Project="packages\cef.redist.x64.3.2785.1486\build\cef.redist.x64.targets" Condition="Exists('packages\cef.redist.x64.3.2785.1486\build\cef.redist.x64.targets')" />
|
||||||
<Import Project="packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.targets" Condition="Exists('packages\CefSharp.Common.53.0.0-pre01\build\CefSharp.Common.targets')" />
|
<Import Project="packages\CefSharp.Common.53.0.1\build\CefSharp.Common.targets" Condition="Exists('packages\CefSharp.Common.53.0.1\build\CefSharp.Common.targets')" />
|
||||||
<Import Project="packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.targets" Condition="Exists('packages\CefSharp.WinForms.53.0.0-pre01\build\CefSharp.WinForms.targets')" />
|
<Import Project="packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.targets" Condition="Exists('packages\CefSharp.WinForms.53.0.1\build\CefSharp.WinForms.targets')" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
Loading…
Reference in New Issue
Block a user