mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-09-14 19:32:10 +02:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
7de79786c9 | |||
d3d1fc808e | |||
1ab9e35c6e | |||
e6e4d0ba75 | |||
147c268ef8 | |||
ebd17e1544 | |||
039233c782 | |||
57484c8bf7 | |||
74fec18146 | |||
00341e984c | |||
c172e7aa3d | |||
1030555bb5 | |||
c53636c013 | |||
cf450447e5 | |||
81c29ab50c | |||
f99435ff6a | |||
39f554693d | |||
38539c4a9b |
@@ -3,6 +3,7 @@ using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Windows.Forms;
|
||||
using TweetDick.Core.Handling;
|
||||
|
||||
namespace TweetDick.Configuration{
|
||||
@@ -13,6 +14,7 @@ namespace TweetDick.Configuration{
|
||||
// START OF CONFIGURATION
|
||||
|
||||
public bool IgnoreMigration { get; set; }
|
||||
public bool IgnoreUninstallCheck { get; set; }
|
||||
|
||||
public bool IsMaximized { get; set; }
|
||||
public Point WindowLocation { get; set; }
|
||||
@@ -26,13 +28,13 @@ namespace TweetDick.Configuration{
|
||||
|
||||
public bool IsCustomWindowLocationSet{
|
||||
get{
|
||||
return WindowLocation.X != 32000;
|
||||
return WindowLocation.X != -32000 && WindowLocation.X != 32000;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCustomNotificationPositionSet{
|
||||
get{
|
||||
return CustomNotificationPosition.X != 32000;
|
||||
return CustomNotificationPosition.X != -32000 && CustomNotificationPosition.X != 32000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,10 +47,10 @@ namespace TweetDick.Configuration{
|
||||
this.file = file;
|
||||
|
||||
IsMaximized = true;
|
||||
WindowLocation = new Point(32000,32000);
|
||||
WindowLocation = new Point(-32000,-32000);
|
||||
NotificationDuration = TweetNotification.Duration.Medium;
|
||||
NotificationPosition = TweetNotification.Position.TopRight;
|
||||
CustomNotificationPosition = new Point(32000,32000);
|
||||
CustomNotificationPosition = new Point(-32000,-32000);
|
||||
NotificationEdgeDistance = 8;
|
||||
}
|
||||
|
||||
@@ -70,8 +72,8 @@ namespace TweetDick.Configuration{
|
||||
}
|
||||
|
||||
return true;
|
||||
}catch(Exception){
|
||||
// TODO
|
||||
}catch(Exception e){
|
||||
Program.HandleException("Could not save the configuration file.",e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -89,8 +91,8 @@ namespace TweetDick.Configuration{
|
||||
|
||||
break;
|
||||
}catch(FileNotFoundException){
|
||||
}catch(Exception){
|
||||
// TODO
|
||||
}catch(Exception e){
|
||||
Program.HandleException("Could not open the configuration file.",e);
|
||||
}
|
||||
}
|
||||
|
||||
|
2
Core/Controls/FlatProgressBar.Designer.cs
generated
2
Core/Controls/FlatProgressBar.Designer.cs
generated
@@ -10,6 +10,8 @@
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing) {
|
||||
if (brush != null)brush.Dispose();
|
||||
|
||||
if (disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
|
2
Core/FormBrowser.Designer.cs
generated
2
Core/FormBrowser.Designer.cs
generated
@@ -31,7 +31,7 @@
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Icon = TweetDick.Properties.Resources.icon;
|
||||
this.Location = new System.Drawing.Point(32000, 32000);
|
||||
this.Location = new System.Drawing.Point(-32000, -32000);
|
||||
this.Name = "FormBrowser";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.ResizeEnd += new System.EventHandler(this.FormBrowser_ResizeEnd);
|
||||
|
@@ -23,6 +23,7 @@ namespace TweetDick.Core{
|
||||
|
||||
private FormSettings currentFormSettings;
|
||||
private FormAbout currentFormAbout;
|
||||
private bool isLoaded;
|
||||
|
||||
public FormBrowser(){
|
||||
InitializeComponent();
|
||||
@@ -38,7 +39,9 @@ namespace TweetDick.Core{
|
||||
|
||||
Controls.Add(browser);
|
||||
|
||||
notification = new FormNotification(this,bridge,true);
|
||||
Disposed += (sender, args) => browser.Dispose();
|
||||
|
||||
notification = new FormNotification(this,bridge,true){ CanMoveWindow = () => false };
|
||||
notification.Show();
|
||||
}
|
||||
|
||||
@@ -70,6 +73,8 @@ namespace TweetDick.Core{
|
||||
Size = Screen.PrimaryScreen.WorkingArea.Size;
|
||||
WindowState = FormWindowState.Maximized;
|
||||
}
|
||||
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
// active event handlers
|
||||
@@ -92,12 +97,16 @@ namespace TweetDick.Core{
|
||||
}
|
||||
|
||||
private void FormBrowser_ResizeEnd(object sender, EventArgs e){ // also triggers when the window moves
|
||||
if (!isLoaded)return;
|
||||
|
||||
Config.WindowLocation = Location;
|
||||
Config.WindowSize = Size;
|
||||
Config.Save();
|
||||
}
|
||||
|
||||
private void FormBrowser_WindowStateChanged(object sender, EventArgs e){
|
||||
if (!isLoaded)return;
|
||||
|
||||
Config.IsMaximized = WindowState != FormWindowState.Normal;
|
||||
FormBrowser_ResizeEnd(sender,e);
|
||||
}
|
||||
|
2
Core/FormNotification.Designer.cs
generated
2
Core/FormNotification.Designer.cs
generated
@@ -65,7 +65,7 @@
|
||||
this.Controls.Add(this.progressBarTimer);
|
||||
this.Controls.Add(this.panelBrowser);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Location = new System.Drawing.Point(32000, 32000);
|
||||
this.Location = new System.Drawing.Point(-32000, -32000);
|
||||
this.Name = "FormNotification";
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
|
@@ -10,6 +10,8 @@ using TweetDick.Resources;
|
||||
|
||||
namespace TweetDick.Core{
|
||||
sealed partial class FormNotification : Form{
|
||||
public Func<bool> CanMoveWindow = () => true;
|
||||
|
||||
private readonly Form owner;
|
||||
private readonly ChromiumWebBrowser browser;
|
||||
|
||||
@@ -39,6 +41,8 @@ namespace TweetDick.Core{
|
||||
}
|
||||
|
||||
panelBrowser.Controls.Add(browser);
|
||||
|
||||
Disposed += (sender, args) => browser.Dispose();
|
||||
}
|
||||
|
||||
public FormNotification(Form owner, bool autoHide) : this(owner,null,autoHide){}
|
||||
@@ -49,6 +53,14 @@ namespace TweetDick.Core{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m){
|
||||
if (m.Msg == 0x0112 && (m.WParam.ToInt32() & 0xFFF0) == 0xF010 && !CanMoveWindow()){ // WM_SYSCOMMAND, SC_MOVE
|
||||
return;
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
public void ShowNotification(TweetNotification notification){
|
||||
MoveToVisibleLocation();
|
||||
|
||||
@@ -76,7 +88,7 @@ namespace TweetDick.Core{
|
||||
|
||||
public void HideNotification(){
|
||||
browser.LoadHtml("","about:blank");
|
||||
Location = new Point(32000,32000);
|
||||
Location = new Point(-32000,-32000);
|
||||
TopMost = false;
|
||||
timerProgress.Stop();
|
||||
}
|
||||
|
@@ -20,8 +20,7 @@ namespace TweetDick.Core.Other{
|
||||
|
||||
Text = Program.BrandName+" Settings";
|
||||
|
||||
notification = new FormNotification(browserForm,false);
|
||||
notification.Show(this);
|
||||
notification = new FormNotification(browserForm,false){ CanMoveWindow = () => radioLocCustom.Checked };
|
||||
|
||||
notification.Move += (sender, args) => {
|
||||
if (radioLocCustom.Checked){
|
||||
@@ -29,6 +28,8 @@ namespace TweetDick.Core.Other{
|
||||
}
|
||||
};
|
||||
|
||||
notification.Show(this);
|
||||
|
||||
switch(Config.NotificationPosition){
|
||||
case TweetNotification.Position.TopLeft: radioLocTL.Checked = true; break;
|
||||
case TweetNotification.Position.TopRight: radioLocTR.Checked = true; break;
|
||||
|
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
@@ -14,8 +16,11 @@ namespace TweetDick.Migration{
|
||||
|
||||
public static void Run(){
|
||||
if (!Program.UserConfig.IgnoreMigration && Directory.Exists(TweetDeckPath)){
|
||||
FormMigrationQuestion formQuestion = new FormMigrationQuestion();
|
||||
MigrationDecision decision = formQuestion.ShowDialog() == DialogResult.OK ? formQuestion.Decision : MigrationDecision.AskLater;
|
||||
MigrationDecision decision;
|
||||
|
||||
using(FormMigrationQuestion formQuestion = new FormMigrationQuestion()){
|
||||
decision = formQuestion.ShowDialog() == DialogResult.OK ? formQuestion.Decision : MigrationDecision.AskLater;
|
||||
}
|
||||
|
||||
switch(decision){
|
||||
case MigrationDecision.MigratePurge:
|
||||
@@ -25,12 +30,13 @@ namespace TweetDick.Migration{
|
||||
|
||||
formWait.ShowWorkDialog(() => {
|
||||
if (!BeginMigration(decision,ex => formWait.Invoke(new Action(() => {
|
||||
if (ex != null){
|
||||
MessageBox.Show(ex.ToString()); // TODO
|
||||
}
|
||||
|
||||
formWait.Close();
|
||||
|
||||
if (ex != null){
|
||||
Program.HandleException("An unexpected exception has occurred during the migration process.",ex);
|
||||
return;
|
||||
}
|
||||
|
||||
Program.UserConfig.IgnoreMigration = true;
|
||||
Program.UserConfig.Save();
|
||||
})))){
|
||||
@@ -46,6 +52,17 @@ namespace TweetDick.Migration{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!Program.UserConfig.IgnoreUninstallCheck){
|
||||
string guid = ProgramRegistrySearch.FindByDisplayName("TweetDeck");
|
||||
|
||||
if (guid != null && MessageBox.Show("TweetDeck is still installed on your computer, do you want to uninstall it?","Uninstall TweetDeck",MessageBoxButtons.YesNo,MessageBoxIcon.Question,MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
RunUninstaller(guid,0);
|
||||
CleanupTweetDeck();
|
||||
}
|
||||
|
||||
Program.UserConfig.IgnoreUninstallCheck = true;
|
||||
Program.UserConfig.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool BeginMigration(MigrationDecision decision, Action<Exception> onFinished){
|
||||
@@ -98,14 +115,10 @@ namespace TweetDick.Migration{
|
||||
}
|
||||
|
||||
if (decision == MigrationDecision.MigratePurge){
|
||||
// update the lnk files wherever possible (desktop icons, pinned taskbar)
|
||||
string[] locations = {
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory),
|
||||
Environment.ExpandEnvironmentVariables(@"%APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar")
|
||||
};
|
||||
// update the lnk files wherever possible (desktop icons, pinned taskbar, start menu)
|
||||
foreach(string location in GetLnkDirectories()){
|
||||
if (location == string.Empty)continue;
|
||||
|
||||
foreach(string location in locations){
|
||||
string linkFile = Path.Combine(location,"TweetDeck.lnk");
|
||||
|
||||
if (File.Exists(linkFile)){
|
||||
@@ -115,7 +128,18 @@ namespace TweetDick.Migration{
|
||||
lnk.SetComment(Program.BrandName); // TODO add a tagline
|
||||
lnk.Save();
|
||||
|
||||
File.Move(linkFile,Path.Combine(location,Program.BrandName+".lnk"));
|
||||
string renamed = Path.Combine(location,Program.BrandName+".lnk");
|
||||
|
||||
try{
|
||||
if (!File.Exists(renamed)){
|
||||
File.Move(linkFile,renamed);
|
||||
}
|
||||
else{
|
||||
File.Delete(linkFile);
|
||||
}
|
||||
}catch{
|
||||
// eh, too bad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,12 +149,11 @@ namespace TweetDick.Migration{
|
||||
string guid = ProgramRegistrySearch.FindByDisplayName("TweetDeck");
|
||||
|
||||
if (guid != null){
|
||||
Process uninstaller = Process.Start("msiexec.exe","/x"+guid+" /quiet /qn");
|
||||
RunUninstaller(guid,5000);
|
||||
}
|
||||
|
||||
if (uninstaller != null){
|
||||
uninstaller.WaitForExit();
|
||||
}
|
||||
}
|
||||
// registry cleanup
|
||||
CleanupTweetDeck();
|
||||
|
||||
// migration finished like a boss
|
||||
}
|
||||
@@ -149,5 +172,41 @@ namespace TweetDick.Migration{
|
||||
}catch(DirectoryNotFoundException){
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetLnkDirectories(){
|
||||
yield return Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
|
||||
yield return Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory);
|
||||
yield return Environment.ExpandEnvironmentVariables(@"%APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar");
|
||||
|
||||
/* already handled by the installer
|
||||
string startMenu = Environment.GetFolderPath(Environment.SpecialFolder.StartMenu);
|
||||
string[] sub = Directory.GetDirectories(startMenu);
|
||||
|
||||
if (sub.Length > 0){
|
||||
yield return Path.Combine(startMenu,sub[0],"TweetDeck");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private static void RunUninstaller(string guid, int timeout){
|
||||
Process uninstaller = Process.Start("msiexec.exe","/x "+guid+" /quiet /qn");
|
||||
|
||||
if (uninstaller != null){
|
||||
if (timeout > 0){
|
||||
uninstaller.WaitForExit(timeout); // it appears that the process is restarted or something that triggers this, but it shouldn't be a problem
|
||||
}
|
||||
|
||||
uninstaller.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void CleanupTweetDeck(){
|
||||
try{
|
||||
Registry.CurrentUser.DeleteSubKeyTree(@"Software\Twitter\TweetDeck",true);
|
||||
Registry.CurrentUser.DeleteSubKey(@"Software\Twitter"); // only if empty
|
||||
}catch(Exception){
|
||||
// not found or too bad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
Program.cs
42
Program.cs
@@ -1,13 +1,16 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using TweetDick.Configuration;
|
||||
using TweetDick.Core;
|
||||
using TweetDick.Migration;
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
namespace TweetDick{
|
||||
static class Program{
|
||||
#if DUCK
|
||||
@@ -19,7 +22,7 @@ namespace TweetDick{
|
||||
#endif
|
||||
|
||||
public static readonly string StoragePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),BrandName);
|
||||
private static readonly LockManager LockManager;
|
||||
private static readonly LockManager LockManager = new LockManager(Path.Combine(StoragePath,".lock"));
|
||||
|
||||
public static UserConfig UserConfig { get; private set; }
|
||||
|
||||
@@ -36,10 +39,6 @@ namespace TweetDick{
|
||||
}
|
||||
}
|
||||
|
||||
static Program(){
|
||||
LockManager = new LockManager(Path.Combine(StoragePath,".lock"));
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr LoadLibrary(string name);
|
||||
|
||||
@@ -82,6 +81,14 @@ namespace TweetDick{
|
||||
#endif
|
||||
});
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, args) => {
|
||||
Exception ex = args.ExceptionObject as Exception;
|
||||
|
||||
if (ex != null){
|
||||
HandleException("An unhandled exception has occurred.",ex);
|
||||
}
|
||||
};
|
||||
|
||||
Application.ApplicationExit += (sender, args) => {
|
||||
UserConfig.Save();
|
||||
LockManager.Unlock();
|
||||
@@ -90,5 +97,30 @@ namespace TweetDick{
|
||||
|
||||
Application.Run(new FormBrowser());
|
||||
}
|
||||
|
||||
public static void HandleException(string message, Exception e){
|
||||
Log(e.ToString());
|
||||
|
||||
if (MessageBox.Show(message+"\r\nDo you want to open the log file to report the issue?",BrandName+" Has Failed :(",MessageBoxButtons.YesNo,MessageBoxIcon.Error,MessageBoxDefaultButton.Button2) == DialogResult.Yes){
|
||||
Process.Start(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"td-log.txt"));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Log(string data){
|
||||
StringBuilder build = new StringBuilder();
|
||||
|
||||
if (!File.Exists("td-log.txt")){
|
||||
build.Append("Please, report all issues to: https://github.com/chylex/TweetDick/issues\r\n\r\n");
|
||||
}
|
||||
|
||||
build.Append("[").Append(DateTime.Now.ToString("G")).Append("]\r\n");
|
||||
build.Append(data).Append("\r\n\r\n");
|
||||
|
||||
try{
|
||||
File.AppendAllText("td-log.txt",build.ToString(),Encoding.UTF8);
|
||||
}catch{
|
||||
// oops
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,13 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using TweetDick;
|
||||
using System.Resources;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle(Program.BrandName)]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyTitle("TweetDeck client for Windows")]
|
||||
[assembly: AssemblyDescription("TweetDeck client for Windows")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct(Program.BrandName)]
|
||||
@@ -32,5 +33,7 @@ using TweetDick;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.9.1.0")]
|
||||
[assembly: AssemblyFileVersion("0.9.1.0")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
[assembly: NeutralResourcesLanguageAttribute("en")]
|
@@ -22,7 +22,7 @@
|
||||
$("[data-action='settings-menu']").click(function(){
|
||||
setTimeout(function(){
|
||||
var menu = $(".js-dropdown-content").children("ul").first();
|
||||
if (menu.length == 0)return;
|
||||
if (menu.length === 0)return;
|
||||
|
||||
menu.children(".drp-h-divider").last().after('<li class="is-selectable" data-std><a href="#" data-action>'+$TD.brandName+'</a></li><li class="drp-h-divider"></li>');
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
mid = mid.children(".js-column-scroller").first();
|
||||
|
||||
var container = mid.children(".js-chirp-container").first();
|
||||
if (container.length == 0)return;
|
||||
if (container.length === 0)return;
|
||||
|
||||
var scroller = container.parent();
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
Array.prototype.forEach.call(mutations,function(mutation){
|
||||
Array.prototype.forEach.call(mutation.addedNodes,function(node){
|
||||
if (node.tagName != "ARTICLE")return;
|
||||
if (node.tagName !== "ARTICLE")return;
|
||||
|
||||
onNewTweet(column,node);
|
||||
});
|
||||
@@ -213,8 +213,9 @@
|
||||
if (urlWait)return;
|
||||
|
||||
var me = $(this);
|
||||
var rel = me.attr("rel");
|
||||
|
||||
if (!me.is(".link-complex") && !(me.attr("rel") == "mediaPreview" && me.closest("#open-modal").length == 0)){
|
||||
if (!me.is(".link-complex") && !(rel === "mediaPreview" && me.closest("#open-modal").length === 0) && rel !== "list"){
|
||||
$TD.openBrowser(me.attr("href"));
|
||||
}
|
||||
|
||||
|
4
_postbuild.bat
Normal file
4
_postbuild.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
del "bin\x86\Release Dick\*.xml"
|
||||
del "bin\x86\Release Dick\devtools_resources.pak"
|
||||
del "bin\x86\Release Duck\*.xml"
|
||||
del "bin\x86\Release Duck\devtools_resources.pak"
|
Reference in New Issue
Block a user