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

Add CTRL+V image paste functionality when writing tweets

Closes 
This commit is contained in:
chylex 2016-04-29 17:55:00 +02:00
parent 62cd076abb
commit fd350528a9
6 changed files with 141 additions and 3 deletions

View File

@ -9,7 +9,6 @@
using TweetDck.Resources;
using TweetDck.Core.Utils;
using TweetDck.Core.Controls;
using System.ComponentModel;
namespace TweetDck.Core{
sealed partial class FormBrowser : Form{
@ -38,7 +37,11 @@ public FormBrowser(){
bridge = new TweetDeckBridge(this);
browser = new ChromiumWebBrowser("https://tweetdeck.twitter.com/"){ MenuHandler = new ContextMenuBrowser(this) };
browser = new ChromiumWebBrowser("https://tweetdeck.twitter.com/"){
MenuHandler = new ContextMenuBrowser(this),
DialogHandler = new DialogHandlerBrowser(this)
};
browser.LoadingStateChanged += Browser_LoadingStateChanged;
browser.FrameLoadEnd += Browser_FrameLoadEnd;
browser.RegisterJsObject("$TD",bridge);
@ -215,6 +218,14 @@ public void OnTweetSound(){
}
public void OnImagePasted(){
browser.ExecuteScriptAsync("TDGF_tryPasteImage",new object[0]);
}
public void OnImagePastedFinish(){
browser.ExecuteScriptAsync("TDGF_tryPasteImageFinish",new object[0]);
}
public void BeginUpdateProcess(string versionTag, string downloadUrl){
Hide();

View File

@ -0,0 +1,26 @@
using CefSharp;
using System.Collections.Generic;
namespace TweetDck.Core.Handling{
class DialogHandlerBrowser : IDialogHandler{
private readonly FormBrowser form;
public DialogHandlerBrowser(FormBrowser form){
this.form = form;
}
public bool OnFileDialog(IWebBrowser browserControl, IBrowser browser, CefFileDialogMode mode, string title, string defaultFilePath, List<string> acceptFilters, int selectedAcceptFilter, IFileDialogCallback callback){
if (!string.IsNullOrEmpty(TweetDeckBridge.ClipboardImagePath)){
callback.Continue(selectedAcceptFilter,new List<string>{ TweetDeckBridge.ClipboardImagePath });
form.InvokeSafe(() => {
TweetDeckBridge.ClipboardImagePath = string.Empty;
});
return true;
}
return false;
}
}
}

View File

@ -1,8 +1,14 @@
using TweetDck.Core.Utils;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using TweetDck.Core.Utils;
namespace TweetDck.Core.Handling{
class TweetDeckBridge{
public static string LastRightClickedLink = string.Empty;
public static string ClipboardImagePath = string.Empty;
private readonly FormBrowser form;
@ -95,6 +101,39 @@ public void OnUpdateDismissed(string versionTag){
});
}
public void TryPasteImage(){
form.InvokeSafe(() => {
if (Clipboard.ContainsImage()){
Image img = Clipboard.GetImage();
if (img == null)return;
try{
Directory.CreateDirectory(Program.TemporaryPath);
ClipboardImagePath = Path.Combine(Program.TemporaryPath,"TD-Img-"+DateTime.Now.Ticks+".png");
img.Save(ClipboardImagePath,ImageFormat.Png);
form.OnImagePasted();
}catch(Exception e){
Program.HandleException("Could not paste image from clipboard.",e);
}
}
});
}
public void ClickUploadImage(int offsetX, int offsetY){
form.InvokeSafe(() => {
Point prevPos = Cursor.Position;
Cursor.Position = form.PointToScreen(new Point(offsetX,offsetY));
Program.mouse_event(0x02,Cursor.Position.X,Cursor.Position.Y,0,0); // MOUSEEVENTF_LEFTDOWN
Program.mouse_event(0x04,Cursor.Position.X,Cursor.Position.Y,0,0); // MOUSEEVENTF_LEFTUP
Cursor.Position = prevPos;
form.OnImagePastedFinish();
});
}
public void OpenBrowser(string url){
BrowserUtils.OpenExternalBrowser(url);
}

View File

@ -47,6 +47,9 @@ public static string LogFile{
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern bool SetWindowPos(int hWnd, int hWndOrder, int x, int y, int width, int height, uint flags);
[DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
[STAThread]
private static void Main(){
Application.EnableVisualStyles();

View File

@ -267,6 +267,64 @@
}
});
//
// Block: Paste images when tweeting.
//
(function(){
var lastPasteElement;
var clickUpload = function(){
var buttonPos = $(".js-add-image-button").first().children().first().offset(); // finds the camera icon offset
$TD.clickUploadImage(Math.floor(buttonPos.left),Math.floor(buttonPos.top));
};
$(".js-app").delegate(".js-compose-text","paste",function(e){
lastPasteElement = $(this);
$TD.tryPasteImage();
});
window.TDGF_tryPasteImage = function(){
if (lastPasteElement){
var parent = lastPasteElement.parent();
if (parent.siblings(".js-add-image-button").length === 0){
var pop = parent.closest(".js-inline-reply").find(".js-inline-compose-pop");
if (pop.length === 0){
lastPasteElement = null;
return;
}
pop.click();
var drawer = $(".js-drawer");
var counter = 0;
var interval = setInterval(function(){
if (drawer.offset().left >= 195){
clickUpload();
clearInterval(interval);
}
else if (++counter >= 10){
clearInterval(interval);
}
},51);
}
else{
clickUpload();
}
lastPasteElement = null;
}
};
window.TDGF_tryPasteImageFinish = function(){
setTimeout(function(){
$(".js-drawer").find(".js-compose-text").first()[0].focus();
},10);
};
})();
//
// Block: Inject custom CSS and layout into the page
//

View File

@ -99,6 +99,7 @@
<DependentUpon>FormNotification.cs</DependentUpon>
</Compile>
<Compile Include="Core\Handling\ContextMenuNotification.cs" />
<Compile Include="Core\Handling\DialogHandlerBrowser.cs" />
<Compile Include="Core\Handling\TweetNotification.cs" />
<Compile Include="Core\Controls\RichTextLabel.cs">
<SubType>Component</SubType>