1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-09-14 01:32:10 +02:00

Compare commits

..

11 Commits
1.17 ... 1.17.1

16 changed files with 153 additions and 73 deletions

View File

@@ -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

View File

@@ -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.")){

View File

@@ -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;
}

View File

@@ -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,12 +122,17 @@ 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);
}
if (!TwitterUtils.IsTwitterLogin2FactorWebsite(frame)){
frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorOverride);
}
}
}
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
IFrame frame = e.Frame;
@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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"));

View File

@@ -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}

View File

@@ -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 {

View File

@@ -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;
}

View File

@@ -1,11 +1,3 @@
/***********/
/* General */
/***********/
body {
margin: 0;
}
/***********************/
/* Redesign scrollbars */
/***********************/

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;