mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-09-14 10:32:10 +02:00
Compare commits
34 Commits
1.17
...
taskbar-ov
Author | SHA1 | Date | |
---|---|---|---|
9238410756 | |||
7210c29cd8 | |||
26d90c0c9b | |||
a03b222a95 | |||
7944a24d3c | |||
cc8459c759 | |||
10074ff92c | |||
173f25bebc | |||
31680fc4ae | |||
e937d43614 | |||
20e29a7975 | |||
ef815dabce | |||
1fb133e6b8 | |||
50b58cd6a6 | |||
01485d7ef9 | |||
b17c6a5ac7 | |||
d2ed2b4a00 | |||
710a7524a1 | |||
2be46464d6 | |||
8d536a6734 | |||
250d502238 | |||
e8de7266d0 | |||
9414f372d7 | |||
b0f9de67cf | |||
9b082e114e | |||
816a5334ac | |||
15a4e10da9 | |||
01b9302b0c | |||
442126a11a | |||
a9c140c0fc | |||
97ad7a3e68 | |||
7d737eefb6 | |||
4ac05b38d3 | |||
651bbbb672 |
@@ -7,6 +7,7 @@ namespace TweetDuck.Configuration{
|
|||||||
public const string ArgDataFolder = "-datafolder";
|
public const string ArgDataFolder = "-datafolder";
|
||||||
public const string ArgLogging = "-log";
|
public const string ArgLogging = "-log";
|
||||||
public const string ArgIgnoreGDPR = "-nogdpr";
|
public const string ArgIgnoreGDPR = "-nogdpr";
|
||||||
|
public const string ArgFreeze = "-freeze";
|
||||||
|
|
||||||
// internal args
|
// internal args
|
||||||
public const string ArgRestart = "-restart";
|
public const string ArgRestart = "-restart";
|
||||||
|
@@ -34,7 +34,7 @@ namespace TweetDuck.Configuration.Instance{
|
|||||||
LoadInternal(attempt > 0);
|
LoadInternal(attempt > 0);
|
||||||
|
|
||||||
if (firstException != null){ // silently log exception that caused a backup restore
|
if (firstException != null){ // silently log exception that caused a backup restore
|
||||||
Program.Reporter.Log(firstException.ToString());
|
Program.Reporter.LogImportant(firstException.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@@ -124,7 +124,7 @@ namespace TweetDuck.Configuration{
|
|||||||
try{
|
try{
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Program.Reporter.Log(e.ToString());
|
Program.Reporter.LogImportant(e.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ namespace TweetDuck.Configuration{
|
|||||||
public Size PluginsWindowSize { get; set; } = Size.Empty;
|
public Size PluginsWindowSize { get; set; } = Size.Empty;
|
||||||
|
|
||||||
public bool ExpandLinksOnHover { get; set; } = true;
|
public bool ExpandLinksOnHover { get; set; } = true;
|
||||||
|
public bool FocusDmInput { get; set; } = true;
|
||||||
public bool OpenSearchInFirstColumn { get; set; } = true;
|
public bool OpenSearchInFirstColumn { get; set; } = true;
|
||||||
public bool KeepLikeFollowDialogsOpen { get; set; } = true;
|
public bool KeepLikeFollowDialogsOpen { get; set; } = true;
|
||||||
public bool BestImageQuality { get; set; } = true;
|
public bool BestImageQuality { get; set; } = true;
|
||||||
|
@@ -17,6 +17,7 @@ namespace TweetDuck.Core.Bridge{
|
|||||||
build.Append("x.expandLinksOnHover=").Append(Bool(config.ExpandLinksOnHover));
|
build.Append("x.expandLinksOnHover=").Append(Bool(config.ExpandLinksOnHover));
|
||||||
|
|
||||||
if (environment == Environment.Browser){
|
if (environment == Environment.Browser){
|
||||||
|
build.Append("x.focusDmInput=").Append(Bool(config.FocusDmInput));
|
||||||
build.Append("x.openSearchInFirstColumn=").Append(Bool(config.OpenSearchInFirstColumn));
|
build.Append("x.openSearchInFirstColumn=").Append(Bool(config.OpenSearchInFirstColumn));
|
||||||
build.Append("x.keepLikeFollowDialogsOpen=").Append(Bool(config.KeepLikeFollowDialogsOpen));
|
build.Append("x.keepLikeFollowDialogsOpen=").Append(Bool(config.KeepLikeFollowDialogsOpen));
|
||||||
build.Append("x.muteNotifications=").Append(Bool(config.MuteNotifications));
|
build.Append("x.muteNotifications=").Append(Bool(config.MuteNotifications));
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Microsoft.WindowsAPICodePack.Taskbar;
|
||||||
using TweetDuck.Configuration;
|
using TweetDuck.Configuration;
|
||||||
using TweetDuck.Core.Bridge;
|
using TweetDuck.Core.Bridge;
|
||||||
using TweetDuck.Core.Controls;
|
using TweetDuck.Core.Controls;
|
||||||
@@ -50,6 +51,7 @@ namespace TweetDuck.Core{
|
|||||||
private readonly FormNotificationTweet notification;
|
private readonly FormNotificationTweet notification;
|
||||||
private readonly ContextMenu contextMenu;
|
private readonly ContextMenu contextMenu;
|
||||||
private readonly UpdateBridge updateBridge;
|
private readonly UpdateBridge updateBridge;
|
||||||
|
private readonly TaskbarIcon taskbarIcon;
|
||||||
|
|
||||||
private bool isLoaded;
|
private bool isLoaded;
|
||||||
private FormWindowState prevState;
|
private FormWindowState prevState;
|
||||||
@@ -84,6 +86,9 @@ namespace TweetDuck.Core{
|
|||||||
|
|
||||||
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
|
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
|
||||||
|
|
||||||
|
this.taskbarIcon = new TaskbarIcon();
|
||||||
|
Shown += (sender, args) => taskbarIcon.UpdateIcon();
|
||||||
|
|
||||||
Disposed += (sender, args) => {
|
Disposed += (sender, args) => {
|
||||||
Config.MuteToggled -= Config_MuteToggled;
|
Config.MuteToggled -= Config_MuteToggled;
|
||||||
Config.TrayBehaviorChanged -= Config_TrayBehaviorChanged;
|
Config.TrayBehaviorChanged -= Config_TrayBehaviorChanged;
|
||||||
@@ -91,6 +96,7 @@ namespace TweetDuck.Core{
|
|||||||
browser.Dispose();
|
browser.Dispose();
|
||||||
updates.Dispose();
|
updates.Dispose();
|
||||||
contextMenu.Dispose();
|
contextMenu.Dispose();
|
||||||
|
taskbarIcon.Dispose();
|
||||||
|
|
||||||
notificationScreenshotManager?.Dispose();
|
notificationScreenshotManager?.Dispose();
|
||||||
videoPlayer?.Dispose();
|
videoPlayer?.Dispose();
|
||||||
@@ -105,10 +111,6 @@ namespace TweetDuck.Core{
|
|||||||
|
|
||||||
UpdateTray();
|
UpdateTray();
|
||||||
|
|
||||||
if (Config.MuteNotifications){
|
|
||||||
UpdateFormIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.AllowDataCollection){
|
if (Config.AllowDataCollection){
|
||||||
analytics = new AnalyticsManager(this, plugins, Program.AnalyticsFilePath);
|
analytics = new AnalyticsManager(this, plugins, Program.AnalyticsFilePath);
|
||||||
}
|
}
|
||||||
@@ -134,10 +136,6 @@ namespace TweetDuck.Core{
|
|||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateFormIcon(){ // TODO fix to show icon in taskbar too
|
|
||||||
Icon = Config.MuteNotifications ? Properties.Resources.icon_muted : Properties.Resources.icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateTray(){
|
private void UpdateTray(){
|
||||||
trayIcon.Visible = Config.TrayBehavior.ShouldDisplayIcon();
|
trayIcon.Visible = Config.TrayBehavior.ShouldDisplayIcon();
|
||||||
}
|
}
|
||||||
@@ -152,6 +150,7 @@ namespace TweetDuck.Core{
|
|||||||
if (!isLoaded)return;
|
if (!isLoaded)return;
|
||||||
|
|
||||||
trayIcon.HasNotifications = false;
|
trayIcon.HasNotifications = false;
|
||||||
|
taskbarIcon.HasNotifications = false;
|
||||||
|
|
||||||
if (!browser.Enabled){ // when taking a screenshot, the window is unfocused and
|
if (!browser.Enabled){ // when taking a screenshot, the window is unfocused and
|
||||||
browser.Enabled = true; // the browser is disabled; if the user clicks back into
|
browser.Enabled = true; // the browser is disabled; if the user clicks back into
|
||||||
@@ -213,7 +212,6 @@ namespace TweetDuck.Core{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void Config_MuteToggled(object sender, EventArgs e){
|
private void Config_MuteToggled(object sender, EventArgs e){
|
||||||
UpdateFormIcon();
|
|
||||||
AnalyticsFile.NotificationMutes.Trigger();
|
AnalyticsFile.NotificationMutes.Trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,7 +492,7 @@ namespace TweetDuck.Core{
|
|||||||
FormManager.TryFind<FormSettings>()?.Close();
|
FormManager.TryFind<FormSettings>()?.Close();
|
||||||
|
|
||||||
using(DialogSettingsManage dialog = new DialogSettingsManage(plugins, true)){
|
using(DialogSettingsManage dialog = new DialogSettingsManage(plugins, true)){
|
||||||
if (dialog.ShowDialog() == DialogResult.OK && !dialog.IsRestarting){
|
if (!dialog.IsDisposed && dialog.ShowDialog() == DialogResult.OK && !dialog.IsRestarting){ // needs disposal check because the dialog may be closed in constructor
|
||||||
BrowserProcessHandler.UpdatePrefs();
|
BrowserProcessHandler.UpdatePrefs();
|
||||||
FormManager.TryFind<FormPlugins>()?.Close();
|
FormManager.TryFind<FormPlugins>()?.Close();
|
||||||
plugins.Reload(); // also reloads the browser
|
plugins.Reload(); // also reloads the browser
|
||||||
@@ -503,9 +501,13 @@ namespace TweetDuck.Core{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void OnTweetNotification(){ // may be called multiple times, once for each type of notification
|
public void OnTweetNotification(){ // may be called multiple times, once for each type of notification
|
||||||
if (Config.EnableTrayHighlight && !ContainsFocus){
|
if (!ContainsFocus){
|
||||||
|
if (Config.EnableTrayHighlight){
|
||||||
trayIcon.HasNotifications = true;
|
trayIcon.HasNotifications = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taskbarIcon.HasNotifications = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTweetSound(){
|
public void OnTweetSound(){
|
||||||
|
47
Core/Handling/KeyboardHandlerBase.cs
Normal file
47
Core/Handling/KeyboardHandlerBase.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System.Windows.Forms;
|
||||||
|
using CefSharp;
|
||||||
|
using TweetDuck.Core.Controls;
|
||||||
|
using TweetDuck.Core.Other;
|
||||||
|
using TweetDuck.Core.Utils;
|
||||||
|
|
||||||
|
namespace TweetDuck.Core.Handling{
|
||||||
|
class KeyboardHandlerBase : IKeyboardHandler{
|
||||||
|
protected virtual bool HandleRawKey(IWebBrowser browserControl, IBrowser browser, Keys key, CefEventFlags modifiers){
|
||||||
|
if (modifiers == (CefEventFlags.ControlDown | CefEventFlags.ShiftDown) && key == Keys.I){
|
||||||
|
if (BrowserUtils.HasDevTools){
|
||||||
|
browser.ShowDevTools();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
browserControl.AsControl().InvokeSafe(() => {
|
||||||
|
string extraMessage;
|
||||||
|
|
||||||
|
if (Program.IsPortable){
|
||||||
|
extraMessage = "Please download the portable installer, select the folder with your current installation of TweetDuck Portable, and tick 'Install dev tools' during the installation process.";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
extraMessage = "Please download the installer, and tick 'Install dev tools' during the installation process. The installer will automatically find and update your current installation of TweetDuck.";
|
||||||
|
}
|
||||||
|
|
||||||
|
FormMessage.Information("Dev Tools", "You do not have dev tools installed. "+extraMessage, FormMessage.OK);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IKeyboardHandler.OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut){
|
||||||
|
if (type == KeyType.RawKeyDown && !browser.FocusedFrame.Url.StartsWith("chrome-devtools://")){
|
||||||
|
return HandleRawKey(browserControl, browser, (Keys)windowsKeyCode, modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IKeyboardHandler.OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,19 +2,19 @@
|
|||||||
using CefSharp;
|
using CefSharp;
|
||||||
|
|
||||||
namespace TweetDuck.Core.Handling{
|
namespace TweetDuck.Core.Handling{
|
||||||
sealed class KeyboardHandlerBrowser : IKeyboardHandler{
|
sealed class KeyboardHandlerBrowser : KeyboardHandlerBase{
|
||||||
private readonly FormBrowser form;
|
private readonly FormBrowser form;
|
||||||
|
|
||||||
public KeyboardHandlerBrowser(FormBrowser form){
|
public KeyboardHandlerBrowser(FormBrowser form){
|
||||||
this.form = form;
|
this.form = form;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IKeyboardHandler.OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut){
|
protected override bool HandleRawKey(IWebBrowser browserControl, IBrowser browser, Keys key, CefEventFlags modifiers){
|
||||||
return type == KeyType.RawKeyDown && form.ProcessBrowserKey((Keys)windowsKeyCode);
|
if (base.HandleRawKey(browserControl, browser, key, modifiers)){
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IKeyboardHandler.OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey){
|
return form.ProcessBrowserKey(key);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ using TweetDuck.Core.Controls;
|
|||||||
using TweetDuck.Core.Notification;
|
using TweetDuck.Core.Notification;
|
||||||
|
|
||||||
namespace TweetDuck.Core.Handling {
|
namespace TweetDuck.Core.Handling {
|
||||||
sealed class KeyboardHandlerNotification : IKeyboardHandler{
|
sealed class KeyboardHandlerNotification : KeyboardHandlerBase{
|
||||||
private readonly FormNotificationBase notification;
|
private readonly FormNotificationBase notification;
|
||||||
|
|
||||||
public KeyboardHandlerNotification(FormNotificationBase notification){
|
public KeyboardHandlerNotification(FormNotificationBase notification){
|
||||||
@@ -15,9 +15,12 @@ namespace TweetDuck.Core.Handling {
|
|||||||
notification.InvokeAsyncSafe(notification.AnalyticsFile.NotificationKeyboardShortcuts.Trigger);
|
notification.InvokeAsyncSafe(notification.AnalyticsFile.NotificationKeyboardShortcuts.Trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IKeyboardHandler.OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut){
|
protected override bool HandleRawKey(IWebBrowser browserControl, IBrowser browser, Keys key, CefEventFlags modifiers){
|
||||||
if (type == KeyType.RawKeyDown && !browser.FocusedFrame.Url.StartsWith("chrome-devtools://")){
|
if (base.HandleRawKey(browserControl, browser, key, modifiers)){
|
||||||
switch((Keys)windowsKeyCode){
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(key){
|
||||||
case Keys.Enter:
|
case Keys.Enter:
|
||||||
notification.InvokeAsyncSafe(notification.FinishCurrentNotification);
|
notification.InvokeAsyncSafe(notification.FinishCurrentNotification);
|
||||||
TriggerKeyboardShortcutAnalytics();
|
TriggerKeyboardShortcutAnalytics();
|
||||||
@@ -32,14 +35,10 @@ namespace TweetDuck.Core.Handling {
|
|||||||
notification.InvokeAsyncSafe(() => notification.FreezeTimer = !notification.FreezeTimer);
|
notification.InvokeAsyncSafe(() => notification.FreezeTimer = !notification.FreezeTimer);
|
||||||
TriggerKeyboardShortcutAnalytics();
|
TriggerKeyboardShortcutAnalytics();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IKeyboardHandler.OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey){
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,45 @@
|
|||||||
// Uncomment to force TweetDeck to load a predefined version of the vendor/bundle scripts and stylesheets
|
using System;
|
||||||
// #define FREEZE_TWEETDECK_RESOURCES
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
using CefSharp.Handler;
|
using CefSharp.Handler;
|
||||||
using TweetDuck.Core.Handling.General;
|
using TweetDuck.Core.Handling.General;
|
||||||
using TweetDuck.Core.Utils;
|
using TweetDuck.Core.Utils;
|
||||||
|
|
||||||
#if FREEZE_TWEETDECK_RESOURCES
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace TweetDuck.Core.Handling{
|
namespace TweetDuck.Core.Handling{
|
||||||
class RequestHandlerBase : DefaultRequestHandler{
|
class RequestHandlerBase : DefaultRequestHandler{
|
||||||
|
private static readonly Regex TweetDeckResourceUrl = new Regex(@"/dist/(.*?)\.(.*?)\.(css|js)$", RegexOptions.Compiled);
|
||||||
|
private static readonly SortedList<string, string> TweetDeckHashes = new SortedList<string, string>(4);
|
||||||
|
|
||||||
|
public static void LoadResourceRewriteRules(string rules){
|
||||||
|
if (string.IsNullOrEmpty(rules)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TweetDeckHashes.Clear();
|
||||||
|
|
||||||
|
foreach(string rule in rules.Replace(" ", "").ToLower().Split(',')){
|
||||||
|
string[] split = rule.Split('=');
|
||||||
|
|
||||||
|
if (split.Length == 2){
|
||||||
|
string key = split[0];
|
||||||
|
string hash = split[1];
|
||||||
|
|
||||||
|
if (hash.All(chr => char.IsDigit(chr) || (chr >= 'a' && chr <= 'f'))){
|
||||||
|
TweetDeckHashes.Add(key, hash);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw new ArgumentException("Invalid hash characters: "+rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw new ArgumentException("A rule must have exactly one '=' character: "+rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly bool autoReload;
|
private readonly bool autoReload;
|
||||||
|
|
||||||
public RequestHandlerBase(bool autoReload){
|
public RequestHandlerBase(bool autoReload){
|
||||||
@@ -35,33 +60,17 @@ namespace TweetDuck.Core.Handling{
|
|||||||
return base.OnBeforeResourceLoad(browserControl, browser, frame, request, callback);
|
return base.OnBeforeResourceLoad(browserControl, browser, frame, request, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status){
|
|
||||||
if (autoReload){
|
|
||||||
browser.Reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if FREEZE_TWEETDECK_RESOURCES
|
|
||||||
private static readonly Regex TweetDeckResourceUrl = new Regex(@"/dist/(.*?)\.(.*?)\.(css|js)$", RegexOptions.Compiled);
|
|
||||||
|
|
||||||
private static readonly SortedList<string, string> TweetDeckHashes = new SortedList<string, string>(2){
|
|
||||||
{ "vendor.js", "d897f6b9ed" },
|
|
||||||
{ "bundle.js", "851d3877b9" },
|
|
||||||
{ "vendor.css", "ce7cdd10b6" },
|
|
||||||
{ "bundle.css", "c339f07047" }
|
|
||||||
};
|
|
||||||
|
|
||||||
public override bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response){
|
public override bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response){
|
||||||
if (request.ResourceType == ResourceType.Script || request.ResourceType == ResourceType.Stylesheet){
|
if ((request.ResourceType == ResourceType.Script || request.ResourceType == ResourceType.Stylesheet) && TweetDeckHashes.Count > 0){
|
||||||
string url = request.Url;
|
string url = request.Url;
|
||||||
Match match = TweetDeckResourceUrl.Match(url);
|
Match match = TweetDeckResourceUrl.Match(url);
|
||||||
|
|
||||||
if (match.Success && TweetDeckHashes.TryGetValue($"{match.Groups[1]}.{match.Groups[3]}", out string hash)){
|
if (match.Success && TweetDeckHashes.TryGetValue($"{match.Groups[1]}.{match.Groups[3]}", out string hash)){
|
||||||
if (match.Groups[2].Value == hash){
|
if (match.Groups[2].Value == hash){
|
||||||
Debug.WriteLine($"Accepting {url}");
|
Program.Reporter.LogVerbose("[RequestHandlerBase] Accepting " + url);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Debug.WriteLine($"Rewriting {url} hash to {hash}");
|
Program.Reporter.LogVerbose("[RequestHandlerBase] Replacing " + url + " hash with " + hash);
|
||||||
request.Url = TweetDeckResourceUrl.Replace(url, $"/dist/$1.{hash}.$3");
|
request.Url = TweetDeckResourceUrl.Replace(url, $"/dist/$1.{hash}.$3");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -70,6 +79,11 @@ namespace TweetDuck.Core.Handling{
|
|||||||
|
|
||||||
return base.OnResourceResponse(browserControl, browser, frame, request, response);
|
return base.OnResourceResponse(browserControl, browser, frame, request, response);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status){
|
||||||
|
if (autoReload){
|
||||||
|
browser.Reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,12 @@ namespace TweetDuck.Core.Handling{
|
|||||||
public RequestHandlerBrowser() : base(true){}
|
public RequestHandlerBrowser() : base(true){}
|
||||||
|
|
||||||
public override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback){
|
public override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback){
|
||||||
if (request.ResourceType == ResourceType.Script){
|
if (request.ResourceType == ResourceType.MainFrame){
|
||||||
|
if (request.Url.EndsWith("//twitter.com/")){
|
||||||
|
request.Url = TwitterUtils.TweetDeckURL; // redirect plain twitter.com requests, fixes bugs with login 2FA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request.ResourceType == ResourceType.Script){
|
||||||
string url = request.Url;
|
string url = request.Url;
|
||||||
|
|
||||||
if (url.Contains("analytics.")){
|
if (url.Contains("analytics.")){
|
||||||
|
@@ -40,7 +40,7 @@ namespace TweetDuck.Core.Management{
|
|||||||
|
|
||||||
if ((process = Process.Start(new ProcessStartInfo{
|
if ((process = Process.Start(new ProcessStartInfo{
|
||||||
FileName = Path.Combine(Program.ProgramPath, "TweetDuck.Video.exe"),
|
FileName = Path.Combine(Program.ProgramPath, "TweetDuck.Video.exe"),
|
||||||
Arguments = $"{owner.Handle} {Config.VideoPlayerVolume} \"{url}\" \"{pipe.GenerateToken()}\"",
|
Arguments = $"{owner.Handle} {(int)Math.Floor(100F*owner.GetDPIScale())} {Config.VideoPlayerVolume} \"{url}\" \"{pipe.GenerateToken()}\"",
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
RedirectStandardOutput = true
|
RedirectStandardOutput = true
|
||||||
})) != null){
|
})) != null){
|
||||||
@@ -135,7 +135,7 @@ namespace TweetDuck.Core.Management{
|
|||||||
|
|
||||||
private void process_OutputDataReceived(object sender, DataReceivedEventArgs e){
|
private void process_OutputDataReceived(object sender, DataReceivedEventArgs e){
|
||||||
if (!string.IsNullOrEmpty(e.Data)){
|
if (!string.IsNullOrEmpty(e.Data)){
|
||||||
Program.Reporter.Log("[VideoPlayer] "+e.Data);
|
Program.Reporter.LogVerbose("[VideoPlayer] "+e.Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -70,6 +70,7 @@ namespace TweetDuck.Core.Other{
|
|||||||
this.browser = new ChromiumWebBrowser(url){
|
this.browser = new ChromiumWebBrowser(url){
|
||||||
MenuHandler = new ContextMenuGuide(owner),
|
MenuHandler = new ContextMenuGuide(owner),
|
||||||
JsDialogHandler = new JavaScriptDialogHandler(),
|
JsDialogHandler = new JavaScriptDialogHandler(),
|
||||||
|
KeyboardHandler = new KeyboardHandlerBase(),
|
||||||
LifeSpanHandler = new LifeSpanHandler(),
|
LifeSpanHandler = new LifeSpanHandler(),
|
||||||
RequestHandler = new RequestHandlerBase(true),
|
RequestHandler = new RequestHandlerBase(true),
|
||||||
ResourceHandlerFactory = resourceHandlerFactory
|
ResourceHandlerFactory = resourceHandlerFactory
|
||||||
|
@@ -33,6 +33,7 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
|||||||
|
|
||||||
private readonly PluginManager plugins;
|
private readonly PluginManager plugins;
|
||||||
private readonly Dictionary<CheckBox, ProfileManager.Items> checkBoxMap = new Dictionary<CheckBox, ProfileManager.Items>(4);
|
private readonly Dictionary<CheckBox, ProfileManager.Items> checkBoxMap = new Dictionary<CheckBox, ProfileManager.Items>(4);
|
||||||
|
private readonly bool openImportImmediately;
|
||||||
|
|
||||||
private State currentState;
|
private State currentState;
|
||||||
private ProfileManager importManager;
|
private ProfileManager importManager;
|
||||||
@@ -51,6 +52,8 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
|||||||
this.checkBoxMap[cbSession] = ProfileManager.Items.Session;
|
this.checkBoxMap[cbSession] = ProfileManager.Items.Session;
|
||||||
this.checkBoxMap[cbPluginData] = ProfileManager.Items.PluginData;
|
this.checkBoxMap[cbPluginData] = ProfileManager.Items.PluginData;
|
||||||
|
|
||||||
|
this.openImportImmediately = openImportImmediately;
|
||||||
|
|
||||||
if (openImportImmediately){
|
if (openImportImmediately){
|
||||||
radioImport.Checked = true;
|
radioImport.Checked = true;
|
||||||
btnContinue_Click(null, EventArgs.Empty);
|
btnContinue_Click(null, EventArgs.Empty);
|
||||||
@@ -88,6 +91,10 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
|||||||
Filter = "TweetDuck Profile (*.tdsettings)|*.tdsettings"
|
Filter = "TweetDuck Profile (*.tdsettings)|*.tdsettings"
|
||||||
}){
|
}){
|
||||||
if (dialog.ShowDialog() != DialogResult.OK){
|
if (dialog.ShowDialog() != DialogResult.OK){
|
||||||
|
if (openImportImmediately){
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
Core/Other/Settings/TabSettingsGeneral.Designer.cs
generated
71
Core/Other/Settings/TabSettingsGeneral.Designer.cs
generated
@@ -39,6 +39,7 @@
|
|||||||
this.checkAnimatedAvatars = new System.Windows.Forms.CheckBox();
|
this.checkAnimatedAvatars = new System.Windows.Forms.CheckBox();
|
||||||
this.labelUpdates = new System.Windows.Forms.Label();
|
this.labelUpdates = new System.Windows.Forms.Label();
|
||||||
this.flowPanelLeft = new System.Windows.Forms.FlowLayoutPanel();
|
this.flowPanelLeft = new System.Windows.Forms.FlowLayoutPanel();
|
||||||
|
this.checkFocusDmInput = new System.Windows.Forms.CheckBox();
|
||||||
this.checkKeepLikeFollowDialogsOpen = new System.Windows.Forms.CheckBox();
|
this.checkKeepLikeFollowDialogsOpen = new System.Windows.Forms.CheckBox();
|
||||||
this.labelTray = new System.Windows.Forms.Label();
|
this.labelTray = new System.Windows.Forms.Label();
|
||||||
this.comboBoxTrayType = new System.Windows.Forms.ComboBox();
|
this.comboBoxTrayType = new System.Windows.Forms.ComboBox();
|
||||||
@@ -82,11 +83,11 @@
|
|||||||
//
|
//
|
||||||
this.checkUpdateNotifications.AutoSize = true;
|
this.checkUpdateNotifications.AutoSize = true;
|
||||||
this.checkUpdateNotifications.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.checkUpdateNotifications.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 393);
|
this.checkUpdateNotifications.Location = new System.Drawing.Point(6, 409);
|
||||||
this.checkUpdateNotifications.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
this.checkUpdateNotifications.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||||
this.checkUpdateNotifications.Name = "checkUpdateNotifications";
|
this.checkUpdateNotifications.Name = "checkUpdateNotifications";
|
||||||
this.checkUpdateNotifications.Size = new System.Drawing.Size(182, 19);
|
this.checkUpdateNotifications.Size = new System.Drawing.Size(182, 19);
|
||||||
this.checkUpdateNotifications.TabIndex = 13;
|
this.checkUpdateNotifications.TabIndex = 14;
|
||||||
this.checkUpdateNotifications.Text = "Check Updates Automatically";
|
this.checkUpdateNotifications.Text = "Check Updates Automatically";
|
||||||
this.checkUpdateNotifications.UseVisualStyleBackColor = true;
|
this.checkUpdateNotifications.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
@@ -94,12 +95,12 @@
|
|||||||
//
|
//
|
||||||
this.btnCheckUpdates.AutoSize = true;
|
this.btnCheckUpdates.AutoSize = true;
|
||||||
this.btnCheckUpdates.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.btnCheckUpdates.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.btnCheckUpdates.Location = new System.Drawing.Point(5, 417);
|
this.btnCheckUpdates.Location = new System.Drawing.Point(5, 433);
|
||||||
this.btnCheckUpdates.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
this.btnCheckUpdates.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||||
this.btnCheckUpdates.Name = "btnCheckUpdates";
|
this.btnCheckUpdates.Name = "btnCheckUpdates";
|
||||||
this.btnCheckUpdates.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
this.btnCheckUpdates.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
this.btnCheckUpdates.Size = new System.Drawing.Size(128, 25);
|
this.btnCheckUpdates.Size = new System.Drawing.Size(128, 25);
|
||||||
this.btnCheckUpdates.TabIndex = 14;
|
this.btnCheckUpdates.TabIndex = 15;
|
||||||
this.btnCheckUpdates.Text = "Check Updates Now";
|
this.btnCheckUpdates.Text = "Check Updates Now";
|
||||||
this.btnCheckUpdates.UseVisualStyleBackColor = true;
|
this.btnCheckUpdates.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
@@ -119,11 +120,11 @@
|
|||||||
//
|
//
|
||||||
this.checkBestImageQuality.AutoSize = true;
|
this.checkBestImageQuality.AutoSize = true;
|
||||||
this.checkBestImageQuality.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.checkBestImageQuality.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.checkBestImageQuality.Location = new System.Drawing.Point(6, 98);
|
this.checkBestImageQuality.Location = new System.Drawing.Point(6, 122);
|
||||||
this.checkBestImageQuality.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
this.checkBestImageQuality.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||||
this.checkBestImageQuality.Name = "checkBestImageQuality";
|
this.checkBestImageQuality.Name = "checkBestImageQuality";
|
||||||
this.checkBestImageQuality.Size = new System.Drawing.Size(125, 19);
|
this.checkBestImageQuality.Size = new System.Drawing.Size(125, 19);
|
||||||
this.checkBestImageQuality.TabIndex = 4;
|
this.checkBestImageQuality.TabIndex = 5;
|
||||||
this.checkBestImageQuality.Text = "Best Image Quality";
|
this.checkBestImageQuality.Text = "Best Image Quality";
|
||||||
this.checkBestImageQuality.UseVisualStyleBackColor = true;
|
this.checkBestImageQuality.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
@@ -131,11 +132,11 @@
|
|||||||
//
|
//
|
||||||
this.checkOpenSearchInFirstColumn.AutoSize = true;
|
this.checkOpenSearchInFirstColumn.AutoSize = true;
|
||||||
this.checkOpenSearchInFirstColumn.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.checkOpenSearchInFirstColumn.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.checkOpenSearchInFirstColumn.Location = new System.Drawing.Point(6, 50);
|
this.checkOpenSearchInFirstColumn.Location = new System.Drawing.Point(6, 74);
|
||||||
this.checkOpenSearchInFirstColumn.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
this.checkOpenSearchInFirstColumn.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||||
this.checkOpenSearchInFirstColumn.Name = "checkOpenSearchInFirstColumn";
|
this.checkOpenSearchInFirstColumn.Name = "checkOpenSearchInFirstColumn";
|
||||||
this.checkOpenSearchInFirstColumn.Size = new System.Drawing.Size(245, 19);
|
this.checkOpenSearchInFirstColumn.Size = new System.Drawing.Size(245, 19);
|
||||||
this.checkOpenSearchInFirstColumn.TabIndex = 2;
|
this.checkOpenSearchInFirstColumn.TabIndex = 3;
|
||||||
this.checkOpenSearchInFirstColumn.Text = "Add Search Columns Before First Column";
|
this.checkOpenSearchInFirstColumn.Text = "Add Search Columns Before First Column";
|
||||||
this.checkOpenSearchInFirstColumn.UseVisualStyleBackColor = true;
|
this.checkOpenSearchInFirstColumn.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
@@ -158,11 +159,11 @@
|
|||||||
//
|
//
|
||||||
this.labelZoom.AutoSize = true;
|
this.labelZoom.AutoSize = true;
|
||||||
this.labelZoom.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
|
this.labelZoom.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
|
||||||
this.labelZoom.Location = new System.Drawing.Point(3, 155);
|
this.labelZoom.Location = new System.Drawing.Point(3, 179);
|
||||||
this.labelZoom.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
this.labelZoom.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||||
this.labelZoom.Name = "labelZoom";
|
this.labelZoom.Name = "labelZoom";
|
||||||
this.labelZoom.Size = new System.Drawing.Size(39, 15);
|
this.labelZoom.Size = new System.Drawing.Size(39, 15);
|
||||||
this.labelZoom.TabIndex = 6;
|
this.labelZoom.TabIndex = 7;
|
||||||
this.labelZoom.Text = "Zoom";
|
this.labelZoom.Text = "Zoom";
|
||||||
//
|
//
|
||||||
// zoomUpdateTimer
|
// zoomUpdateTimer
|
||||||
@@ -185,21 +186,21 @@
|
|||||||
//
|
//
|
||||||
this.panelZoom.Controls.Add(this.trackBarZoom);
|
this.panelZoom.Controls.Add(this.trackBarZoom);
|
||||||
this.panelZoom.Controls.Add(this.labelZoomValue);
|
this.panelZoom.Controls.Add(this.labelZoomValue);
|
||||||
this.panelZoom.Location = new System.Drawing.Point(0, 171);
|
this.panelZoom.Location = new System.Drawing.Point(0, 195);
|
||||||
this.panelZoom.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);
|
this.panelZoom.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);
|
||||||
this.panelZoom.Name = "panelZoom";
|
this.panelZoom.Name = "panelZoom";
|
||||||
this.panelZoom.Size = new System.Drawing.Size(300, 35);
|
this.panelZoom.Size = new System.Drawing.Size(300, 35);
|
||||||
this.panelZoom.TabIndex = 7;
|
this.panelZoom.TabIndex = 8;
|
||||||
//
|
//
|
||||||
// checkAnimatedAvatars
|
// checkAnimatedAvatars
|
||||||
//
|
//
|
||||||
this.checkAnimatedAvatars.AutoSize = true;
|
this.checkAnimatedAvatars.AutoSize = true;
|
||||||
this.checkAnimatedAvatars.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.checkAnimatedAvatars.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.checkAnimatedAvatars.Location = new System.Drawing.Point(6, 122);
|
this.checkAnimatedAvatars.Location = new System.Drawing.Point(6, 146);
|
||||||
this.checkAnimatedAvatars.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
this.checkAnimatedAvatars.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||||
this.checkAnimatedAvatars.Name = "checkAnimatedAvatars";
|
this.checkAnimatedAvatars.Name = "checkAnimatedAvatars";
|
||||||
this.checkAnimatedAvatars.Size = new System.Drawing.Size(158, 19);
|
this.checkAnimatedAvatars.Size = new System.Drawing.Size(158, 19);
|
||||||
this.checkAnimatedAvatars.TabIndex = 5;
|
this.checkAnimatedAvatars.TabIndex = 6;
|
||||||
this.checkAnimatedAvatars.Text = "Enable Animated Avatars";
|
this.checkAnimatedAvatars.Text = "Enable Animated Avatars";
|
||||||
this.checkAnimatedAvatars.UseVisualStyleBackColor = true;
|
this.checkAnimatedAvatars.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
@@ -207,11 +208,11 @@
|
|||||||
//
|
//
|
||||||
this.labelUpdates.AutoSize = true;
|
this.labelUpdates.AutoSize = true;
|
||||||
this.labelUpdates.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
|
this.labelUpdates.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
|
||||||
this.labelUpdates.Location = new System.Drawing.Point(0, 367);
|
this.labelUpdates.Location = new System.Drawing.Point(0, 383);
|
||||||
this.labelUpdates.Margin = new System.Windows.Forms.Padding(0, 30, 0, 1);
|
this.labelUpdates.Margin = new System.Windows.Forms.Padding(0, 27, 0, 1);
|
||||||
this.labelUpdates.Name = "labelUpdates";
|
this.labelUpdates.Name = "labelUpdates";
|
||||||
this.labelUpdates.Size = new System.Drawing.Size(69, 19);
|
this.labelUpdates.Size = new System.Drawing.Size(69, 19);
|
||||||
this.labelUpdates.TabIndex = 12;
|
this.labelUpdates.TabIndex = 13;
|
||||||
this.labelUpdates.Text = "UPDATES";
|
this.labelUpdates.Text = "UPDATES";
|
||||||
//
|
//
|
||||||
// flowPanelLeft
|
// flowPanelLeft
|
||||||
@@ -220,6 +221,7 @@
|
|||||||
| System.Windows.Forms.AnchorStyles.Left)));
|
| System.Windows.Forms.AnchorStyles.Left)));
|
||||||
this.flowPanelLeft.Controls.Add(this.labelUI);
|
this.flowPanelLeft.Controls.Add(this.labelUI);
|
||||||
this.flowPanelLeft.Controls.Add(this.checkExpandLinks);
|
this.flowPanelLeft.Controls.Add(this.checkExpandLinks);
|
||||||
|
this.flowPanelLeft.Controls.Add(this.checkFocusDmInput);
|
||||||
this.flowPanelLeft.Controls.Add(this.checkOpenSearchInFirstColumn);
|
this.flowPanelLeft.Controls.Add(this.checkOpenSearchInFirstColumn);
|
||||||
this.flowPanelLeft.Controls.Add(this.checkKeepLikeFollowDialogsOpen);
|
this.flowPanelLeft.Controls.Add(this.checkKeepLikeFollowDialogsOpen);
|
||||||
this.flowPanelLeft.Controls.Add(this.checkBestImageQuality);
|
this.flowPanelLeft.Controls.Add(this.checkBestImageQuality);
|
||||||
@@ -240,15 +242,27 @@
|
|||||||
this.flowPanelLeft.TabIndex = 0;
|
this.flowPanelLeft.TabIndex = 0;
|
||||||
this.flowPanelLeft.WrapContents = false;
|
this.flowPanelLeft.WrapContents = false;
|
||||||
//
|
//
|
||||||
|
// checkFocusDmInput
|
||||||
|
//
|
||||||
|
this.checkFocusDmInput.AutoSize = true;
|
||||||
|
this.checkFocusDmInput.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
|
this.checkFocusDmInput.Location = new System.Drawing.Point(6, 50);
|
||||||
|
this.checkFocusDmInput.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||||
|
this.checkFocusDmInput.Name = "checkFocusDmInput";
|
||||||
|
this.checkFocusDmInput.Size = new System.Drawing.Size(282, 19);
|
||||||
|
this.checkFocusDmInput.TabIndex = 2;
|
||||||
|
this.checkFocusDmInput.Text = "Focus Input Field When Opening Direct Message";
|
||||||
|
this.checkFocusDmInput.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
// checkKeepLikeFollowDialogsOpen
|
// checkKeepLikeFollowDialogsOpen
|
||||||
//
|
//
|
||||||
this.checkKeepLikeFollowDialogsOpen.AutoSize = true;
|
this.checkKeepLikeFollowDialogsOpen.AutoSize = true;
|
||||||
this.checkKeepLikeFollowDialogsOpen.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.checkKeepLikeFollowDialogsOpen.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.checkKeepLikeFollowDialogsOpen.Location = new System.Drawing.Point(6, 74);
|
this.checkKeepLikeFollowDialogsOpen.Location = new System.Drawing.Point(6, 98);
|
||||||
this.checkKeepLikeFollowDialogsOpen.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
this.checkKeepLikeFollowDialogsOpen.Margin = new System.Windows.Forms.Padding(6, 3, 3, 2);
|
||||||
this.checkKeepLikeFollowDialogsOpen.Name = "checkKeepLikeFollowDialogsOpen";
|
this.checkKeepLikeFollowDialogsOpen.Name = "checkKeepLikeFollowDialogsOpen";
|
||||||
this.checkKeepLikeFollowDialogsOpen.Size = new System.Drawing.Size(190, 19);
|
this.checkKeepLikeFollowDialogsOpen.Size = new System.Drawing.Size(190, 19);
|
||||||
this.checkKeepLikeFollowDialogsOpen.TabIndex = 3;
|
this.checkKeepLikeFollowDialogsOpen.TabIndex = 4;
|
||||||
this.checkKeepLikeFollowDialogsOpen.Text = "Keep Like/Follow Dialogs Open";
|
this.checkKeepLikeFollowDialogsOpen.Text = "Keep Like/Follow Dialogs Open";
|
||||||
this.checkKeepLikeFollowDialogsOpen.UseVisualStyleBackColor = true;
|
this.checkKeepLikeFollowDialogsOpen.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
@@ -256,11 +270,11 @@
|
|||||||
//
|
//
|
||||||
this.labelTray.AutoSize = true;
|
this.labelTray.AutoSize = true;
|
||||||
this.labelTray.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
|
this.labelTray.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold);
|
||||||
this.labelTray.Location = new System.Drawing.Point(0, 236);
|
this.labelTray.Location = new System.Drawing.Point(0, 255);
|
||||||
this.labelTray.Margin = new System.Windows.Forms.Padding(0, 30, 0, 1);
|
this.labelTray.Margin = new System.Windows.Forms.Padding(0, 25, 0, 1);
|
||||||
this.labelTray.Name = "labelTray";
|
this.labelTray.Name = "labelTray";
|
||||||
this.labelTray.Size = new System.Drawing.Size(99, 19);
|
this.labelTray.Size = new System.Drawing.Size(99, 19);
|
||||||
this.labelTray.TabIndex = 8;
|
this.labelTray.TabIndex = 9;
|
||||||
this.labelTray.Text = "SYSTEM TRAY";
|
this.labelTray.Text = "SYSTEM TRAY";
|
||||||
//
|
//
|
||||||
// comboBoxTrayType
|
// comboBoxTrayType
|
||||||
@@ -268,32 +282,32 @@
|
|||||||
this.comboBoxTrayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
this.comboBoxTrayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.comboBoxTrayType.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.comboBoxTrayType.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.comboBoxTrayType.FormattingEnabled = true;
|
this.comboBoxTrayType.FormattingEnabled = true;
|
||||||
this.comboBoxTrayType.Location = new System.Drawing.Point(5, 260);
|
this.comboBoxTrayType.Location = new System.Drawing.Point(5, 279);
|
||||||
this.comboBoxTrayType.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
this.comboBoxTrayType.Margin = new System.Windows.Forms.Padding(5, 4, 3, 3);
|
||||||
this.comboBoxTrayType.Name = "comboBoxTrayType";
|
this.comboBoxTrayType.Name = "comboBoxTrayType";
|
||||||
this.comboBoxTrayType.Size = new System.Drawing.Size(144, 23);
|
this.comboBoxTrayType.Size = new System.Drawing.Size(144, 23);
|
||||||
this.comboBoxTrayType.TabIndex = 9;
|
this.comboBoxTrayType.TabIndex = 10;
|
||||||
//
|
//
|
||||||
// labelTrayIcon
|
// labelTrayIcon
|
||||||
//
|
//
|
||||||
this.labelTrayIcon.AutoSize = true;
|
this.labelTrayIcon.AutoSize = true;
|
||||||
this.labelTrayIcon.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
|
this.labelTrayIcon.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
|
||||||
this.labelTrayIcon.Location = new System.Drawing.Point(3, 295);
|
this.labelTrayIcon.Location = new System.Drawing.Point(3, 314);
|
||||||
this.labelTrayIcon.Margin = new System.Windows.Forms.Padding(3, 9, 3, 0);
|
this.labelTrayIcon.Margin = new System.Windows.Forms.Padding(3, 9, 3, 0);
|
||||||
this.labelTrayIcon.Name = "labelTrayIcon";
|
this.labelTrayIcon.Name = "labelTrayIcon";
|
||||||
this.labelTrayIcon.Size = new System.Drawing.Size(56, 15);
|
this.labelTrayIcon.Size = new System.Drawing.Size(56, 15);
|
||||||
this.labelTrayIcon.TabIndex = 10;
|
this.labelTrayIcon.TabIndex = 11;
|
||||||
this.labelTrayIcon.Text = "Tray Icon";
|
this.labelTrayIcon.Text = "Tray Icon";
|
||||||
//
|
//
|
||||||
// checkTrayHighlight
|
// checkTrayHighlight
|
||||||
//
|
//
|
||||||
this.checkTrayHighlight.AutoSize = true;
|
this.checkTrayHighlight.AutoSize = true;
|
||||||
this.checkTrayHighlight.Font = new System.Drawing.Font("Segoe UI", 9F);
|
this.checkTrayHighlight.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.checkTrayHighlight.Location = new System.Drawing.Point(6, 316);
|
this.checkTrayHighlight.Location = new System.Drawing.Point(6, 335);
|
||||||
this.checkTrayHighlight.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
this.checkTrayHighlight.Margin = new System.Windows.Forms.Padding(6, 6, 3, 2);
|
||||||
this.checkTrayHighlight.Name = "checkTrayHighlight";
|
this.checkTrayHighlight.Name = "checkTrayHighlight";
|
||||||
this.checkTrayHighlight.Size = new System.Drawing.Size(114, 19);
|
this.checkTrayHighlight.Size = new System.Drawing.Size(114, 19);
|
||||||
this.checkTrayHighlight.TabIndex = 11;
|
this.checkTrayHighlight.TabIndex = 12;
|
||||||
this.checkTrayHighlight.Text = "Enable Highlight";
|
this.checkTrayHighlight.Text = "Enable Highlight";
|
||||||
this.checkTrayHighlight.UseVisualStyleBackColor = true;
|
this.checkTrayHighlight.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
@@ -548,5 +562,6 @@
|
|||||||
private System.Windows.Forms.Label labelTranslationTarget;
|
private System.Windows.Forms.Label labelTranslationTarget;
|
||||||
private System.Windows.Forms.ComboBox comboBoxTranslationTarget;
|
private System.Windows.Forms.ComboBox comboBoxTranslationTarget;
|
||||||
private System.Windows.Forms.CheckBox checkHardwareAcceleration;
|
private System.Windows.Forms.CheckBox checkHardwareAcceleration;
|
||||||
|
private System.Windows.Forms.CheckBox checkFocusDmInput;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ namespace TweetDuck.Core.Other.Settings{
|
|||||||
// user interface
|
// user interface
|
||||||
|
|
||||||
toolTip.SetToolTip(checkExpandLinks, "Expands links inside the tweets. If disabled,\r\nthe full links show up in a tooltip instead.");
|
toolTip.SetToolTip(checkExpandLinks, "Expands links inside the tweets. If disabled,\r\nthe full links show up in a tooltip instead.");
|
||||||
|
toolTip.SetToolTip(checkFocusDmInput, "Places cursor into Direct Message input\r\nfield when opening a conversation.");
|
||||||
toolTip.SetToolTip(checkOpenSearchInFirstColumn, "By default, TweetDeck adds Search columns at the end.\r\nThis option makes them appear before the first column instead.");
|
toolTip.SetToolTip(checkOpenSearchInFirstColumn, "By default, TweetDeck adds Search columns at the end.\r\nThis option makes them appear before the first column instead.");
|
||||||
toolTip.SetToolTip(checkKeepLikeFollowDialogsOpen, "Allows liking and following from multiple accounts at once,\r\ninstead of automatically closing the dialog after taking an action.");
|
toolTip.SetToolTip(checkKeepLikeFollowDialogsOpen, "Allows liking and following from multiple accounts at once,\r\ninstead of automatically closing the dialog after taking an action.");
|
||||||
toolTip.SetToolTip(checkBestImageQuality, "When right-clicking a tweet image, the context menu options\r\nwill use links to the original image size (:orig in the URL).");
|
toolTip.SetToolTip(checkBestImageQuality, "When right-clicking a tweet image, the context menu options\r\nwill use links to the original image size (:orig in the URL).");
|
||||||
@@ -42,6 +43,7 @@ namespace TweetDuck.Core.Other.Settings{
|
|||||||
toolTip.SetToolTip(trackBarZoom, toolTip.GetToolTip(labelZoomValue));
|
toolTip.SetToolTip(trackBarZoom, toolTip.GetToolTip(labelZoomValue));
|
||||||
|
|
||||||
checkExpandLinks.Checked = Config.ExpandLinksOnHover;
|
checkExpandLinks.Checked = Config.ExpandLinksOnHover;
|
||||||
|
checkFocusDmInput.Checked = Config.FocusDmInput;
|
||||||
checkOpenSearchInFirstColumn.Checked = Config.OpenSearchInFirstColumn;
|
checkOpenSearchInFirstColumn.Checked = Config.OpenSearchInFirstColumn;
|
||||||
checkKeepLikeFollowDialogsOpen.Checked = Config.KeepLikeFollowDialogsOpen;
|
checkKeepLikeFollowDialogsOpen.Checked = Config.KeepLikeFollowDialogsOpen;
|
||||||
checkBestImageQuality.Checked = Config.BestImageQuality;
|
checkBestImageQuality.Checked = Config.BestImageQuality;
|
||||||
@@ -127,6 +129,7 @@ namespace TweetDuck.Core.Other.Settings{
|
|||||||
|
|
||||||
public override void OnReady(){
|
public override void OnReady(){
|
||||||
checkExpandLinks.CheckedChanged += checkExpandLinks_CheckedChanged;
|
checkExpandLinks.CheckedChanged += checkExpandLinks_CheckedChanged;
|
||||||
|
checkFocusDmInput.CheckedChanged += checkFocusDmInput_CheckedChanged;
|
||||||
checkOpenSearchInFirstColumn.CheckedChanged += checkOpenSearchInFirstColumn_CheckedChanged;
|
checkOpenSearchInFirstColumn.CheckedChanged += checkOpenSearchInFirstColumn_CheckedChanged;
|
||||||
checkKeepLikeFollowDialogsOpen.CheckedChanged += checkKeepLikeFollowDialogsOpen_CheckedChanged;
|
checkKeepLikeFollowDialogsOpen.CheckedChanged += checkKeepLikeFollowDialogsOpen_CheckedChanged;
|
||||||
checkBestImageQuality.CheckedChanged += checkBestImageQuality_CheckedChanged;
|
checkBestImageQuality.CheckedChanged += checkBestImageQuality_CheckedChanged;
|
||||||
@@ -160,6 +163,10 @@ namespace TweetDuck.Core.Other.Settings{
|
|||||||
Config.ExpandLinksOnHover = checkExpandLinks.Checked;
|
Config.ExpandLinksOnHover = checkExpandLinks.Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkFocusDmInput_CheckedChanged(object sender, EventArgs e){
|
||||||
|
Config.FocusDmInput = checkFocusDmInput.Checked;
|
||||||
|
}
|
||||||
|
|
||||||
private void checkOpenSearchInFirstColumn_CheckedChanged(object sender, EventArgs e){
|
private void checkOpenSearchInFirstColumn_CheckedChanged(object sender, EventArgs e){
|
||||||
Config.OpenSearchInFirstColumn = checkOpenSearchInFirstColumn.Checked;
|
Config.OpenSearchInFirstColumn = checkOpenSearchInFirstColumn.Checked;
|
||||||
}
|
}
|
||||||
|
49
Core/Other/TaskbarIcon.cs
Normal file
49
Core/Other/TaskbarIcon.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.WindowsAPICodePack.Taskbar;
|
||||||
|
using TweetDuck.Configuration;
|
||||||
|
using Res = TweetDuck.Properties.Resources;
|
||||||
|
|
||||||
|
namespace TweetDuck.Core.Other{
|
||||||
|
sealed class TaskbarIcon : IDisposable{
|
||||||
|
private static UserConfig Config => Program.Config.User;
|
||||||
|
|
||||||
|
public bool HasNotifications{
|
||||||
|
get{
|
||||||
|
return hasNotifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
set{
|
||||||
|
if (hasNotifications != value){
|
||||||
|
hasNotifications = value;
|
||||||
|
UpdateIcon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool hasNotifications;
|
||||||
|
|
||||||
|
public TaskbarIcon(){
|
||||||
|
Config.MuteToggled += Config_MuteToggled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose(){
|
||||||
|
Config.MuteToggled -= Config_MuteToggled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Config_MuteToggled(object sender, EventArgs e){
|
||||||
|
UpdateIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateIcon(){
|
||||||
|
if (hasNotifications){
|
||||||
|
TaskbarManager.Instance.SetOverlayIcon(Res.overlay_notification, "Unread Notifications");
|
||||||
|
}
|
||||||
|
else if (Config.MuteNotifications){
|
||||||
|
TaskbarManager.Instance.SetOverlayIcon(Res.overlay_muted, "Notifications Muted");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
TaskbarManager.Instance.SetOverlayIcon(null, string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -19,6 +19,9 @@ namespace TweetDuck.Core{
|
|||||||
sealed class TweetDeckBrowser : IDisposable{
|
sealed class TweetDeckBrowser : IDisposable{
|
||||||
private static UserConfig Config => Program.Config.User;
|
private static UserConfig Config => Program.Config.User;
|
||||||
|
|
||||||
|
private const string ErrorUrl = "http://td/error";
|
||||||
|
private const string TwitterStyleUrl = "https://abs.twimg.com/tduck/css";
|
||||||
|
|
||||||
public bool Ready { get; private set; }
|
public bool Ready { get; private set; }
|
||||||
|
|
||||||
public bool Enabled{
|
public bool Enabled{
|
||||||
@@ -119,12 +122,17 @@ namespace TweetDuck.Core{
|
|||||||
|
|
||||||
if (frame.IsMain){
|
if (frame.IsMain){
|
||||||
if (TwitterUtils.IsTwitterWebsite(frame)){
|
if (TwitterUtils.IsTwitterWebsite(frame)){
|
||||||
|
string css = ScriptLoader.LoadResource("styles/twitter.css", browser);
|
||||||
|
resourceHandlerFactory.RegisterHandler(TwitterStyleUrl, ResourceHandler.FromString(css, mimeType: "text/css"));
|
||||||
|
|
||||||
ScriptLoader.ExecuteFile(frame, "twitter.js", browser);
|
ScriptLoader.ExecuteFile(frame, "twitter.js", browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!TwitterUtils.IsTwitterLogin2FactorWebsite(frame)){
|
||||||
frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorOverride);
|
frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorOverride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||||
IFrame frame = e.Frame;
|
IFrame frame = e.Frame;
|
||||||
@@ -151,6 +159,10 @@ namespace TweetDuck.Core{
|
|||||||
|
|
||||||
ScriptLoader.ExecuteFile(frame, "update.js", browser);
|
ScriptLoader.ExecuteFile(frame, "update.js", browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame.Url == ErrorUrl){
|
||||||
|
resourceHandlerFactory.UnregisterHandler(ErrorUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void browser_LoadError(object sender, LoadErrorEventArgs e){
|
private void browser_LoadError(object sender, LoadErrorEventArgs e){
|
||||||
@@ -162,7 +174,8 @@ namespace TweetDuck.Core{
|
|||||||
string errorPage = ScriptLoader.LoadResourceSilent("pages/error.html");
|
string errorPage = ScriptLoader.LoadResourceSilent("pages/error.html");
|
||||||
|
|
||||||
if (errorPage != null){
|
if (errorPage != null){
|
||||||
browser.LoadHtml(errorPage.Replace("{err}", BrowserUtils.GetErrorName(e.ErrorCode)), "http://td/error");
|
resourceHandlerFactory.RegisterHandler(ErrorUrl, ResourceHandler.FromString(errorPage.Replace("{err}", BrowserUtils.GetErrorName(e.ErrorCode))));
|
||||||
|
browser.Load(ErrorUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,11 +30,19 @@ namespace TweetDuck.Core.Utils{
|
|||||||
|
|
||||||
public sealed class Item : IComparable<Item>{
|
public sealed class Item : IComparable<Item>{
|
||||||
public string Code { get; }
|
public string Code { get; }
|
||||||
public CultureInfo Info { get; }
|
|
||||||
|
private string Name => info?.NativeName ?? Code;
|
||||||
|
|
||||||
|
private readonly CultureInfo info;
|
||||||
|
|
||||||
public Item(string code, string alt = null){
|
public Item(string code, string alt = null){
|
||||||
this.Code = code;
|
this.Code = code;
|
||||||
this.Info = CultureInfo.GetCultureInfo(alt ?? code);
|
|
||||||
|
try{
|
||||||
|
this.info = CultureInfo.GetCultureInfo(alt ?? code);
|
||||||
|
}catch(CultureNotFoundException){
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj){
|
public override bool Equals(object obj){
|
||||||
@@ -46,12 +54,16 @@ namespace TweetDuck.Core.Utils{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString(){
|
public override string ToString(){
|
||||||
string capitalizedName = Info.TextInfo.ToTitleCase(Info.NativeName);
|
if (info == null){
|
||||||
return Info.DisplayName == Info.NativeName ? capitalizedName : $"{capitalizedName}, {Info.DisplayName}";
|
return Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
string capitalizedName = info.TextInfo.ToTitleCase(info.NativeName);
|
||||||
|
return info.DisplayName == info.NativeName ? capitalizedName : $"{capitalizedName}, {info.DisplayName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo(Item other){
|
public int CompareTo(Item other){
|
||||||
return string.Compare(Info.NativeName, other.Info.NativeName, false, CultureInfo.InvariantCulture);
|
return string.Compare(Name, other.Name, false, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ namespace TweetDuck.Core.Utils{
|
|||||||
public const string TweetDeckURL = "https://tweetdeck.twitter.com";
|
public const string TweetDeckURL = "https://tweetdeck.twitter.com";
|
||||||
|
|
||||||
public static readonly Color BackgroundColor = Color.FromArgb(28, 99, 153);
|
public static readonly Color BackgroundColor = Color.FromArgb(28, 99, 153);
|
||||||
public const string BackgroundColorOverride = "setTimeout(function f(){let h=document.head;if(!h){setTimeout(f,5);return;}let e=document.createElement('style');e.innerHTML='body,body::before{background:#1c6399!important}';h.appendChild(e);},1)";
|
public const string BackgroundColorOverride = "setTimeout(function f(){let h=document.head;if(!h){setTimeout(f,5);return;}let e=document.createElement('style');e.innerHTML='body,body::before{background:#1c6399!important;margin:0}';h.appendChild(e);},1)";
|
||||||
|
|
||||||
public static readonly ResourceLink LoadingSpinner = new ResourceLink("https://ton.twimg.com/tduck/spinner", ResourceHandler.FromByteArray(Properties.Resources.spinner, "image/apng"));
|
public static readonly ResourceLink LoadingSpinner = new ResourceLink("https://ton.twimg.com/tduck/spinner", ResourceHandler.FromByteArray(Properties.Resources.spinner, "image/apng"));
|
||||||
|
|
||||||
@@ -43,6 +43,10 @@ namespace TweetDuck.Core.Utils{
|
|||||||
return frame.Url.Contains("//twitter.com/");
|
return frame.Url.Contains("//twitter.com/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsTwitterLogin2FactorWebsite(IFrame frame){
|
||||||
|
return frame.Url.Contains("//twitter.com/account/login_verification");
|
||||||
|
}
|
||||||
|
|
||||||
private static string ExtractMediaBaseLink(string url){
|
private static string ExtractMediaBaseLink(string url){
|
||||||
int slash = url.LastIndexOf('/');
|
int slash = url.LastIndexOf('/');
|
||||||
return slash == -1 ? url : StringUtils.ExtractBefore(url, ':', slash);
|
return slash == -1 ? url : StringUtils.ExtractBefore(url, ':', slash);
|
||||||
|
10
Program.cs
10
Program.cs
@@ -9,6 +9,7 @@ using System.Threading;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using TweetDuck.Configuration;
|
using TweetDuck.Configuration;
|
||||||
using TweetDuck.Core;
|
using TweetDuck.Core;
|
||||||
|
using TweetDuck.Core.Handling;
|
||||||
using TweetDuck.Core.Handling.General;
|
using TweetDuck.Core.Handling.General;
|
||||||
using TweetDuck.Core.Other;
|
using TweetDuck.Core.Other;
|
||||||
using TweetDuck.Core.Management;
|
using TweetDuck.Core.Management;
|
||||||
@@ -20,7 +21,7 @@ namespace TweetDuck{
|
|||||||
public const string BrandName = "TweetDuck";
|
public const string BrandName = "TweetDuck";
|
||||||
public const string Website = "https://tweetduck.chylex.com";
|
public const string Website = "https://tweetduck.chylex.com";
|
||||||
|
|
||||||
public const string VersionTag = "1.17";
|
public const string VersionTag = "1.17.4";
|
||||||
|
|
||||||
public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
|
public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
public static readonly bool IsPortable = File.Exists(Path.Combine(ProgramPath, "makeportable"));
|
public static readonly bool IsPortable = File.Exists(Path.Combine(ProgramPath, "makeportable"));
|
||||||
@@ -129,6 +130,13 @@ namespace TweetDuck{
|
|||||||
BrowserCache.TryClearNow();
|
BrowserCache.TryClearNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
RequestHandlerBase.LoadResourceRewriteRules(Arguments.GetValue(Arguments.ArgFreeze, null));
|
||||||
|
}catch(Exception e){
|
||||||
|
FormMessage.Error("Resource Freeze", "Error parsing resource rewrite rules: "+e.Message, FormMessage.OK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BrowserCache.RefreshTimer();
|
BrowserCache.RefreshTimer();
|
||||||
|
|
||||||
CefSharpSettings.WcfEnabled = false;
|
CefSharpSettings.WcfEnabled = false;
|
||||||
|
22
Properties/Resources.Designer.cs
generated
22
Properties/Resources.Designer.cs
generated
@@ -19,7 +19,7 @@ namespace TweetDuck.Properties {
|
|||||||
// class via a tool like ResGen or Visual Studio.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// with the /str option, or rebuild your VS project.
|
// with the /str option, or rebuild your VS project.
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
internal class Resources {
|
internal class Resources {
|
||||||
@@ -120,6 +120,26 @@ namespace TweetDuck.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Icon overlay_muted {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("overlay_muted", resourceCulture);
|
||||||
|
return ((System.Drawing.Icon)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||||
|
/// </summary>
|
||||||
|
internal static System.Drawing.Icon overlay_notification {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("overlay_notification", resourceCulture);
|
||||||
|
return ((System.Drawing.Icon)(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Byte[].
|
/// Looks up a localized resource of type System.Byte[].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -136,6 +136,12 @@
|
|||||||
<data name="icon_tray_new" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="icon_tray_new" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\Images\icon-tray-new.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Resources\Images\icon-tray-new.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="overlay_muted" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\Images\overlay-muted.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
|
<data name="overlay_notification" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\Images\overlay-notification.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
|
</data>
|
||||||
<data name="spinner" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="spinner" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\Images\spinner.apng;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>..\Resources\Images\spinner.apng;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</data>
|
</data>
|
||||||
|
10
README.md
10
README.md
@@ -6,20 +6,20 @@
|
|||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
The program was built using Visual Studio 2017. Before opening the solution, please make sure you have the following workloads and components installed (optional components that are not listed can be deselected to save space):
|
The program can be built using Visual Studio 2017 or newer. Before opening the solution, please make sure you have the following workloads and components installed (optional components that are not listed can be deselected to save space):
|
||||||
* **.NET desktop development**
|
* **.NET desktop development**
|
||||||
* .NET Framework 4 – 4.6 development tools
|
* .NET Framework 4 – 4.6 development tools
|
||||||
* F# desktop language support
|
* F# desktop language support
|
||||||
* **Desktop development with C++**
|
* **Desktop development with C++**
|
||||||
* VC++ 2017 latest v141 tools
|
* *(VS 2017)* VC++ 2017 version 15.9 v14.16 latest v141 tools
|
||||||
|
* *(VS 2019)* MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.20)
|
||||||
|
|
||||||
After opening the solution, right-click the solution and select **Restore NuGet Packages**, or manually run this command in the **Package Manager Console**:
|
After opening the solution, right-click the solution and select **Restore NuGet Packages**, or manually run this command in the **Package Manager Console**:
|
||||||
```
|
```
|
||||||
PM> Install-Package CefSharp.WinForms -Version 67.0.0-pre01
|
PM> Install-Package CefSharp.WinForms -Version 67.0.0
|
||||||
|
PM> Install-Package WindowsAPICodePack-Shell -Version 1.1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that some pre-release builds of CefSharp are not available on NuGet. To correctly restore packages in that case, open **Package Manager Settings**, and add `https://www.myget.org/F/cefsharp/api/v3/index.json` to the list of package sources.
|
|
||||||
|
|
||||||
### Debug
|
### Debug
|
||||||
|
|
||||||
The `Debug` configuration uses a separate data folder by default (`%LOCALAPPDATA%\TweetDuckDebug`) to avoid affecting an existing installation of TweetDuck. You can modify this by opening **TweetDuck Properties** in Visual Studio, clicking the **Debug** tab, and changing the **Command line arguments** field.
|
The `Debug` configuration uses a separate data folder by default (`%LOCALAPPDATA%\TweetDuckDebug`) to avoid affecting an existing installation of TweetDuck. You can modify this by opening **TweetDuck Properties** in Visual Studio, clicking the **Debug** tab, and changing the **Command line arguments** field.
|
||||||
|
@@ -4,6 +4,7 @@ using System.Drawing;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using TweetDuck.Configuration;
|
||||||
using TweetDuck.Core.Other;
|
using TweetDuck.Core.Other;
|
||||||
|
|
||||||
namespace TweetDuck{
|
namespace TweetDuck{
|
||||||
@@ -22,7 +23,11 @@ namespace TweetDuck{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Log(string data){
|
public bool LogVerbose(string data){
|
||||||
|
return Arguments.HasFlag(Arguments.ArgLogging) && LogImportant(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool LogImportant(string data){
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Debug.WriteLine(data);
|
Debug.WriteLine(data);
|
||||||
#endif
|
#endif
|
||||||
@@ -45,7 +50,7 @@ namespace TweetDuck{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void HandleException(string caption, string message, bool canIgnore, Exception e){
|
public void HandleException(string caption, string message, bool canIgnore, Exception e){
|
||||||
bool loggedSuccessfully = Log(e.ToString());
|
bool loggedSuccessfully = LogImportant(e.ToString());
|
||||||
|
|
||||||
string exceptionText = e is ExpandedLogException ? e.Message+"\n\nDetails with potentially sensitive information are in the Error Log." : e.Message;
|
string exceptionText = e is ExpandedLogException ? e.Message+"\n\nDetails with potentially sensitive information are in the Error Log." : e.Message;
|
||||||
FormMessage form = new FormMessage(caption, message+"\nError: "+exceptionText, canIgnore ? MessageBoxIcon.Warning : MessageBoxIcon.Error);
|
FormMessage form = new FormMessage(caption, message+"\nError: "+exceptionText, canIgnore ? MessageBoxIcon.Warning : MessageBoxIcon.Error);
|
||||||
|
BIN
Resources/Design/overlay_icons.afdesign
Normal file
BIN
Resources/Design/overlay_icons.afdesign
Normal file
Binary file not shown.
BIN
Resources/Images/overlay-muted.ico
Normal file
BIN
Resources/Images/overlay-muted.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
BIN
Resources/Images/overlay-notification.ico
Normal file
BIN
Resources/Images/overlay-notification.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
@@ -87,9 +87,9 @@ enabled(){
|
|||||||
// update UI
|
// update UI
|
||||||
|
|
||||||
this.btnClearAllHTML = `
|
this.btnClearAllHTML = `
|
||||||
<a class="clear-columns-btn-all-parent js-header-action link-clean cf app-nav-link padding-h--10" data-title="Clear columns (hold Shift to restore)" data-action="td-clearcolumns-doall">
|
<a class="clear-columns-btn-all-parent js-header-action link-clean cf app-nav-link padding-h--16 padding-v--2" data-title="Clear columns (hold Shift to restore)" data-action="td-clearcolumns-doall">
|
||||||
<div class="obj-left margin-l--2"><i class="icon icon-medium icon-clear-timeline"></i></div>
|
<div class="obj-left margin-l--2"><i class="icon icon-medium icon-clear-timeline"></i></div>
|
||||||
<div class="clear-columns-btn-all nbfc padding-ts hide-condensed txt-size--16 app-nav-link-text">Clear columns</div>
|
<div class="clear-columns-btn-all nbfc padding-ts hide-condensed txt-size--14 app-nav-link-text">Clear columns</div>
|
||||||
</a>`;
|
</a>`;
|
||||||
|
|
||||||
this.btnClearOneHTML = `
|
this.btnClearOneHTML = `
|
||||||
@@ -123,6 +123,7 @@ enabled(){
|
|||||||
this.css.insert(".js-app-add-column.is-hidden + .clear-columns-btn-all-parent { display: none; }");
|
this.css.insert(".js-app-add-column.is-hidden + .clear-columns-btn-all-parent { display: none; }");
|
||||||
this.css.insert(".column-navigator-overflow .clear-columns-btn-all-parent { display: none !important; }");
|
this.css.insert(".column-navigator-overflow .clear-columns-btn-all-parent { display: none !important; }");
|
||||||
this.css.insert(".column-navigator-overflow { bottom: 224px !important; }");
|
this.css.insert(".column-navigator-overflow { bottom: 224px !important; }");
|
||||||
|
this.css.insert(".app-navigator .clear-columns-btn-all-parent { font-weight: 700; }");
|
||||||
|
|
||||||
this.css.insert(".column-header-links { min-width: 51px !important; }");
|
this.css.insert(".column-header-links { min-width: 51px !important; }");
|
||||||
this.css.insert(".column[data-td-icon='icon-message'] .column-header-links { min-width: 110px !important; }");
|
this.css.insert(".column[data-td-icon='icon-message'] .column-header-links { min-width: 110px !important; }");
|
||||||
|
@@ -800,10 +800,12 @@ html.dark .NotificationList .Notification-body{color:#14171A}
|
|||||||
html.dark .DrawerModal{color:#14171A}
|
html.dark .DrawerModal{color:#14171A}
|
||||||
/* fixes */
|
/* fixes */
|
||||||
html.dark .app-search-fake{border-color:transparent}
|
html.dark .app-search-fake{border-color:transparent}
|
||||||
html.dark .spinner-small,html.dark .spinner-large{filter:grayscale(80%)brightness(93%)}
|
html.dark .spinner-small,html.dark .spinner-large{filter:grayscale(85%)brightness(117%)}
|
||||||
html.dark .tweet>.color-twitter-blue{color:#8bd!important}
|
html.dark .tweet>.color-twitter-blue{color:#8bd!important}
|
||||||
html.dark .hw-card-container>div{border-color:#292F33;background:transparent}
|
html.dark .hw-card-container>div{border-color:#292F33;background:transparent}
|
||||||
html.dark .hw-card-container>div>div{border-color:#292F33}
|
html.dark .hw-card-container>div>div{border-color:#292F33}
|
||||||
html.dark .modal-content,html.dark .lst-group{color:#292F33}
|
html.dark .modal-content,html.dark .lst-group,html.dark #actions-modal{color:#292F33}
|
||||||
|
html.dark #actions-modal .account-link{color:#38444d}
|
||||||
|
html.dark .mdl-accent{background-color:transparent}
|
||||||
html.dark .lst-launcher a span{color:#657786!important}
|
html.dark .lst-launcher a span{color:#657786!important}
|
||||||
html.dark .social-proof-names a{color:#3b94d9}
|
html.dark .social-proof-names a{color:#3b94d9}
|
||||||
|
@@ -56,11 +56,13 @@ enabled(){
|
|||||||
this.prevComposeMustache = TD.mustaches["compose/docked_compose.mustache"];
|
this.prevComposeMustache = TD.mustaches["compose/docked_compose.mustache"];
|
||||||
window.TDPF_injectMustache("compose/docked_compose.mustache", "append", '<div class="cf margin-t--12 margin-b--30">', buttonHTML);
|
window.TDPF_injectMustache("compose/docked_compose.mustache", "append", '<div class="cf margin-t--12 margin-b--30">', buttonHTML);
|
||||||
|
|
||||||
let maybeDockedComposePanel = $(".js-docked-compose");
|
this.getDrawerInput = () => {
|
||||||
|
return $(".js-compose-text", me.composeDrawer);
|
||||||
|
};
|
||||||
|
|
||||||
if (maybeDockedComposePanel.length){
|
this.getDrawerScroller = () => {
|
||||||
maybeDockedComposePanel.find(".cf.margin-t--12.margin-b--30").first().append(buttonHTML);
|
return $(".js-compose-scroller > .scroll-v", me.composeDrawer);
|
||||||
}
|
};
|
||||||
|
|
||||||
// keyboard generation
|
// keyboard generation
|
||||||
|
|
||||||
@@ -79,12 +81,12 @@ enabled(){
|
|||||||
|
|
||||||
this.currentKeywords = [];
|
this.currentKeywords = [];
|
||||||
|
|
||||||
this.composePanelScroller.trigger("scroll");
|
this.getDrawerScroller().trigger("scroll");
|
||||||
|
|
||||||
$(".emoji-keyboard-popup-btn").removeClass("is-selected");
|
$(".emoji-keyboard-popup-btn").removeClass("is-selected");
|
||||||
|
|
||||||
if (refocus){
|
if (refocus){
|
||||||
this.composeInput.focus();
|
this.getDrawerInput().focus();
|
||||||
|
|
||||||
if (lastEmojiKeyword && lastEmojiPosition === 0){
|
if (lastEmojiKeyword && lastEmojiPosition === 0){
|
||||||
document.execCommand("insertText", false, lastEmojiKeyword);
|
document.execCommand("insertText", false, lastEmojiKeyword);
|
||||||
@@ -229,16 +231,16 @@ enabled(){
|
|||||||
this.currentSpanner.style.height = ($(this.currentKeyboard).height()-10)+"px";
|
this.currentSpanner.style.height = ($(this.currentKeyboard).height()-10)+"px";
|
||||||
$(".emoji-keyboard-popup-btn").parent().after(this.currentSpanner);
|
$(".emoji-keyboard-popup-btn").parent().after(this.currentSpanner);
|
||||||
|
|
||||||
this.composePanelScroller.trigger("scroll");
|
this.getDrawerScroller().trigger("scroll");
|
||||||
};
|
};
|
||||||
|
|
||||||
const getKeyboardTop = () => {
|
const getKeyboardTop = () => {
|
||||||
let button = $(".emoji-keyboard-popup-btn");
|
let button = $(".emoji-keyboard-popup-btn");
|
||||||
return button.offset().top+button.outerHeight()+me.composePanelScroller.scrollTop()+8;
|
return button.offset().top + button.outerHeight() + me.getDrawerScroller().scrollTop() + 8;
|
||||||
};
|
};
|
||||||
|
|
||||||
const insertEmoji = (src, alt) => {
|
const insertEmoji = (src, alt) => {
|
||||||
let input = this.composeInput;
|
let input = this.getDrawerInput();
|
||||||
|
|
||||||
let val = input.val();
|
let val = input.val();
|
||||||
let posStart = input[0].selectionStart;
|
let posStart = input[0].selectionStart;
|
||||||
@@ -378,6 +380,15 @@ enabled(){
|
|||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.drawerToggleEvent = function(e, data){
|
||||||
|
if (data.activeDrawer === "compose"){
|
||||||
|
setTimeout(function(){
|
||||||
|
$(".emoji-keyboard-popup-btn", me.composeDrawer).on("click", me.emojiKeyboardButtonClickEvent);
|
||||||
|
$(".js-docked-compose .js-compose-scroller > .scroll-v", me.composeDrawer).on("scroll", me.composerScrollEvent);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.documentClickEvent = function(e){
|
this.documentClickEvent = function(e){
|
||||||
if (me.currentKeyboard && $(e.target).closest(".compose-text-container").length === 0){
|
if (me.currentKeyboard && $(e.target).closest(".compose-text-container").length === 0){
|
||||||
hideKeyboard();
|
hideKeyboard();
|
||||||
@@ -396,20 +407,26 @@ enabled(){
|
|||||||
me.currentKeyboard.style.top = getKeyboardTop()+"px";
|
me.currentKeyboard.style.top = getKeyboardTop()+"px";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// re-enabling
|
||||||
|
|
||||||
|
let maybeDockedComposePanel = $(".js-docked-compose");
|
||||||
|
|
||||||
|
if (maybeDockedComposePanel.length){
|
||||||
|
maybeDockedComposePanel.find(".cf.margin-t--12.margin-b--30").first().append(buttonHTML);
|
||||||
|
this.drawerToggleEvent({}, { activeDrawer: "compose" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ready(){
|
ready(){
|
||||||
this.composeDrawer = $("[data-drawer='compose']");
|
this.composeDrawer = $(".js-drawer[data-drawer='compose']");
|
||||||
this.composeInput = $(".js-compose-text", ".js-docked-compose");
|
|
||||||
this.composeSelector = ".js-compose-text,.js-reply-tweetbox";
|
this.composeSelector = ".js-compose-text,.js-reply-tweetbox";
|
||||||
|
|
||||||
this.composePanelScroller = $(".js-compose-scroller", ".js-docked-compose").first().children().first();
|
|
||||||
this.composePanelScroller.on("scroll", this.composerScrollEvent);
|
|
||||||
|
|
||||||
$(".emoji-keyboard-popup-btn").on("click", this.emojiKeyboardButtonClickEvent);
|
|
||||||
$(document).on("click", this.documentClickEvent);
|
$(document).on("click", this.documentClickEvent);
|
||||||
$(document).on("keydown", this.documentKeyEvent);
|
$(document).on("keydown", this.documentKeyEvent);
|
||||||
|
$(document).on("uiDrawerActive", this.drawerToggleEvent);
|
||||||
$(document).on("uiComposeImageAdded", this.uploadFilesEvent);
|
$(document).on("uiComposeImageAdded", this.uploadFilesEvent);
|
||||||
|
|
||||||
this.composeDrawer.on("uiComposeTweetSending", this.composerSendingEvent);
|
this.composeDrawer.on("uiComposeTweetSending", this.composerSendingEvent);
|
||||||
|
|
||||||
$(document).on("keydown", this.composeSelector, this.composeInputKeyDownEvent);
|
$(document).on("keydown", this.composeSelector, this.composeInputKeyDownEvent);
|
||||||
@@ -529,14 +546,13 @@ disabled(){
|
|||||||
$(this.currentSpanner).remove();
|
$(this.currentSpanner).remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.composePanelScroller.off("scroll", this.composerScrollEvent);
|
|
||||||
|
|
||||||
$(".emoji-keyboard-popup-btn").off("click", this.emojiKeyboardButtonClickEvent);
|
|
||||||
$(".emoji-keyboard-popup-btn").remove();
|
$(".emoji-keyboard-popup-btn").remove();
|
||||||
|
|
||||||
$(document).off("click", this.documentClickEvent);
|
$(document).off("click", this.documentClickEvent);
|
||||||
$(document).off("keydown", this.documentKeyEvent);
|
$(document).off("keydown", this.documentKeyEvent);
|
||||||
|
$(document).off("uiDrawerActive", this.drawerToggleEvent);
|
||||||
$(document).off("uiComposeImageAdded", this.uploadFilesEvent);
|
$(document).off("uiComposeImageAdded", this.uploadFilesEvent);
|
||||||
|
|
||||||
this.composeDrawer.off("uiComposeTweetSending", this.composerSendingEvent);
|
this.composeDrawer.off("uiComposeTweetSending", this.composerSendingEvent);
|
||||||
|
|
||||||
$(document).off("keydown", this.composeSelector, this.composeInputKeyDownEvent);
|
$(document).off("keydown", this.composeSelector, this.composeInputKeyDownEvent);
|
||||||
|
@@ -383,7 +383,7 @@ enabled(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
ready(){
|
ready(){
|
||||||
$(".manage-templates-btn").on("click", this.manageTemplatesButtonClickEvent);
|
$(".js-drawer[data-drawer='compose']").on("click", ".manage-templates-btn", this.manageTemplatesButtonClickEvent);
|
||||||
$(document).on("uiDrawerActive", this.drawerToggleEvent);
|
$(document).on("uiDrawerActive", this.drawerToggleEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,6 +391,7 @@ disabled(){
|
|||||||
$(".manage-templates-btn").remove();
|
$(".manage-templates-btn").remove();
|
||||||
$("#templates-modal-wrap").remove();
|
$("#templates-modal-wrap").remove();
|
||||||
|
|
||||||
|
$(".js-drawer[data-drawer='compose']").off("click", ".manage-templates-btn", this.manageTemplatesButtonClickEvent);
|
||||||
$(document).off("uiDrawerActive", this.drawerToggleEvent);
|
$(document).off("uiDrawerActive", this.drawerToggleEvent);
|
||||||
|
|
||||||
TD.mustaches["compose/docked_compose.mustache"] = this.prevComposeMustache;
|
TD.mustaches["compose/docked_compose.mustache"] = this.prevComposeMustache;
|
||||||
|
@@ -1039,14 +1039,20 @@
|
|||||||
// Block: Refocus the textbox after switching accounts.
|
// Block: Refocus the textbox after switching accounts.
|
||||||
//
|
//
|
||||||
onAppReady.push(function setupAccountSwitchRefocus(){
|
onAppReady.push(function setupAccountSwitchRefocus(){
|
||||||
const composeInput = $$(".js-compose-text", ".js-docked-compose");
|
|
||||||
|
|
||||||
const refocusInput = function(){
|
const refocusInput = function(){
|
||||||
composeInput.focus();
|
$$(".js-compose-text", ".js-docked-compose").focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
$$(".js-account-list", ".js-docked-compose").delegate(".js-account-item", "click", function(e){
|
const accountItemClickEvent = function(e){
|
||||||
setTimeout(refocusInput, 0);
|
setTimeout(refocusInput, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).on("uiDrawerActive", function(e, data){
|
||||||
|
if (data.activeDrawer === "compose"){
|
||||||
|
setTimeout(function(){
|
||||||
|
$$(".js-account-list", ".js-docked-compose").delegate(".js-account-item", "click", accountItemClickEvent);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1198,6 +1204,8 @@
|
|||||||
//
|
//
|
||||||
execSafe(function setupVideoPlayer(){
|
execSafe(function setupVideoPlayer(){
|
||||||
window.TDGF_playVideo = function(url, username){
|
window.TDGF_playVideo = function(url, username){
|
||||||
|
return if !url;
|
||||||
|
|
||||||
$('<div id="td-video-player-overlay" class="ovl" style="display:block"></div>').on("click contextmenu", function(){
|
$('<div id="td-video-player-overlay" class="ovl" style="display:block"></div>').on("click contextmenu", function(){
|
||||||
$TD.playVideo(null, null);
|
$TD.playVideo(null, null);
|
||||||
}).appendTo(app);
|
}).appendTo(app);
|
||||||
@@ -1503,6 +1511,8 @@
|
|||||||
//
|
//
|
||||||
if (ensurePropertyExists(TD, "components", "ConversationDetailView", "prototype", "showChirp")){
|
if (ensurePropertyExists(TD, "components", "ConversationDetailView", "prototype", "showChirp")){
|
||||||
TD.components.ConversationDetailView.prototype.showChirp = appendToFunction(TD.components.ConversationDetailView.prototype.showChirp, function(){
|
TD.components.ConversationDetailView.prototype.showChirp = appendToFunction(TD.components.ConversationDetailView.prototype.showChirp, function(){
|
||||||
|
return if !$TDX.focusDmInput;
|
||||||
|
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
$(".js-reply-tweetbox").first().focus();
|
$(".js-reply-tweetbox").first().focus();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
@@ -7,19 +7,30 @@
|
|||||||
min-width: 515px;
|
min-width: 515px;
|
||||||
max-width: 835px;
|
max-width: 835px;
|
||||||
height: 328px;
|
height: 328px;
|
||||||
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#td-introduction-modal .mdl-inner {
|
#td-introduction-modal .mdl-header {
|
||||||
padding-top: 0;
|
color: #8899a6;
|
||||||
}
|
}
|
||||||
|
|
||||||
#td-introduction-modal .mdl-header-title {
|
#td-introduction-modal .mdl-header-title {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#td-introduction-modal .mdl-dismiss {
|
||||||
|
color: #292f33;
|
||||||
|
}
|
||||||
|
|
||||||
|
#td-introduction-modal .mdl-inner {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#td-introduction-modal .mdl-content {
|
#td-introduction-modal .mdl-content {
|
||||||
padding: 4px 16px 0;
|
padding: 4px 16px 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
border-color: #ccd6dd;
|
||||||
|
background: #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
#td-introduction-modal p {
|
#td-introduction-modal p {
|
||||||
|
@@ -1,38 +0,0 @@
|
|||||||
/*****************************/
|
|
||||||
/* Fix min width and margins */
|
|
||||||
/*****************************/
|
|
||||||
|
|
||||||
.page-canvas {
|
|
||||||
width: auto !important;
|
|
||||||
max-width: 888px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.signout-wrapper {
|
|
||||||
width: auto !important;
|
|
||||||
margin: 0 auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.signout {
|
|
||||||
margin: 60px 0 54px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
padding-bottom: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************/
|
|
||||||
/* General styling */
|
|
||||||
/*******************/
|
|
||||||
|
|
||||||
.aside {
|
|
||||||
/* hide elements around dialog */
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons button, .buttons a {
|
|
||||||
/* style buttons */
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 4px !important;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.3) !important;
|
|
||||||
border-radius: 0 !important;
|
|
||||||
}
|
|
@@ -1,11 +1,3 @@
|
|||||||
/***********/
|
|
||||||
/* General */
|
|
||||||
/***********/
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
/* Redesign scrollbars */
|
/* Redesign scrollbars */
|
||||||
/***********************/
|
/***********************/
|
||||||
@@ -377,14 +369,25 @@ html[data-td-font='smallest'] .badge-verified:before {
|
|||||||
|
|
||||||
html[data-td-font='smallest'] .tweet-detail-wrapper .badge-verified:before {
|
html[data-td-font='smallest'] .tweet-detail-wrapper .badge-verified:before {
|
||||||
/* fix cut off badge in detail view */
|
/* fix cut off badge in detail view */
|
||||||
width: 13px !important;
|
width: 14px !important;
|
||||||
height: 14px !important;
|
height: 14px !important;
|
||||||
background-position: -223px -97px !important;
|
background-position: -223px -97px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-td-font='smallest'] .fullname-badged:before, html[data-td-font='small'] .fullname-badged:before {
|
html[data-td-font='smallest'] .fullname-badged:before, html[data-td-font='small'] .fullname-badged:before {
|
||||||
/* fix cut off badge in follow chirps */
|
/* fix cut off badge in follow chirps and detail view */
|
||||||
margin-top: -7px !important;
|
margin-top: -1px !important;
|
||||||
|
min-width: 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-td-font='smallest'] .tweet-detail-wrapper .fullname-badged:before {
|
||||||
|
/* fix misaligned badge in detail view */
|
||||||
|
margin-top: -2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-td-font='small'] .tweet-detail-wrapper .fullname-badged:before {
|
||||||
|
/* fix misaligned badge in detail view */
|
||||||
|
margin-top: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.keyboard-shortcut-list {
|
.keyboard-shortcut-list {
|
||||||
|
@@ -25,6 +25,17 @@
|
|||||||
margin: 0 auto !important;
|
margin: 0 auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ResponsiveLayout {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Section {
|
||||||
|
padding: 36px !important;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************/
|
/*******************/
|
||||||
/* General styling */
|
/* General styling */
|
||||||
/*******************/
|
/*******************/
|
||||||
@@ -39,7 +50,7 @@ body {
|
|||||||
box-shadow: 0 0 150px rgba(255, 255, 255, 0.3) !important;
|
box-shadow: 0 0 150px rgba(255, 255, 255, 0.3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topbar {
|
.topbar, .TopNav {
|
||||||
/* hide top bar */
|
/* hide top bar */
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@@ -65,3 +76,42 @@ button[type='submit'] {
|
|||||||
margin-top: 15px !important;
|
margin-top: 15px !important;
|
||||||
font-weight: bold !important;
|
font-weight: bold !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
/* Fix min width and margins on logout page */
|
||||||
|
/********************************************/
|
||||||
|
|
||||||
|
html[logout] .page-canvas {
|
||||||
|
width: auto !important;
|
||||||
|
max-width: 888px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[logout] .signout-wrapper {
|
||||||
|
width: auto !important;
|
||||||
|
margin: 0 auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[logout] .signout {
|
||||||
|
margin: 60px 0 54px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[logout] .buttons {
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************/
|
||||||
|
/* General logout page styling */
|
||||||
|
/*******************************/
|
||||||
|
|
||||||
|
html[logout] .aside {
|
||||||
|
/* hide elements around dialog */
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[logout] .buttons button, html[logout] .buttons a {
|
||||||
|
/* style buttons */
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 4px !important;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.3) !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
@@ -8,15 +8,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let style = document.createElement("style");
|
let link = document.createElement("link");
|
||||||
|
link.rel = "stylesheet";
|
||||||
|
link.href = "https://abs.twimg.com/tduck/css";
|
||||||
|
|
||||||
style.innerText = `#import "styles/twitter.base.css"`;
|
document.head.appendChild(link);
|
||||||
|
|
||||||
if (location.pathname === "/logout"){
|
if (location.pathname === "/logout"){
|
||||||
style.innerText += `#import "styles/twitter.logout.css"`;
|
document.documentElement.setAttribute("logout", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
document.head.appendChild(style);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setTimeout(injectCSS, 1);
|
setTimeout(injectCSS, 1);
|
||||||
|
@@ -46,6 +46,12 @@
|
|||||||
<LangVersion>7</LangVersion>
|
<LangVersion>7</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.WindowsAPICodePack, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\WindowsAPICodePack-Core.1.1.1\lib\Microsoft.WindowsAPICodePack.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.WindowsAPICodePack.Shell, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>packages\WindowsAPICodePack-Shell.1.1.1\lib\Microsoft.WindowsAPICodePack.Shell.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
@@ -92,6 +98,7 @@
|
|||||||
<DependentUpon>FormBrowser.cs</DependentUpon>
|
<DependentUpon>FormBrowser.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Core\Handling\General\FileDialogHandler.cs" />
|
<Compile Include="Core\Handling\General\FileDialogHandler.cs" />
|
||||||
|
<Compile Include="Core\Handling\KeyboardHandlerBase.cs" />
|
||||||
<Compile Include="Core\Handling\KeyboardHandlerBrowser.cs" />
|
<Compile Include="Core\Handling\KeyboardHandlerBrowser.cs" />
|
||||||
<Compile Include="Core\Handling\KeyboardHandlerNotification.cs" />
|
<Compile Include="Core\Handling\KeyboardHandlerNotification.cs" />
|
||||||
<Compile Include="Core\Handling\RequestHandlerBase.cs" />
|
<Compile Include="Core\Handling\RequestHandlerBase.cs" />
|
||||||
@@ -392,6 +399,15 @@
|
|||||||
<Name>TweetLib.Communication</Name>
|
<Name>TweetLib.Communication</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Resources\Images\overlay-muted.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Resources\Images\overlay-muted.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Resources\Images\overlay-notification.ico" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>rmdir "$(ProjectDir)bin\Debug"
|
<PostBuildEvent>rmdir "$(ProjectDir)bin\Debug"
|
||||||
|
@@ -5,4 +5,6 @@
|
|||||||
<package id="CefSharp.Common" version="67.0.0" targetFramework="net452" />
|
<package id="CefSharp.Common" version="67.0.0" targetFramework="net452" />
|
||||||
<package id="CefSharp.WinForms" version="67.0.0" targetFramework="net452" />
|
<package id="CefSharp.WinForms" version="67.0.0" targetFramework="net452" />
|
||||||
<package id="Microsoft.Net.Compilers" version="2.9.0" targetFramework="net452" developmentDependency="true" />
|
<package id="Microsoft.Net.Compilers" version="2.9.0" targetFramework="net452" developmentDependency="true" />
|
||||||
|
<package id="WindowsAPICodePack-Core" version="1.1.1" targetFramework="net452" />
|
||||||
|
<package id="WindowsAPICodePack-Shell" version="1.1.1" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
@@ -1,17 +1,29 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using CefSharp.BrowserSubprocess;
|
using CefSharp.BrowserSubprocess;
|
||||||
|
|
||||||
namespace TweetDuck.Browser{
|
namespace TweetDuck.Browser{
|
||||||
static class Program{
|
static class Program{
|
||||||
internal const string Version = "1.4.1.0";
|
internal const string Version = "1.4.2";
|
||||||
|
|
||||||
private static int Main(string[] args){
|
private static int Main(string[] args){
|
||||||
SubProcess.EnableHighDPISupport();
|
SubProcess.EnableHighDPISupport();
|
||||||
|
|
||||||
const string typePrefix = "--type=";
|
string FindArg(string key){
|
||||||
string type = Array.Find(args, arg => arg.StartsWith(typePrefix, StringComparison.OrdinalIgnoreCase)).Substring(typePrefix.Length);
|
return Array.Find(args, arg => arg.StartsWith(key, StringComparison.OrdinalIgnoreCase)).Substring(key.Length);
|
||||||
|
}
|
||||||
|
|
||||||
if (type == "renderer"){
|
const string typePrefix = "--type=";
|
||||||
|
const string parentIdPrefix = "--host-process-id=";
|
||||||
|
|
||||||
|
if (!int.TryParse(FindArg(parentIdPrefix), out int parentId)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.Factory.StartNew(() => KillWhenHung(parentId), TaskCreationOptions.LongRunning);
|
||||||
|
|
||||||
|
if (FindArg(typePrefix) == "renderer"){
|
||||||
using(SubProcess subProcess = new SubProcess(args)){
|
using(SubProcess subProcess = new SubProcess(args)){
|
||||||
return subProcess.Run();
|
return subProcess.Run();
|
||||||
}
|
}
|
||||||
@@ -20,5 +32,18 @@ namespace TweetDuck.Browser{
|
|||||||
return SubProcess.ExecuteProcess();
|
return SubProcess.ExecuteProcess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async void KillWhenHung(int parentId){
|
||||||
|
try{
|
||||||
|
using(Process process = Process.GetProcessById(parentId)){
|
||||||
|
process.WaitForExit();
|
||||||
|
}
|
||||||
|
}catch{
|
||||||
|
// ded
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(10000);
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,14 @@ namespace TweetDuck.Video.Controls{
|
|||||||
Form form = control.FindForm();
|
Form form = control.FindForm();
|
||||||
System.Diagnostics.Debug.Assert(form != null);
|
System.Diagnostics.Debug.Assert(form != null);
|
||||||
|
|
||||||
Text = tooltipFunc(args);
|
string text = tooltipFunc(args);
|
||||||
|
|
||||||
|
if (text == null){
|
||||||
|
Visible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text = text;
|
||||||
|
|
||||||
Point loc = form.PointToClient(control.Parent.PointToScreen(new Point(control.Location.X+(followCursor ? args.X : control.Width/2), 0)));
|
Point loc = form.PointToClient(control.Parent.PointToScreen(new Point(control.Location.X+(followCursor ? args.X : control.Width/2), 0)));
|
||||||
loc.X = Math.Max(0, Math.Min(form.Width-Width, loc.X-Width/2));
|
loc.X = Math.Max(0, Math.Min(form.Width-Width, loc.X-Width/2));
|
||||||
|
@@ -30,7 +30,7 @@ namespace TweetDuck.Video.Controls{
|
|||||||
brushBack.Color = Parent.BackColor;
|
brushBack.Color = Parent.BackColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle rect = e.ClipRectangle;
|
Rectangle rect = new Rectangle(0, 0, Width, Height);
|
||||||
Point cursor = PointToClient(Cursor.Position);
|
Point cursor = PointToClient(Cursor.Position);
|
||||||
int width = rect.Width-1;
|
int width = rect.Width-1;
|
||||||
int progress = (int)(width*((double)Value/Maximum));
|
int progress = (int)(width*((double)Value/Maximum));
|
||||||
|
155
video/FormPlayer.Designer.cs
generated
155
video/FormPlayer.Designer.cs
generated
@@ -26,16 +26,18 @@
|
|||||||
this.components = new System.ComponentModel.Container();
|
this.components = new System.ComponentModel.Container();
|
||||||
this.timerSync = new System.Windows.Forms.Timer(this.components);
|
this.timerSync = new System.Windows.Forms.Timer(this.components);
|
||||||
this.trackBarVolume = new System.Windows.Forms.TrackBar();
|
this.trackBarVolume = new System.Windows.Forms.TrackBar();
|
||||||
this.tablePanel = new System.Windows.Forms.TableLayoutPanel();
|
this.tablePanelFull = new System.Windows.Forms.TableLayoutPanel();
|
||||||
this.progressSeek = new TweetDuck.Video.Controls.SeekBar();
|
this.progressSeek = new TweetDuck.Video.Controls.SeekBar();
|
||||||
this.labelTime = new System.Windows.Forms.Label();
|
this.labelTime = new System.Windows.Forms.Label();
|
||||||
this.timerData = new System.Windows.Forms.Timer(this.components);
|
|
||||||
this.labelTooltip = new TweetDuck.Video.Controls.LabelTooltip();
|
|
||||||
this.imageResize = new System.Windows.Forms.PictureBox();
|
this.imageResize = new System.Windows.Forms.PictureBox();
|
||||||
this.imageDownload = new System.Windows.Forms.PictureBox();
|
this.imageDownload = new System.Windows.Forms.PictureBox();
|
||||||
this.imageClose = new System.Windows.Forms.PictureBox();
|
this.imageClose = new System.Windows.Forms.PictureBox();
|
||||||
|
this.timerData = new System.Windows.Forms.Timer(this.components);
|
||||||
|
this.tablePanelCompactBottom = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.tablePanelCompactTop = new System.Windows.Forms.TableLayoutPanel();
|
||||||
|
this.labelTooltip = new TweetDuck.Video.Controls.LabelTooltip();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).BeginInit();
|
||||||
this.tablePanel.SuspendLayout();
|
this.tablePanelFull.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.imageResize)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.imageResize)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.imageDownload)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.imageDownload)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.imageClose)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.imageClose)).BeginInit();
|
||||||
@@ -64,30 +66,32 @@
|
|||||||
this.trackBarVolume.MouseDown += new System.Windows.Forms.MouseEventHandler(this.trackBarVolume_MouseDown);
|
this.trackBarVolume.MouseDown += new System.Windows.Forms.MouseEventHandler(this.trackBarVolume_MouseDown);
|
||||||
this.trackBarVolume.MouseUp += new System.Windows.Forms.MouseEventHandler(this.trackBarVolume_MouseUp);
|
this.trackBarVolume.MouseUp += new System.Windows.Forms.MouseEventHandler(this.trackBarVolume_MouseUp);
|
||||||
//
|
//
|
||||||
// tablePanel
|
// tablePanelFull
|
||||||
//
|
//
|
||||||
this.tablePanel.BackColor = System.Drawing.SystemColors.Control;
|
this.tablePanelFull.BackColor = System.Drawing.SystemColors.Control;
|
||||||
this.tablePanel.ColumnCount = 6;
|
this.tablePanelFull.ColumnCount = 6;
|
||||||
this.tablePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
this.tablePanelFull.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
||||||
this.tablePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
this.tablePanelFull.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
this.tablePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 74F));
|
this.tablePanelFull.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
|
||||||
this.tablePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130F));
|
this.tablePanelFull.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130F));
|
||||||
this.tablePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
this.tablePanelFull.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
||||||
this.tablePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
this.tablePanelFull.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
||||||
this.tablePanel.Controls.Add(this.trackBarVolume, 3, 0);
|
this.tablePanelFull.Controls.Add(this.trackBarVolume, 3, 0);
|
||||||
this.tablePanel.Controls.Add(this.progressSeek, 1, 0);
|
this.tablePanelFull.Controls.Add(this.progressSeek, 1, 0);
|
||||||
this.tablePanel.Controls.Add(this.labelTime, 2, 0);
|
this.tablePanelFull.Controls.Add(this.labelTime, 2, 0);
|
||||||
this.tablePanel.Controls.Add(this.imageResize, 5, 0);
|
this.tablePanelFull.Controls.Add(this.imageResize, 5, 0);
|
||||||
this.tablePanel.Controls.Add(this.imageDownload, 4, 0);
|
this.tablePanelFull.Controls.Add(this.imageDownload, 4, 0);
|
||||||
this.tablePanel.Controls.Add(this.imageClose, 0, 0);
|
this.tablePanelFull.Controls.Add(this.imageClose, 0, 0);
|
||||||
this.tablePanel.Dock = System.Windows.Forms.DockStyle.Bottom;
|
this.tablePanelFull.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||||
this.tablePanel.Location = new System.Drawing.Point(0, 86);
|
this.tablePanelFull.Enabled = false;
|
||||||
this.tablePanel.Name = "tablePanel";
|
this.tablePanelFull.Location = new System.Drawing.Point(0, 86);
|
||||||
this.tablePanel.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
this.tablePanelFull.Name = "tablePanelFull";
|
||||||
this.tablePanel.RowCount = 1;
|
this.tablePanelFull.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
this.tablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
this.tablePanelFull.RowCount = 1;
|
||||||
this.tablePanel.Size = new System.Drawing.Size(400, 34);
|
this.tablePanelFull.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
this.tablePanel.TabIndex = 1;
|
this.tablePanelFull.Size = new System.Drawing.Size(400, 34);
|
||||||
|
this.tablePanelFull.TabIndex = 0;
|
||||||
|
this.tablePanelFull.Visible = false;
|
||||||
//
|
//
|
||||||
// progressSeek
|
// progressSeek
|
||||||
//
|
//
|
||||||
@@ -98,7 +102,7 @@
|
|||||||
this.progressSeek.Margin = new System.Windows.Forms.Padding(9, 10, 8, 10);
|
this.progressSeek.Margin = new System.Windows.Forms.Padding(9, 10, 8, 10);
|
||||||
this.progressSeek.Maximum = 5000;
|
this.progressSeek.Maximum = 5000;
|
||||||
this.progressSeek.Name = "progressSeek";
|
this.progressSeek.Name = "progressSeek";
|
||||||
this.progressSeek.Size = new System.Drawing.Size(91, 14);
|
this.progressSeek.Size = new System.Drawing.Size(85, 14);
|
||||||
this.progressSeek.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
|
this.progressSeek.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
|
||||||
this.progressSeek.TabIndex = 0;
|
this.progressSeek.TabIndex = 0;
|
||||||
this.progressSeek.MouseDown += new System.Windows.Forms.MouseEventHandler(this.progressSeek_MouseDown);
|
this.progressSeek.MouseDown += new System.Windows.Forms.MouseEventHandler(this.progressSeek_MouseDown);
|
||||||
@@ -106,32 +110,14 @@
|
|||||||
// labelTime
|
// labelTime
|
||||||
//
|
//
|
||||||
this.labelTime.Dock = System.Windows.Forms.DockStyle.Fill;
|
this.labelTime.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
this.labelTime.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular);
|
this.labelTime.Font = new System.Drawing.Font("Segoe UI", 9F);
|
||||||
this.labelTime.Location = new System.Drawing.Point(138, 3);
|
this.labelTime.Location = new System.Drawing.Point(132, 3);
|
||||||
this.labelTime.Margin = new System.Windows.Forms.Padding(0, 3, 0, 5);
|
this.labelTime.Margin = new System.Windows.Forms.Padding(0, 3, 0, 5);
|
||||||
this.labelTime.Name = "labelTime";
|
this.labelTime.Name = "labelTime";
|
||||||
this.labelTime.Size = new System.Drawing.Size(74, 26);
|
this.labelTime.Size = new System.Drawing.Size(80, 26);
|
||||||
this.labelTime.TabIndex = 1;
|
this.labelTime.TabIndex = 1;
|
||||||
this.labelTime.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
this.labelTime.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||||
//
|
//
|
||||||
// timerData
|
|
||||||
//
|
|
||||||
this.timerData.Interval = 500;
|
|
||||||
this.timerData.Tick += new System.EventHandler(this.timerData_Tick);
|
|
||||||
//
|
|
||||||
// labelTooltip
|
|
||||||
//
|
|
||||||
this.labelTooltip.AutoSize = true;
|
|
||||||
this.labelTooltip.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
|
|
||||||
this.labelTooltip.ForeColor = System.Drawing.Color.White;
|
|
||||||
this.labelTooltip.Location = new System.Drawing.Point(0, 0);
|
|
||||||
this.labelTooltip.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
|
||||||
this.labelTooltip.Name = "labelTooltip";
|
|
||||||
this.labelTooltip.Padding = new System.Windows.Forms.Padding(4, 2, 2, 2);
|
|
||||||
this.labelTooltip.Size = new System.Drawing.Size(6, 19);
|
|
||||||
this.labelTooltip.TabIndex = 2;
|
|
||||||
this.labelTooltip.Visible = false;
|
|
||||||
//
|
|
||||||
// imageResize
|
// imageResize
|
||||||
//
|
//
|
||||||
this.imageResize.Cursor = System.Windows.Forms.Cursors.Hand;
|
this.imageResize.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||||
@@ -178,6 +164,66 @@
|
|||||||
this.imageClose.WaitOnLoad = true;
|
this.imageClose.WaitOnLoad = true;
|
||||||
this.imageClose.Click += new System.EventHandler(this.imageClose_Click);
|
this.imageClose.Click += new System.EventHandler(this.imageClose_Click);
|
||||||
//
|
//
|
||||||
|
// timerData
|
||||||
|
//
|
||||||
|
this.timerData.Interval = 500;
|
||||||
|
this.timerData.Tick += new System.EventHandler(this.timerData_Tick);
|
||||||
|
//
|
||||||
|
// tablePanelCompactBottom
|
||||||
|
//
|
||||||
|
this.tablePanelCompactBottom.BackColor = System.Drawing.SystemColors.Control;
|
||||||
|
this.tablePanelCompactBottom.ColumnCount = 5;
|
||||||
|
this.tablePanelCompactBottom.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
||||||
|
this.tablePanelCompactBottom.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tablePanelCompactBottom.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130F));
|
||||||
|
this.tablePanelCompactBottom.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
||||||
|
this.tablePanelCompactBottom.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 28F));
|
||||||
|
this.tablePanelCompactBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||||
|
this.tablePanelCompactBottom.Enabled = false;
|
||||||
|
this.tablePanelCompactBottom.Location = new System.Drawing.Point(0, 52);
|
||||||
|
this.tablePanelCompactBottom.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3);
|
||||||
|
this.tablePanelCompactBottom.Name = "tablePanelCompactBottom";
|
||||||
|
this.tablePanelCompactBottom.Padding = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||||
|
this.tablePanelCompactBottom.RowCount = 1;
|
||||||
|
this.tablePanelCompactBottom.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tablePanelCompactBottom.Size = new System.Drawing.Size(400, 34);
|
||||||
|
this.tablePanelCompactBottom.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// tablePanelCompactTop
|
||||||
|
//
|
||||||
|
this.tablePanelCompactTop.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.tablePanelCompactTop.BackColor = System.Drawing.SystemColors.Control;
|
||||||
|
this.tablePanelCompactTop.ColumnCount = 2;
|
||||||
|
this.tablePanelCompactTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tablePanelCompactTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
|
||||||
|
this.tablePanelCompactTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||||
|
this.tablePanelCompactTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||||
|
this.tablePanelCompactTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||||
|
this.tablePanelCompactTop.Enabled = false;
|
||||||
|
this.tablePanelCompactTop.Location = new System.Drawing.Point(0, 60);
|
||||||
|
this.tablePanelCompactTop.Margin = new System.Windows.Forms.Padding(0);
|
||||||
|
this.tablePanelCompactTop.Name = "tablePanelCompactTop";
|
||||||
|
this.tablePanelCompactTop.Padding = new System.Windows.Forms.Padding(2, 0, 4, 0);
|
||||||
|
this.tablePanelCompactTop.RowCount = 1;
|
||||||
|
this.tablePanelCompactTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||||
|
this.tablePanelCompactTop.Size = new System.Drawing.Size(400, 34);
|
||||||
|
this.tablePanelCompactTop.TabIndex = 2;
|
||||||
|
this.tablePanelCompactTop.Visible = false;
|
||||||
|
//
|
||||||
|
// labelTooltip
|
||||||
|
//
|
||||||
|
this.labelTooltip.AutoSize = true;
|
||||||
|
this.labelTooltip.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold);
|
||||||
|
this.labelTooltip.ForeColor = System.Drawing.Color.White;
|
||||||
|
this.labelTooltip.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.labelTooltip.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||||
|
this.labelTooltip.Name = "labelTooltip";
|
||||||
|
this.labelTooltip.Padding = new System.Windows.Forms.Padding(4, 2, 2, 2);
|
||||||
|
this.labelTooltip.Size = new System.Drawing.Size(6, 19);
|
||||||
|
this.labelTooltip.TabIndex = 3;
|
||||||
|
this.labelTooltip.Visible = false;
|
||||||
|
//
|
||||||
// FormPlayer
|
// FormPlayer
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
@@ -186,12 +232,13 @@
|
|||||||
this.ClientSize = new System.Drawing.Size(400, 120);
|
this.ClientSize = new System.Drawing.Size(400, 120);
|
||||||
this.ControlBox = false;
|
this.ControlBox = false;
|
||||||
this.Controls.Add(this.labelTooltip);
|
this.Controls.Add(this.labelTooltip);
|
||||||
this.Controls.Add(this.tablePanel);
|
this.Controls.Add(this.tablePanelCompactBottom);
|
||||||
|
this.Controls.Add(this.tablePanelFull);
|
||||||
|
this.Controls.Add(this.tablePanelCompactTop);
|
||||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||||
this.Location = new System.Drawing.Point(-32000, -32000);
|
this.Location = new System.Drawing.Point(-32000, -32000);
|
||||||
this.MaximizeBox = false;
|
this.MaximizeBox = false;
|
||||||
this.MinimizeBox = false;
|
this.MinimizeBox = false;
|
||||||
this.MinimumSize = new System.Drawing.Size(400, 120);
|
|
||||||
this.Name = "FormPlayer";
|
this.Name = "FormPlayer";
|
||||||
this.ShowIcon = false;
|
this.ShowIcon = false;
|
||||||
this.ShowInTaskbar = false;
|
this.ShowInTaskbar = false;
|
||||||
@@ -199,7 +246,7 @@
|
|||||||
this.Text = "TweetDuck Video";
|
this.Text = "TweetDuck Video";
|
||||||
this.Load += new System.EventHandler(this.FormPlayer_Load);
|
this.Load += new System.EventHandler(this.FormPlayer_Load);
|
||||||
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).EndInit();
|
||||||
this.tablePanel.ResumeLayout(false);
|
this.tablePanelFull.ResumeLayout(false);
|
||||||
((System.ComponentModel.ISupportInitialize)(this.imageResize)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.imageResize)).EndInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.imageDownload)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.imageDownload)).EndInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.imageClose)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.imageClose)).EndInit();
|
||||||
@@ -212,7 +259,7 @@
|
|||||||
|
|
||||||
private System.Windows.Forms.Timer timerSync;
|
private System.Windows.Forms.Timer timerSync;
|
||||||
private System.Windows.Forms.TrackBar trackBarVolume;
|
private System.Windows.Forms.TrackBar trackBarVolume;
|
||||||
private System.Windows.Forms.TableLayoutPanel tablePanel;
|
private System.Windows.Forms.TableLayoutPanel tablePanelFull;
|
||||||
private Controls.SeekBar progressSeek;
|
private Controls.SeekBar progressSeek;
|
||||||
private System.Windows.Forms.Label labelTime;
|
private System.Windows.Forms.Label labelTime;
|
||||||
private System.Windows.Forms.Timer timerData;
|
private System.Windows.Forms.Timer timerData;
|
||||||
@@ -220,6 +267,8 @@
|
|||||||
private System.Windows.Forms.PictureBox imageResize;
|
private System.Windows.Forms.PictureBox imageResize;
|
||||||
private System.Windows.Forms.PictureBox imageDownload;
|
private System.Windows.Forms.PictureBox imageDownload;
|
||||||
private System.Windows.Forms.PictureBox imageClose;
|
private System.Windows.Forms.PictureBox imageClose;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tablePanelCompactBottom;
|
||||||
|
private System.Windows.Forms.TableLayoutPanel tablePanelCompactTop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,9 +10,17 @@ using WMPLib;
|
|||||||
|
|
||||||
namespace TweetDuck.Video{
|
namespace TweetDuck.Video{
|
||||||
sealed partial class FormPlayer : Form{
|
sealed partial class FormPlayer : Form{
|
||||||
|
private bool IsCursorOverVideo{
|
||||||
|
get{
|
||||||
|
Point cursor = PointToClient(Cursor.Position);
|
||||||
|
return cursor.Y < (tablePanelFull.Enabled ? tablePanelFull.Location.Y : tablePanelCompactTop.Location.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool ShowWithoutActivation => true;
|
protected override bool ShowWithoutActivation => true;
|
||||||
|
|
||||||
private readonly IntPtr ownerHandle;
|
private readonly IntPtr ownerHandle;
|
||||||
|
private readonly float ownerDpi;
|
||||||
private readonly string videoUrl;
|
private readonly string videoUrl;
|
||||||
private readonly DuplexPipe pipe;
|
private readonly DuplexPipe pipe;
|
||||||
|
|
||||||
@@ -23,14 +31,21 @@ namespace TweetDuck.Video{
|
|||||||
|
|
||||||
private WindowsMediaPlayer Player => player.Ocx;
|
private WindowsMediaPlayer Player => player.Ocx;
|
||||||
|
|
||||||
public FormPlayer(IntPtr handle, int volume, string url, string token){
|
public FormPlayer(IntPtr handle, int dpi, int volume, string url, string token){
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
this.ownerHandle = handle;
|
this.ownerHandle = handle;
|
||||||
|
this.ownerDpi = dpi / 100F;
|
||||||
this.videoUrl = url;
|
this.videoUrl = url;
|
||||||
this.pipe = DuplexPipe.CreateClient(token);
|
this.pipe = DuplexPipe.CreateClient(token);
|
||||||
this.pipe.DataIn += pipe_DataIn;
|
this.pipe.DataIn += pipe_DataIn;
|
||||||
|
|
||||||
|
if (NativeMethods.GetWindowRect(ownerHandle, out NativeMethods.RECT rect)){
|
||||||
|
ClientSize = new Size(0, 0);
|
||||||
|
Location = new Point((rect.Left+rect.Right)/2, (rect.Top+rect.Bottom)/2);
|
||||||
|
Opacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
player = new ControlWMP{
|
player = new ControlWMP{
|
||||||
Dock = DockStyle.Fill
|
Dock = DockStyle.Fill
|
||||||
};
|
};
|
||||||
@@ -51,6 +66,10 @@ namespace TweetDuck.Video{
|
|||||||
trackBarVolume.Value = volume; // changes player volume too if non-default
|
trackBarVolume.Value = volume; // changes player volume too if non-default
|
||||||
|
|
||||||
labelTooltip.AttachTooltip(progressSeek, true, args => {
|
labelTooltip.AttachTooltip(progressSeek, true, args => {
|
||||||
|
if (args.X < 0 || args.Y < 0 || args.X >= progressSeek.Width || args.Y >= progressSeek.Height){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
IWMPMedia media = Player.currentMedia;
|
IWMPMedia media = Player.currentMedia;
|
||||||
int progress = (int)(media.duration*progressSeek.GetProgress(args.X));
|
int progress = (int)(media.duration*progressSeek.GetProgress(args.X));
|
||||||
|
|
||||||
@@ -68,6 +87,59 @@ namespace TweetDuck.Video{
|
|||||||
Application.AddMessageFilter(new MessageFilter(this));
|
Application.AddMessageFilter(new MessageFilter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Layout
|
||||||
|
|
||||||
|
private int DpiScaled(int value){
|
||||||
|
return (int)Math.Round(value*ownerDpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshControlPanel(){
|
||||||
|
bool useCompactLayout = ClientSize.Width < DpiScaled(480);
|
||||||
|
bool needsUpdate = !timerSync.Enabled || (useCompactLayout ? tablePanelFull.Enabled : tablePanelCompactBottom.Enabled);
|
||||||
|
|
||||||
|
if (needsUpdate){
|
||||||
|
void Disable(TableLayoutPanel panel){
|
||||||
|
panel.Controls.Clear();
|
||||||
|
panel.Visible = false;
|
||||||
|
panel.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tablePanelFull.SuspendLayout();
|
||||||
|
tablePanelCompactBottom.SuspendLayout();
|
||||||
|
tablePanelCompactTop.SuspendLayout();
|
||||||
|
|
||||||
|
if (useCompactLayout){
|
||||||
|
Disable(tablePanelFull);
|
||||||
|
|
||||||
|
tablePanelCompactBottom.Enabled = true;
|
||||||
|
tablePanelCompactBottom.Controls.Add(imageClose, 0, 0);
|
||||||
|
tablePanelCompactBottom.Controls.Add(trackBarVolume, 2, 0);
|
||||||
|
tablePanelCompactBottom.Controls.Add(imageDownload, 3, 0);
|
||||||
|
tablePanelCompactBottom.Controls.Add(imageResize, 4, 0);
|
||||||
|
|
||||||
|
tablePanelCompactTop.Enabled = true;
|
||||||
|
tablePanelCompactTop.Controls.Add(progressSeek, 0, 0);
|
||||||
|
tablePanelCompactTop.Controls.Add(labelTime, 1, 0);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Disable(tablePanelCompactBottom);
|
||||||
|
Disable(tablePanelCompactTop);
|
||||||
|
|
||||||
|
tablePanelFull.Enabled = true;
|
||||||
|
tablePanelFull.Controls.Add(imageClose, 0, 0);
|
||||||
|
tablePanelFull.Controls.Add(progressSeek, 1, 0);
|
||||||
|
tablePanelFull.Controls.Add(labelTime, 2, 0);
|
||||||
|
tablePanelFull.Controls.Add(trackBarVolume, 3, 0);
|
||||||
|
tablePanelFull.Controls.Add(imageDownload, 4, 0);
|
||||||
|
tablePanelFull.Controls.Add(imageResize, 5, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
tablePanelFull.ResumeLayout();
|
||||||
|
tablePanelCompactBottom.ResumeLayout();
|
||||||
|
tablePanelCompactTop.ResumeLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
private void FormPlayer_Load(object sender, EventArgs e){
|
private void FormPlayer_Load(object sender, EventArgs e){
|
||||||
@@ -97,9 +169,14 @@ namespace TweetDuck.Video{
|
|||||||
else if (state == WMPPlayState.wmppsPlaying){
|
else if (state == WMPPlayState.wmppsPlaying){
|
||||||
Player.PlayStateChange -= player_PlayStateChange;
|
Player.PlayStateChange -= player_PlayStateChange;
|
||||||
|
|
||||||
timerSync.Start();
|
|
||||||
NativeMethods.SetWindowOwner(Handle, ownerHandle);
|
NativeMethods.SetWindowOwner(Handle, ownerHandle);
|
||||||
Cursor.Current = Cursors.Default;
|
Cursor.Current = Cursors.Default;
|
||||||
|
|
||||||
|
SuspendLayout();
|
||||||
|
timerSync_Tick(timerSync, EventArgs.Empty);
|
||||||
|
timerSync.Start();
|
||||||
|
Opacity = 1;
|
||||||
|
ResumeLayout(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,20 +192,38 @@ namespace TweetDuck.Video{
|
|||||||
[HandleProcessCorruptedStateExceptions]
|
[HandleProcessCorruptedStateExceptions]
|
||||||
private void timerSync_Tick(object sender, EventArgs e){
|
private void timerSync_Tick(object sender, EventArgs e){
|
||||||
if (NativeMethods.GetWindowRect(ownerHandle, out NativeMethods.RECT rect)){
|
if (NativeMethods.GetWindowRect(ownerHandle, out NativeMethods.RECT rect)){
|
||||||
int width = rect.Right-rect.Left+1;
|
|
||||||
int height = rect.Bottom-rect.Top+1;
|
|
||||||
|
|
||||||
IWMPMedia media = Player.currentMedia;
|
IWMPMedia media = Player.currentMedia;
|
||||||
IWMPControls controls = Player.controls;
|
IWMPControls controls = Player.controls;
|
||||||
|
|
||||||
|
int ownerLeft = rect.Left;
|
||||||
|
int ownerTop = rect.Top;
|
||||||
|
int ownerWidth = rect.Right-rect.Left+1;
|
||||||
|
int ownerHeight = rect.Bottom-rect.Top+1;
|
||||||
|
|
||||||
|
// roughly matches MinimumSize for client bounds, adjusted a bit for weirdness with higher DPI
|
||||||
|
int minWidth = DpiScaled(356);
|
||||||
|
int minHeight = DpiScaled(386);
|
||||||
|
|
||||||
|
if (NativeMethods.GetClientRect(ownerHandle, out NativeMethods.RECT clientSize)){
|
||||||
|
minWidth = Math.Min(minWidth, clientSize.Right);
|
||||||
|
minHeight = Math.Min(minHeight, clientSize.Bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxWidth = Math.Min(DpiScaled(media.imageSourceWidth), ownerWidth*3/4);
|
||||||
|
int maxHeight = Math.Min(DpiScaled(media.imageSourceHeight), ownerHeight*3/4);
|
||||||
|
|
||||||
bool isCursorInside = ClientRectangle.Contains(PointToClient(Cursor.Position));
|
bool isCursorInside = ClientRectangle.Contains(PointToClient(Cursor.Position));
|
||||||
|
|
||||||
ClientSize = new Size(Math.Max(MinimumSize.Width, Math.Min(media.imageSourceWidth, width*3/4)), Math.Max(MinimumSize.Height, Math.Min(media.imageSourceHeight, height*3/4)));
|
Size newSize = new Size(Math.Max(minWidth+2, maxWidth), Math.Max(minHeight+2, maxHeight));
|
||||||
Location = new Point(rect.Left+(width-ClientSize.Width)/2, rect.Top+(height-ClientSize.Height+SystemInformation.CaptionHeight)/2);
|
Point newLocation = new Point(ownerLeft+(ownerWidth-newSize.Width)/2, ownerTop+(ownerHeight-newSize.Height+SystemInformation.CaptionHeight)/2);
|
||||||
|
|
||||||
tablePanel.Visible = isCursorInside || isDragging;
|
if (ClientSize != newSize || Location != newLocation){
|
||||||
|
ClientSize = newSize;
|
||||||
|
Location = newLocation;
|
||||||
|
RefreshControlPanel();
|
||||||
|
}
|
||||||
|
|
||||||
if (tablePanel.Visible){
|
if (isCursorInside || isDragging){
|
||||||
labelTime.Text = $"{controls.currentPositionString} / {media.durationString}";
|
labelTime.Text = $"{controls.currentPositionString} / {media.durationString}";
|
||||||
|
|
||||||
int value = (int)Math.Round(progressSeek.Maximum*controls.currentPosition/media.duration);
|
int value = (int)Math.Round(progressSeek.Maximum*controls.currentPosition/media.duration);
|
||||||
@@ -142,6 +237,19 @@ namespace TweetDuck.Video{
|
|||||||
progressSeek.Value = value+1;
|
progressSeek.Value = value+1;
|
||||||
progressSeek.Value = value;
|
progressSeek.Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tablePanelFull.Enabled){
|
||||||
|
tablePanelFull.Visible = true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
tablePanelCompactBottom.Visible = true;
|
||||||
|
tablePanelCompactTop.Visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
tablePanelFull.Visible = false;
|
||||||
|
tablePanelCompactBottom.Visible = false;
|
||||||
|
tablePanelCompactTop.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controls.currentPosition > media.duration){ // pausing near the end of the video causes WMP to play beyond the end of the video wtf
|
if (controls.currentPosition > media.duration){ // pausing near the end of the video causes WMP to play beyond the end of the video wtf
|
||||||
@@ -157,6 +265,10 @@ namespace TweetDuck.Video{
|
|||||||
|
|
||||||
if (isCursorInside && !wasCursorInside){
|
if (isCursorInside && !wasCursorInside){
|
||||||
wasCursorInside = true;
|
wasCursorInside = true;
|
||||||
|
|
||||||
|
if (IsCursorOverVideo){
|
||||||
|
Cursor.Current = Cursors.Default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!isCursorInside && wasCursorInside){
|
else if (!isCursorInside && wasCursorInside){
|
||||||
wasCursorInside = false;
|
wasCursorInside = false;
|
||||||
@@ -273,26 +385,19 @@ namespace TweetDuck.Video{
|
|||||||
internal sealed class MessageFilter : IMessageFilter{
|
internal sealed class MessageFilter : IMessageFilter{
|
||||||
private readonly FormPlayer form;
|
private readonly FormPlayer form;
|
||||||
|
|
||||||
private bool IsCursorOverVideo{
|
|
||||||
get{
|
|
||||||
Point cursor = form.PointToClient(Cursor.Position);
|
|
||||||
return cursor.Y < form.tablePanel.Location.Y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessageFilter(FormPlayer form){
|
public MessageFilter(FormPlayer form){
|
||||||
this.form = form;
|
this.form = form;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IMessageFilter.PreFilterMessage(ref Message m){
|
bool IMessageFilter.PreFilterMessage(ref Message m){
|
||||||
if (m.Msg == 0x0201){ // WM_LBUTTONDOWN
|
if (m.Msg == 0x0201){ // WM_LBUTTONDOWN
|
||||||
if (IsCursorOverVideo){
|
if (form.IsCursorOverVideo){
|
||||||
form.TogglePause();
|
form.TogglePause();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m.Msg == 0x0203){ // WM_LBUTTONDBLCLK
|
else if (m.Msg == 0x0203){ // WM_LBUTTONDBLCLK
|
||||||
if (IsCursorOverVideo){
|
if (form.IsCursorOverVideo){
|
||||||
form.TogglePause();
|
form.TogglePause();
|
||||||
form.Player.fullScreen = !form.Player.fullScreen;
|
form.Player.fullScreen = !form.Player.fullScreen;
|
||||||
return true;
|
return true;
|
||||||
|
@@ -9,6 +9,10 @@ namespace TweetDuck.Video{
|
|||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ using System.Windows.Forms;
|
|||||||
|
|
||||||
namespace TweetDuck.Video{
|
namespace TweetDuck.Video{
|
||||||
static class Program{
|
static class Program{
|
||||||
internal const string Version = "1.3";
|
internal const string Version = "1.4.2";
|
||||||
|
|
||||||
// referenced in VideoPlayer
|
// referenced in VideoPlayer
|
||||||
// set by task manager -- public const int CODE_PROCESS_KILLED = 1;
|
// set by task manager -- public const int CODE_PROCESS_KILLED = 1;
|
||||||
@@ -25,21 +25,23 @@ namespace TweetDuck.Video{
|
|||||||
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
|
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
|
||||||
|
|
||||||
IntPtr ownerHandle;
|
IntPtr ownerHandle;
|
||||||
|
int ownerDpi;
|
||||||
int defaultVolume;
|
int defaultVolume;
|
||||||
string videoUrl;
|
string videoUrl;
|
||||||
string pipeToken;
|
string pipeToken;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
ownerHandle = new IntPtr(int.Parse(args[0], NumberStyles.Integer));
|
ownerHandle = new IntPtr(int.Parse(args[0], NumberStyles.Integer));
|
||||||
defaultVolume = int.Parse(args[1], NumberStyles.Integer);
|
ownerDpi = int.Parse(args[1], NumberStyles.Integer);
|
||||||
videoUrl = new Uri(args[2], UriKind.Absolute).AbsoluteUri;
|
defaultVolume = int.Parse(args[2], NumberStyles.Integer);
|
||||||
pipeToken = args[3];
|
videoUrl = new Uri(args[3], UriKind.Absolute).AbsoluteUri;
|
||||||
|
pipeToken = args[4];
|
||||||
}catch{
|
}catch{
|
||||||
return CODE_INVALID_ARGS;
|
return CODE_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Application.Run(new FormPlayer(ownerHandle, defaultVolume, videoUrl, pipeToken));
|
Application.Run(new FormPlayer(ownerHandle, ownerDpi, defaultVolume, videoUrl, pipeToken));
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
Console.Out.WriteLine(e);
|
Console.Out.WriteLine(e);
|
||||||
return CODE_LAUNCH_FAIL;
|
return CODE_LAUNCH_FAIL;
|
||||||
|
Reference in New Issue
Block a user