mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-09-14 10:32:10 +02:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
b0f9de67cf | |||
9b082e114e | |||
816a5334ac | |||
15a4e10da9 | |||
01b9302b0c | |||
442126a11a | |||
a9c140c0fc | |||
97ad7a3e68 | |||
7d737eefb6 | |||
4ac05b38d3 | |||
651bbbb672 |
@@ -494,7 +494,7 @@ namespace TweetDuck.Core{
|
||||
FormManager.TryFind<FormSettings>()?.Close();
|
||||
|
||||
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();
|
||||
FormManager.TryFind<FormPlugins>()?.Close();
|
||||
plugins.Reload(); // also reloads the browser
|
||||
|
@@ -13,7 +13,12 @@ namespace TweetDuck.Core.Handling{
|
||||
public RequestHandlerBrowser() : base(true){}
|
||||
|
||||
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;
|
||||
|
||||
if (url.Contains("analytics.")){
|
||||
|
@@ -33,6 +33,7 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
|
||||
private readonly PluginManager plugins;
|
||||
private readonly Dictionary<CheckBox, ProfileManager.Items> checkBoxMap = new Dictionary<CheckBox, ProfileManager.Items>(4);
|
||||
private readonly bool openImportImmediately;
|
||||
|
||||
private State currentState;
|
||||
private ProfileManager importManager;
|
||||
@@ -51,6 +52,8 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
this.checkBoxMap[cbSession] = ProfileManager.Items.Session;
|
||||
this.checkBoxMap[cbPluginData] = ProfileManager.Items.PluginData;
|
||||
|
||||
this.openImportImmediately = openImportImmediately;
|
||||
|
||||
if (openImportImmediately){
|
||||
radioImport.Checked = true;
|
||||
btnContinue_Click(null, EventArgs.Empty);
|
||||
@@ -88,6 +91,10 @@ namespace TweetDuck.Core.Other.Settings.Dialogs{
|
||||
Filter = "TweetDuck Profile (*.tdsettings)|*.tdsettings"
|
||||
}){
|
||||
if (dialog.ShowDialog() != DialogResult.OK){
|
||||
if (openImportImmediately){
|
||||
Close();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,9 @@ namespace TweetDuck.Core{
|
||||
sealed class TweetDeckBrowser : IDisposable{
|
||||
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 Enabled{
|
||||
@@ -119,10 +122,15 @@ namespace TweetDuck.Core{
|
||||
|
||||
if (frame.IsMain){
|
||||
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);
|
||||
}
|
||||
|
||||
frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorOverride);
|
||||
if (!TwitterUtils.IsTwitterLogin2FactorWebsite(frame)){
|
||||
frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorOverride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +159,10 @@ namespace TweetDuck.Core{
|
||||
|
||||
ScriptLoader.ExecuteFile(frame, "update.js", browser);
|
||||
}
|
||||
|
||||
if (frame.Url == ErrorUrl){
|
||||
resourceHandlerFactory.UnregisterHandler(ErrorUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private void browser_LoadError(object sender, LoadErrorEventArgs e){
|
||||
@@ -162,7 +174,8 @@ namespace TweetDuck.Core{
|
||||
string errorPage = ScriptLoader.LoadResourceSilent("pages/error.html");
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ namespace TweetDuck.Core.Utils{
|
||||
public const string TweetDeckURL = "https://tweetdeck.twitter.com";
|
||||
|
||||
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"));
|
||||
|
||||
@@ -43,6 +43,10 @@ namespace TweetDuck.Core.Utils{
|
||||
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){
|
||||
int slash = url.LastIndexOf('/');
|
||||
return slash == -1 ? url : StringUtils.ExtractBefore(url, ':', slash);
|
||||
|
@@ -20,7 +20,7 @@ namespace TweetDuck{
|
||||
public const string BrandName = "TweetDuck";
|
||||
public const string Website = "https://tweetduck.chylex.com";
|
||||
|
||||
public const string VersionTag = "1.17";
|
||||
public const string VersionTag = "1.17.1";
|
||||
|
||||
public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
public static readonly bool IsPortable = File.Exists(Path.Combine(ProgramPath, "makeportable"));
|
||||
|
@@ -800,7 +800,7 @@ html.dark .NotificationList .Notification-body{color:#14171A}
|
||||
html.dark .DrawerModal{color:#14171A}
|
||||
/* fixes */
|
||||
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 .hw-card-container>div{border-color:#292F33;background:transparent}
|
||||
html.dark .hw-card-container>div>div{border-color:#292F33}
|
||||
|
@@ -7,19 +7,30 @@
|
||||
min-width: 515px;
|
||||
max-width: 835px;
|
||||
height: 328px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#td-introduction-modal .mdl-inner {
|
||||
padding-top: 0;
|
||||
#td-introduction-modal .mdl-header {
|
||||
color: #8899a6;
|
||||
}
|
||||
|
||||
#td-introduction-modal .mdl-header-title {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#td-introduction-modal .mdl-dismiss {
|
||||
color: #292f33;
|
||||
}
|
||||
|
||||
#td-introduction-modal .mdl-inner {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#td-introduction-modal .mdl-content {
|
||||
padding: 4px 16px 0;
|
||||
overflow-y: auto;
|
||||
border-color: #ccd6dd;
|
||||
background: #eaeaea;
|
||||
}
|
||||
|
||||
#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 */
|
||||
/***********************/
|
||||
|
@@ -25,6 +25,17 @@
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.ResponsiveLayout {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.Section {
|
||||
padding: 36px !important;
|
||||
}
|
||||
|
||||
/*******************/
|
||||
/* General styling */
|
||||
/*******************/
|
||||
@@ -39,7 +50,7 @@ body {
|
||||
box-shadow: 0 0 150px rgba(255, 255, 255, 0.3) !important;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
.topbar, .TopNav {
|
||||
/* hide top bar */
|
||||
display: none !important;
|
||||
}
|
||||
@@ -65,3 +76,42 @@ button[type='submit'] {
|
||||
margin-top: 15px !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;
|
||||
}
|
||||
|
||||
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"){
|
||||
style.innerText += `#import "styles/twitter.logout.css"`;
|
||||
document.documentElement.setAttribute("logout", "");
|
||||
}
|
||||
|
||||
document.head.appendChild(style);
|
||||
};
|
||||
|
||||
setTimeout(injectCSS, 1);
|
||||
|
@@ -19,7 +19,14 @@ namespace TweetDuck.Video.Controls{
|
||||
Form form = control.FindForm();
|
||||
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)));
|
||||
loc.X = Math.Max(0, Math.Min(form.Width-Width, loc.X-Width/2));
|
||||
|
4
video/FormPlayer.Designer.cs
generated
4
video/FormPlayer.Designer.cs
generated
@@ -88,6 +88,7 @@
|
||||
this.tablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tablePanel.Size = new System.Drawing.Size(400, 34);
|
||||
this.tablePanel.TabIndex = 1;
|
||||
this.tablePanel.Visible = false;
|
||||
//
|
||||
// progressSeek
|
||||
//
|
||||
@@ -106,7 +107,7 @@
|
||||
// labelTime
|
||||
//
|
||||
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.Margin = new System.Windows.Forms.Padding(0, 3, 0, 5);
|
||||
this.labelTime.Name = "labelTime";
|
||||
@@ -191,7 +192,6 @@
|
||||
this.Location = new System.Drawing.Point(-32000, -32000);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(400, 120);
|
||||
this.Name = "FormPlayer";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
|
@@ -31,6 +31,12 @@ namespace TweetDuck.Video{
|
||||
this.pipe = DuplexPipe.CreateClient(token);
|
||||
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{
|
||||
Dock = DockStyle.Fill
|
||||
};
|
||||
@@ -51,6 +57,10 @@ namespace TweetDuck.Video{
|
||||
trackBarVolume.Value = volume; // changes player volume too if non-default
|
||||
|
||||
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;
|
||||
int progress = (int)(media.duration*progressSeek.GetProgress(args.X));
|
||||
|
||||
@@ -100,6 +110,11 @@ namespace TweetDuck.Video{
|
||||
timerSync.Start();
|
||||
NativeMethods.SetWindowOwner(Handle, ownerHandle);
|
||||
Cursor.Current = Cursors.Default;
|
||||
|
||||
SuspendLayout();
|
||||
timerSync_Tick(timerSync, EventArgs.Empty);
|
||||
Opacity = 1;
|
||||
ResumeLayout(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,16 +130,30 @@ namespace TweetDuck.Video{
|
||||
[HandleProcessCorruptedStateExceptions]
|
||||
private void timerSync_Tick(object sender, EventArgs e){
|
||||
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;
|
||||
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
|
||||
const int minWidth = 334;
|
||||
const int minHeight = 388;
|
||||
|
||||
int maxWidth = Math.Min(media.imageSourceWidth, ownerWidth*3/4);
|
||||
int maxHeight = Math.Min(media.imageSourceHeight, ownerHeight*3/4);
|
||||
|
||||
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)));
|
||||
Location = new Point(rect.Left+(width-ClientSize.Width)/2, rect.Top+(height-ClientSize.Height+SystemInformation.CaptionHeight)/2);
|
||||
Size newSize = new Size(Math.Max(minWidth, maxWidth), Math.Max(minHeight, maxHeight));
|
||||
Point newLocation = new Point(ownerLeft+(ownerWidth-newSize.Width)/2, ownerTop+(ownerHeight-newSize.Height+SystemInformation.CaptionHeight)/2);
|
||||
|
||||
if (ClientSize != newSize || Location != newLocation){
|
||||
ClientSize = newSize;
|
||||
Location = newLocation;
|
||||
}
|
||||
|
||||
tablePanel.Visible = isCursorInside || isDragging;
|
||||
|
||||
|
@@ -5,7 +5,7 @@ using System.Windows.Forms;
|
||||
|
||||
namespace TweetDuck.Video{
|
||||
static class Program{
|
||||
internal const string Version = "1.3";
|
||||
internal const string Version = "1.4";
|
||||
|
||||
// referenced in VideoPlayer
|
||||
// set by task manager -- public const int CODE_PROCESS_KILLED = 1;
|
||||
|
Reference in New Issue
Block a user