mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-01 17:34:10 +02:00
Address inspections
This commit is contained in:
parent
c4aa62fc3a
commit
933e0e54df
lib
TweetLib.Browser.CEF
Data
Logic
TweetLib.Browser
TweetLib.Core
App.cs
Features
Notifications
Plugins
PropertyObjectScript.csTweetDeck
Twitter
Systems
Configuration
Dialogs
Startup
Updates
TweetLib.Utils
Collections
Data
IO
Serialization
windows
@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace TweetLib.Browser.CEF.Data {
|
namespace TweetLib.Browser.CEF.Data {
|
||||||
public abstract class ContextMenuActionRegistry<T> {
|
abstract class ContextMenuActionRegistry<T> {
|
||||||
private readonly Dictionary<T, Action> actions = new ();
|
private readonly Dictionary<T, Action> actions = new ();
|
||||||
|
|
||||||
protected abstract T NextId(int n);
|
protected abstract T NextId(int n);
|
||||||
|
@ -28,7 +28,7 @@ public abstract class ContextMenuLogic {
|
|||||||
206 // AddToDictionary
|
206 // AddToDictionary
|
||||||
};
|
};
|
||||||
|
|
||||||
protected sealed class ContextMenuActionRegistry : ContextMenuActionRegistry<int> {
|
private protected sealed class ContextMenuActionRegistry : ContextMenuActionRegistry<int> {
|
||||||
private const int CommandUserFirst = 26500;
|
private const int CommandUserFirst = 26500;
|
||||||
|
|
||||||
protected override int NextId(int n) {
|
protected override int NextId(int n) {
|
||||||
|
@ -30,19 +30,16 @@ public bool OnBeforeResourceLoad(TRequest request, IDisposable callback) {
|
|||||||
if (resourceRequestHandler != null) {
|
if (resourceRequestHandler != null) {
|
||||||
var result = resourceRequestHandler.Handle(requestAdapter.GetUrl(request), requestAdapter.GetResourceType(request));
|
var result = resourceRequestHandler.Handle(requestAdapter.GetUrl(request), requestAdapter.GetResourceType(request));
|
||||||
|
|
||||||
switch (result) {
|
if (result is RequestHandleResult.Redirect redirect) {
|
||||||
case RequestHandleResult.Redirect redirect:
|
requestAdapter.SetUrl(request, redirect.Url);
|
||||||
requestAdapter.SetUrl(request, redirect.Url);
|
}
|
||||||
break;
|
else if (result is RequestHandleResult.Process process) {
|
||||||
|
requestAdapter.SetHeader(request, "Accept-Encoding", "identity");
|
||||||
case RequestHandleResult.Process process:
|
responseProcessors[requestAdapter.GetIdentifier(request)] = process.Processor;
|
||||||
requestAdapter.SetHeader(request, "Accept-Encoding", "identity");
|
}
|
||||||
responseProcessors[requestAdapter.GetIdentifier(request)] = process.Processor;
|
else if (result == RequestHandleResult.Cancel) {
|
||||||
break;
|
callback.Dispose();
|
||||||
|
return false;
|
||||||
case RequestHandleResult.Cancel:
|
|
||||||
callback.Dispose();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
using TweetLib.Browser.Request;
|
using TweetLib.Browser.Request;
|
||||||
|
|
||||||
namespace TweetLib.Browser.CEF.Logic {
|
namespace TweetLib.Browser.CEF.Logic {
|
||||||
internal abstract class SchemeResourceVisitor {
|
abstract class SchemeResourceVisitor {
|
||||||
protected static readonly SchemeResource.Status FileIsEmpty = new (HttpStatusCode.NoContent, "File is empty.");
|
protected static readonly SchemeResource.Status FileIsEmpty = new (HttpStatusCode.NoContent, "File is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class SchemeResourceVisitor<TResourceHandler> : SchemeResourceVisitor, ISchemeResourceVisitor<TResourceHandler> {
|
sealed class SchemeResourceVisitor<TResourceHandler> : SchemeResourceVisitor, ISchemeResourceVisitor<TResourceHandler> {
|
||||||
private readonly IResourceHandlerFactory<TResourceHandler> factory;
|
private readonly IResourceHandlerFactory<TResourceHandler> factory;
|
||||||
|
|
||||||
public SchemeResourceVisitor(IResourceHandlerFactory<TResourceHandler> factory) {
|
public SchemeResourceVisitor(IResourceHandlerFactory<TResourceHandler> factory) {
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace TweetLib.Browser.Interfaces {
|
|
||||||
public interface IResourceProvider<T> {
|
|
||||||
T Status(HttpStatusCode code, string message);
|
|
||||||
T File(byte[] contents, string extension);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,9 @@
|
|||||||
using TweetLib.Browser.Interfaces;
|
using TweetLib.Browser.Interfaces;
|
||||||
|
|
||||||
namespace TweetLib.Browser.Request {
|
namespace TweetLib.Browser.Request {
|
||||||
public abstract class RequestHandleResult {
|
public class RequestHandleResult {
|
||||||
|
public static RequestHandleResult Cancel { get; } = new ();
|
||||||
|
|
||||||
private RequestHandleResult() {}
|
private RequestHandleResult() {}
|
||||||
|
|
||||||
public sealed class Redirect : RequestHandleResult {
|
public sealed class Redirect : RequestHandleResult {
|
||||||
@ -19,11 +21,5 @@ public Process(IResponseProcessor processor) {
|
|||||||
Processor = processor;
|
Processor = processor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class Cancel : RequestHandleResult {
|
|
||||||
public static Cancel Instance { get; } = new ();
|
|
||||||
|
|
||||||
private Cancel() {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,22 +17,23 @@ public static class App {
|
|||||||
public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
|
public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
public static readonly bool IsPortable = Setup.IsPortable;
|
public static readonly bool IsPortable = Setup.IsPortable;
|
||||||
|
|
||||||
public static readonly string ResourcesPath = Path.Combine(ProgramPath, "resources");
|
internal static readonly string ResourcesPath = Path.Combine(ProgramPath, "resources");
|
||||||
public static readonly string PluginPath = Path.Combine(ProgramPath, "plugins");
|
internal static readonly string PluginPath = Path.Combine(ProgramPath, "plugins");
|
||||||
public static readonly string GuidePath = Path.Combine(ProgramPath, "guide");
|
internal static readonly string GuidePath = Path.Combine(ProgramPath, "guide");
|
||||||
|
|
||||||
public static readonly string StoragePath = IsPortable ? Path.Combine(ProgramPath, "portable", "storage") : GetDataFolder();
|
public static readonly string StoragePath = IsPortable ? Path.Combine(ProgramPath, "portable", "storage") : GetDataFolder();
|
||||||
|
public static readonly string LogoPath = Path.Combine(ResourcesPath, "images/logo.png");
|
||||||
|
|
||||||
public static Logger Logger { get; } = new (Path.Combine(StoragePath, "TD_Log.txt"), Setup.IsDebugLogging);
|
public static Logger Logger { get; } = new (Path.Combine(StoragePath, "TD_Log.txt"), Setup.IsDebugLogging);
|
||||||
public static ConfigManager ConfigManager { get; } = Setup.CreateConfigManager(StoragePath);
|
public static ConfigManager ConfigManager { get; } = Setup.CreateConfigManager(StoragePath);
|
||||||
|
|
||||||
public static IAppErrorHandler ErrorHandler { get; } = Validate(Builder.ErrorHandler, nameof(Builder.ErrorHandler));
|
public static IAppErrorHandler ErrorHandler { get; } = Validate(Builder.ErrorHandler, nameof(Builder.ErrorHandler));
|
||||||
public static IAppSystemHandler SystemHandler { get; } = Validate(Builder.SystemHandler, nameof(Builder.SystemHandler));
|
public static IAppSystemHandler SystemHandler { get; } = Validate(Builder.SystemHandler, nameof(Builder.SystemHandler));
|
||||||
public static IAppMessageDialogs MessageDialogs { get; } = Validate(Builder.MessageDialogs, nameof(Builder.MessageDialogs));
|
|
||||||
public static IAppFileDialogs? FileDialogs { get; } = Builder.FileDialogs;
|
internal static IAppMessageDialogs MessageDialogs { get; } = Validate(Builder.MessageDialogs, nameof(Builder.MessageDialogs));
|
||||||
|
internal static IAppFileDialogs? FileDialogs { get; } = Builder.FileDialogs;
|
||||||
|
|
||||||
internal static IAppUserConfiguration UserConfiguration => ConfigManager.User;
|
internal static IAppUserConfiguration UserConfiguration => ConfigManager.User;
|
||||||
internal static IAppSystemConfiguration SystemConfiguration => ConfigManager.System;
|
|
||||||
|
|
||||||
private static string GetDataFolder() {
|
private static string GetDataFolder() {
|
||||||
string? custom = Setup.CustomDataFolder;
|
string? custom = Setup.CustomDataFolder;
|
||||||
@ -75,7 +76,7 @@ internal static void Launch() {
|
|||||||
|
|
||||||
WebUtils.DefaultUserAgent = Lib.BrandName + " " + Version.Tag;
|
WebUtils.DefaultUserAgent = Lib.BrandName + " " + Version.Tag;
|
||||||
|
|
||||||
if (SystemConfiguration.UseSystemProxyForAllConnections) {
|
if (ConfigManager.System.UseSystemProxyForAllConnections) {
|
||||||
WebUtils.EnableSystemProxy();
|
WebUtils.EnableSystemProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using TweetLib.Utils.Data;
|
using TweetLib.Utils.Data;
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ public int GetDisplayDuration(int value) {
|
|||||||
return 2000 + Math.Max(1000, value * characters);
|
return 2000 + Math.Max(1000, value * characters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateHtml(string bodyClasses, string? headLayout, string? customStyles, IEnumerable<InjectedString> injections, string[] scripts) { // TODO
|
internal string GenerateHtml(string bodyClasses, string? headLayout, string? customStyles, IEnumerable<InjectedString> injections, string[] scripts) { // TODO
|
||||||
headLayout ??= DefaultHeadLayout;
|
headLayout ??= DefaultHeadLayout;
|
||||||
customStyles ??= string.Empty;
|
customStyles ??= string.Empty;
|
||||||
|
|
||||||
@ -71,12 +72,7 @@ public string GenerateHtml(string bodyClasses, string? headLayout, string? custo
|
|||||||
build.Append("<tweetduck-script-placeholder></body></html>");
|
build.Append("<tweetduck-script-placeholder></body></html>");
|
||||||
|
|
||||||
string result = build.ToString();
|
string result = build.ToString();
|
||||||
|
return injections.Aggregate(result, static (current, injection) => injection.InjectInto(current)).Replace("<tweetduck-script-placeholder>", GenerateScripts(scripts));
|
||||||
foreach (var injection in injections) {
|
|
||||||
result = injection.InjectInto(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.Replace("<tweetduck-script-placeholder>", GenerateScripts(scripts));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateScripts(string[] scripts) {
|
private string GenerateScripts(string[] scripts) {
|
||||||
|
@ -13,7 +13,7 @@ internal static void SetNotificationLayout(string? fontSize, string? headLayout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string? FontSize { get; private set; }
|
public static string? FontSize { get; private set; }
|
||||||
public static string? HeadLayout { get; private set; }
|
private static string? HeadLayout { get; set; }
|
||||||
|
|
||||||
private NotificationBrowser(IBrowserComponent browserComponent, Func<NotificationBrowser, BrowserSetup> setup) : base(browserComponent, setup) {}
|
private NotificationBrowser(IBrowserComponent browserComponent, Func<NotificationBrowser, BrowserSetup> setup) : base(browserComponent, setup) {}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ namespace TweetLib.Core.Features.Plugins.Config {
|
|||||||
public sealed class PluginConfig : IConfigObject<PluginConfig> {
|
public sealed class PluginConfig : IConfigObject<PluginConfig> {
|
||||||
internal IEnumerable<string> DisabledPlugins => disabled;
|
internal IEnumerable<string> DisabledPlugins => disabled;
|
||||||
|
|
||||||
public event EventHandler<PluginChangedStateEventArgs>? PluginChangedState;
|
internal event EventHandler<PluginChangedStateEventArgs>? PluginChangedState;
|
||||||
|
|
||||||
private readonly HashSet<string> defaultDisabled;
|
private readonly HashSet<string> defaultDisabled;
|
||||||
private readonly HashSet<string> disabled;
|
private readonly HashSet<string> disabled;
|
||||||
|
@ -6,12 +6,11 @@
|
|||||||
|
|
||||||
namespace TweetLib.Core.Features.Plugins.Config {
|
namespace TweetLib.Core.Features.Plugins.Config {
|
||||||
sealed class PluginConfigInstance : IConfigInstance {
|
sealed class PluginConfigInstance : IConfigInstance {
|
||||||
public PluginConfig Instance { get; }
|
private readonly PluginConfig instance;
|
||||||
|
|
||||||
private readonly string filename;
|
private readonly string filename;
|
||||||
|
|
||||||
public PluginConfigInstance(string filename, PluginConfig instance) {
|
public PluginConfigInstance(string filename, PluginConfig instance) {
|
||||||
this.Instance = instance;
|
this.instance = instance;
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +26,7 @@ public void Load() {
|
|||||||
newDisabled.Add(line);
|
newDisabled.Add(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance.Reset(newDisabled);
|
instance.Reset(newDisabled);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException) {
|
} catch (FileNotFoundException) {
|
||||||
// ignore
|
// ignore
|
||||||
@ -43,7 +42,7 @@ public void Save() {
|
|||||||
using var writer = new StreamWriter(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None), Encoding.UTF8);
|
using var writer = new StreamWriter(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None), Encoding.UTF8);
|
||||||
writer.WriteLine("#Disabled");
|
writer.WriteLine("#Disabled");
|
||||||
|
|
||||||
foreach (string identifier in Instance.DisabledPlugins) {
|
foreach (string identifier in instance.DisabledPlugins) {
|
||||||
writer.WriteLine(identifier);
|
writer.WriteLine(identifier);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -58,7 +57,7 @@ public void Reload() {
|
|||||||
public void Reset() {
|
public void Reset() {
|
||||||
try {
|
try {
|
||||||
File.Delete(filename);
|
File.Delete(filename);
|
||||||
Instance.ResetToDefault();
|
instance.ResetToDefault();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
OnException("Could not delete the plugin configuration file.", e);
|
OnException("Could not delete the plugin configuration file.", e);
|
||||||
return;
|
return;
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace TweetLib.Core.Features.Plugins.Enums {
|
namespace TweetLib.Core.Features.Plugins.Enums {
|
||||||
public enum PluginEnvironment {
|
enum PluginEnvironment {
|
||||||
Browser,
|
Browser,
|
||||||
Notification
|
Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class PluginEnvironments {
|
static class PluginEnvironments {
|
||||||
public static IEnumerable<PluginEnvironment> All { get; } = new PluginEnvironment[] {
|
public static IEnumerable<PluginEnvironment> All { get; } = new PluginEnvironment[] {
|
||||||
PluginEnvironment.Browser,
|
PluginEnvironment.Browser,
|
||||||
PluginEnvironment.Notification
|
PluginEnvironment.Notification
|
||||||
|
@ -7,7 +7,7 @@ public enum PluginGroup {
|
|||||||
Custom
|
Custom
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class PluginGroups {
|
static class PluginGroups {
|
||||||
public static IEnumerable<PluginGroup> All { get; } = new PluginGroup[] {
|
public static IEnumerable<PluginGroup> All { get; } = new PluginGroup[] {
|
||||||
PluginGroup.Official,
|
PluginGroup.Official,
|
||||||
PluginGroup.Custom
|
PluginGroup.Custom
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace TweetLib.Core.Features.Plugins.Events {
|
namespace TweetLib.Core.Features.Plugins.Events {
|
||||||
public sealed class PluginChangedStateEventArgs : EventArgs {
|
internal sealed class PluginChangedStateEventArgs : EventArgs {
|
||||||
public Plugin Plugin { get; }
|
public Plugin Plugin { get; }
|
||||||
public bool IsEnabled { get; }
|
public bool IsEnabled { get; }
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace TweetLib.Core.Features.Plugins.Events {
|
namespace TweetLib.Core.Features.Plugins.Events {
|
||||||
public sealed class PluginErrorEventArgs : EventArgs {
|
internal sealed class PluginErrorEventArgs : EventArgs {
|
||||||
public bool HasErrors => Errors.Count > 0;
|
public bool HasErrors => Errors.Count > 0;
|
||||||
|
|
||||||
public IList<string> Errors { get; }
|
public IList<string> Errors { get; }
|
||||||
|
@ -17,31 +17,32 @@ public sealed class Plugin {
|
|||||||
public string Author { get; }
|
public string Author { get; }
|
||||||
public string Version { get; }
|
public string Version { get; }
|
||||||
public string Website { get; }
|
public string Website { get; }
|
||||||
public string ConfigFile { get; }
|
|
||||||
public string ConfigDefault { get; }
|
|
||||||
public Version RequiredVersion { get; }
|
public Version RequiredVersion { get; }
|
||||||
|
|
||||||
public bool CanRun { get; }
|
public bool CanRun { get; }
|
||||||
|
|
||||||
public bool HasConfig {
|
internal bool HasConfig {
|
||||||
get => ConfigFile.Length > 0 && GetFullPathIfSafe(PluginFolder.Data, ConfigFile).Length > 0;
|
get => configFile.Length > 0 && GetFullPathIfSafe(PluginFolder.Data, configFile).Length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ConfigPath {
|
internal string ConfigPath {
|
||||||
get => HasConfig ? Path.Combine(GetPluginFolder(PluginFolder.Data), ConfigFile) : string.Empty;
|
get => HasConfig ? Path.Combine(GetPluginFolder(PluginFolder.Data), configFile) : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasDefaultConfig {
|
private bool HasDefaultConfig {
|
||||||
get => ConfigDefault.Length > 0 && GetFullPathIfSafe(PluginFolder.Root, ConfigDefault).Length > 0;
|
get => configDefault.Length > 0 && GetFullPathIfSafe(PluginFolder.Root, configDefault).Length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DefaultConfigPath {
|
private string DefaultConfigPath {
|
||||||
get => HasDefaultConfig ? Path.Combine(GetPluginFolder(PluginFolder.Root), ConfigDefault) : string.Empty;
|
get => HasDefaultConfig ? Path.Combine(GetPluginFolder(PluginFolder.Root), configDefault) : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly string pathRoot;
|
private readonly string pathRoot;
|
||||||
private readonly string pathData;
|
private readonly string pathData;
|
||||||
private readonly ISet<PluginEnvironment> environments;
|
private readonly ISet<PluginEnvironment> environments;
|
||||||
|
|
||||||
|
private readonly string configFile;
|
||||||
|
private readonly string configDefault;
|
||||||
|
|
||||||
private Plugin(PluginGroup group, string identifier, string pathRoot, string pathData, Builder builder) {
|
private Plugin(PluginGroup group, string identifier, string pathRoot, string pathData, Builder builder) {
|
||||||
this.pathRoot = pathRoot;
|
this.pathRoot = pathRoot;
|
||||||
@ -56,18 +57,18 @@ private Plugin(PluginGroup group, string identifier, string pathRoot, string pat
|
|||||||
this.Author = builder.Author;
|
this.Author = builder.Author;
|
||||||
this.Version = builder.Version;
|
this.Version = builder.Version;
|
||||||
this.Website = builder.Website;
|
this.Website = builder.Website;
|
||||||
this.ConfigFile = builder.ConfigFile;
|
this.configFile = builder.ConfigFile;
|
||||||
this.ConfigDefault = builder.ConfigDefault;
|
this.configDefault = builder.ConfigDefault;
|
||||||
this.RequiredVersion = builder.RequiredVersion;
|
this.RequiredVersion = builder.RequiredVersion;
|
||||||
|
|
||||||
this.CanRun = AppVersion >= RequiredVersion;
|
this.CanRun = AppVersion >= RequiredVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasEnvironment(PluginEnvironment environment) {
|
internal bool HasEnvironment(PluginEnvironment environment) {
|
||||||
return environments.Contains(environment);
|
return environments.Contains(environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetScriptPath(PluginEnvironment environment) {
|
internal string GetScriptPath(PluginEnvironment environment) {
|
||||||
return environments.Contains(environment) ? Path.Combine(pathRoot, environment.GetPluginScriptFile()) : string.Empty;
|
return environments.Contains(environment) ? Path.Combine(pathRoot, environment.GetPluginScriptFile()) : string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +80,7 @@ public string GetPluginFolder(PluginFolder folder) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetFullPathIfSafe(PluginFolder folder, string relativePath) {
|
internal string GetFullPathIfSafe(PluginFolder folder, string relativePath) {
|
||||||
string rootFolder = GetPluginFolder(folder);
|
string rootFolder = GetPluginFolder(folder);
|
||||||
return FileUtils.ResolveRelativePathSafely(rootFolder, relativePath);
|
return FileUtils.ResolveRelativePathSafely(rootFolder, relativePath);
|
||||||
}
|
}
|
||||||
@ -98,7 +99,7 @@ public override bool Equals(object obj) {
|
|||||||
|
|
||||||
// Builder
|
// Builder
|
||||||
|
|
||||||
public sealed class Builder {
|
internal sealed class Builder {
|
||||||
private static readonly Version DefaultRequiredVersion = new (0, 0, 0, 0);
|
private static readonly Version DefaultRequiredVersion = new (0, 0, 0, 0);
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
using TweetLib.Utils.Data;
|
using TweetLib.Utils.Data;
|
||||||
|
|
||||||
namespace TweetLib.Core.Features.Plugins {
|
namespace TweetLib.Core.Features.Plugins {
|
||||||
internal static class PluginLoader {
|
static class PluginLoader {
|
||||||
private static readonly string[] EndTag = { "[END]" };
|
private static readonly string[] EndTag = { "[END]" };
|
||||||
|
|
||||||
public static IEnumerable<Result<Plugin>> AllInFolder(string pluginFolder, string pluginDataFolder, PluginGroup group) {
|
public static IEnumerable<Result<Plugin>> AllInFolder(string pluginFolder, string pluginDataFolder, PluginGroup group) {
|
||||||
@ -38,7 +38,7 @@ public static IEnumerable<Result<Plugin>> AllInFolder(string pluginFolder, strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Plugin FromFolder(string name, string pathRoot, string pathData, PluginGroup group) {
|
private static Plugin FromFolder(string name, string pathRoot, string pathData, PluginGroup group) {
|
||||||
Plugin.Builder builder = new Plugin.Builder(group, name, pathRoot, pathData);
|
Plugin.Builder builder = new Plugin.Builder(group, name, pathRoot, pathData);
|
||||||
|
|
||||||
foreach (var environment in Directory.EnumerateFiles(pathRoot, "*.js", SearchOption.TopDirectoryOnly).Select(Path.GetFileName).Select(EnvironmentFromFileName)) {
|
foreach (var environment in Directory.EnumerateFiles(pathRoot, "*.js", SearchOption.TopDirectoryOnly).Select(Path.GetFileName).Select(EnvironmentFromFileName)) {
|
||||||
|
@ -18,15 +18,15 @@ public sealed class PluginManager {
|
|||||||
public string PluginFolder { get; }
|
public string PluginFolder { get; }
|
||||||
public string PluginDataFolder { get; }
|
public string PluginDataFolder { get; }
|
||||||
|
|
||||||
public event EventHandler<PluginErrorEventArgs>? Reloaded;
|
internal event EventHandler<PluginErrorEventArgs>? Reloaded;
|
||||||
public event EventHandler<PluginErrorEventArgs>? Executed;
|
internal event EventHandler<PluginErrorEventArgs>? Executed;
|
||||||
|
|
||||||
internal readonly PluginBridge bridge;
|
internal readonly PluginBridge bridge;
|
||||||
private IScriptExecutor? browserExecutor;
|
private IScriptExecutor? browserExecutor;
|
||||||
|
|
||||||
private readonly HashSet<Plugin> plugins = new ();
|
private readonly HashSet<Plugin> plugins = new ();
|
||||||
|
|
||||||
public PluginManager(PluginConfig config, string pluginFolder, string pluginDataFolder) {
|
internal PluginManager(PluginConfig config, string pluginFolder, string pluginDataFolder) {
|
||||||
this.Config = config;
|
this.Config = config;
|
||||||
this.Config.PluginChangedState += Config_PluginChangedState;
|
this.Config.PluginChangedState += Config_PluginChangedState;
|
||||||
this.PluginFolder = pluginFolder;
|
this.PluginFolder = pluginFolder;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
using TweetLib.Core.Features.Plugins.Enums;
|
using TweetLib.Core.Features.Plugins.Enums;
|
||||||
|
|
||||||
namespace TweetLib.Core.Features.Plugins {
|
namespace TweetLib.Core.Features.Plugins {
|
||||||
internal static class PluginScriptGenerator {
|
static class PluginScriptGenerator {
|
||||||
public static string GenerateConfig(PluginConfig config) {
|
public static string GenerateConfig(PluginConfig config) {
|
||||||
return "window.TD_PLUGINS_DISABLE = [" + string.Join(",", config.DisabledPlugins.Select(static id => '"' + id + '"')) + "]";
|
return "window.TD_PLUGINS_DISABLE = [" + string.Join(",", config.DisabledPlugins.Select(static id => '"' + id + '"')) + "]";
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
using TweetLib.Core.Features.Twitter;
|
using TweetLib.Core.Features.Twitter;
|
||||||
|
|
||||||
namespace TweetLib.Core.Features {
|
namespace TweetLib.Core.Features {
|
||||||
public static class PropertyObjectScript {
|
static class PropertyObjectScript {
|
||||||
public enum Environment {
|
internal enum Environment {
|
||||||
Browser,
|
Browser,
|
||||||
Notification
|
Notification
|
||||||
}
|
}
|
||||||
|
@ -247,10 +247,10 @@ private sealed class ResourceRequestHandler : BaseResourceRequestHandler {
|
|||||||
return new RequestHandleResult.Process(VendorScriptProcessor.Instance);
|
return new RequestHandleResult.Process(VendorScriptProcessor.Instance);
|
||||||
|
|
||||||
case ResourceType.Script when url.Contains("analytics."):
|
case ResourceType.Script when url.Contains("analytics."):
|
||||||
return RequestHandleResult.Cancel.Instance;
|
return RequestHandleResult.Cancel;
|
||||||
|
|
||||||
case ResourceType.Xhr when url.Contains(UrlVersionCheck):
|
case ResourceType.Xhr when url.Contains(UrlVersionCheck):
|
||||||
return RequestHandleResult.Cancel.Instance;
|
return RequestHandleResult.Cancel;
|
||||||
|
|
||||||
case ResourceType.Xhr when url.Contains("://api.twitter.com/") && url.Contains("include_entities=1") && !url.Contains("&include_ext_has_nft_avatar=1"):
|
case ResourceType.Xhr when url.Contains("://api.twitter.com/") && url.Contains("include_entities=1") && !url.Contains("&include_ext_has_nft_avatar=1"):
|
||||||
return new RequestHandleResult.Redirect(url.Replace("include_entities=1", "include_entities=1&include_ext_has_nft_avatar=1"));
|
return new RequestHandleResult.Redirect(url.Replace("include_entities=1", "include_entities=1&include_ext_has_nft_avatar=1"));
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using TweetLib.Utils.Static;
|
using TweetLib.Utils.Static;
|
||||||
|
|
||||||
namespace TweetLib.Core.Features.Twitter {
|
namespace TweetLib.Core.Features.Twitter {
|
||||||
|
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||||
public static class TwitterUrls {
|
public static class TwitterUrls {
|
||||||
public const string TweetDeck = "https://tweetdeck.twitter.com";
|
public const string TweetDeck = "https://tweetdeck.twitter.com";
|
||||||
private const string TwitterTrackingUrl = "t.co";
|
private const string TwitterTrackingUrl = "t.co";
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
namespace TweetLib.Core.Systems.Configuration {
|
namespace TweetLib.Core.Systems.Configuration {
|
||||||
sealed class FileConfigInstance<T> : IConfigInstance where T : IConfigObject<T> {
|
sealed class FileConfigInstance<T> : IConfigInstance where T : IConfigObject<T> {
|
||||||
public T Instance { get; }
|
private readonly T instance;
|
||||||
|
|
||||||
private readonly SimpleObjectSerializer<T> serializer;
|
private readonly SimpleObjectSerializer<T> serializer;
|
||||||
|
|
||||||
private readonly string filenameMain;
|
private readonly string filenameMain;
|
||||||
@ -13,7 +12,7 @@ sealed class FileConfigInstance<T> : IConfigInstance where T : IConfigObject<T>
|
|||||||
private readonly string identifier;
|
private readonly string identifier;
|
||||||
|
|
||||||
public FileConfigInstance(string filename, T instance, string identifier, TypeConverterRegistry converterRegistry) {
|
public FileConfigInstance(string filename, T instance, string identifier, TypeConverterRegistry converterRegistry) {
|
||||||
this.Instance = instance;
|
this.instance = instance;
|
||||||
this.serializer = new SimpleObjectSerializer<T>(converterRegistry);
|
this.serializer = new SimpleObjectSerializer<T>(converterRegistry);
|
||||||
|
|
||||||
this.filenameMain = filename ?? throw new ArgumentNullException(nameof(filename), "Config file name must not be null!");
|
this.filenameMain = filename ?? throw new ArgumentNullException(nameof(filename), "Config file name must not be null!");
|
||||||
@ -22,7 +21,7 @@ public FileConfigInstance(string filename, T instance, string identifier, TypeCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void LoadInternal(bool backup) {
|
private void LoadInternal(bool backup) {
|
||||||
serializer.Read(backup ? filenameBackup : filenameMain, Instance);
|
serializer.Read(backup ? filenameBackup : filenameMain, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load() {
|
public void Load() {
|
||||||
@ -64,7 +63,7 @@ public void Save() {
|
|||||||
File.Move(filenameMain, filenameBackup);
|
File.Move(filenameMain, filenameBackup);
|
||||||
}
|
}
|
||||||
|
|
||||||
serializer.Write(filenameMain, Instance);
|
serializer.Write(filenameMain, instance);
|
||||||
} catch (SerializationSoftException e) {
|
} catch (SerializationSoftException e) {
|
||||||
OnException($"{e.Errors.Count} error{(e.Errors.Count == 1 ? " was" : "s were")} encountered while saving the configuration file for {identifier}.", e);
|
OnException($"{e.Errors.Count} error{(e.Errors.Count == 1 ? " was" : "s were")} encountered while saving the configuration file for {identifier}.", e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -77,7 +76,7 @@ public void Reload() {
|
|||||||
LoadInternal(false);
|
LoadInternal(false);
|
||||||
} catch (FileNotFoundException) {
|
} catch (FileNotFoundException) {
|
||||||
try {
|
try {
|
||||||
serializer.Write(filenameMain, Instance.ConstructWithDefaults());
|
serializer.Write(filenameMain, instance.ConstructWithDefaults());
|
||||||
LoadInternal(false);
|
LoadInternal(false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
OnException($"Could not regenerate the configuration file for {identifier}.", e);
|
OnException($"Could not regenerate the configuration file for {identifier}.", e);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
namespace TweetLib.Core.Systems.Dialogs {
|
namespace TweetLib.Core.Systems.Dialogs {
|
||||||
public static class Dialogs {
|
internal static class Dialogs {
|
||||||
public const string OK = "OK";
|
public const string OK = "OK";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ public sealed class FileDialogFilter {
|
|||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public IReadOnlyList<string> Extensions { get; }
|
public IReadOnlyList<string> Extensions { get; }
|
||||||
|
|
||||||
public FileDialogFilter(string name, params string[] extensions) {
|
internal FileDialogFilter(string name, params string[] extensions) {
|
||||||
Name = name;
|
Name = name;
|
||||||
Extensions = extensions;
|
Extensions = extensions;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,11 @@ private LockResult DetermineLockingProcessOrFail(Exception originalException) {
|
|||||||
|
|
||||||
using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
|
using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
|
||||||
byte[] bytes = new byte[sizeof(int)];
|
byte[] bytes = new byte[sizeof(int)];
|
||||||
fileStream.Read(bytes, 0, bytes.Length);
|
|
||||||
|
if (fileStream.Read(bytes, 0, bytes.Length) != bytes.Length) {
|
||||||
|
throw new IOException("Read fewer bytes than requested!");
|
||||||
|
}
|
||||||
|
|
||||||
pid = BitConverter.ToInt32(bytes, 0);
|
pid = BitConverter.ToInt32(bytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ public enum UpdateDownloadStatus {
|
|||||||
|
|
||||||
public static class UpdateDownloadStatusExtensions {
|
public static class UpdateDownloadStatusExtensions {
|
||||||
public static bool IsFinished(this UpdateDownloadStatus status, bool canRetry) {
|
public static bool IsFinished(this UpdateDownloadStatus status, bool canRetry) {
|
||||||
return status == UpdateDownloadStatus.AssetMissing || status == UpdateDownloadStatus.Done || (status == UpdateDownloadStatus.Failed && !canRetry);
|
return status is UpdateDownloadStatus.AssetMissing or UpdateDownloadStatus.Done || (status == UpdateDownloadStatus.Failed && !canRetry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ internal void BeginSilentDownload() {
|
|||||||
internal void DeleteInstaller() {
|
internal void DeleteInstaller() {
|
||||||
DownloadStatus = UpdateDownloadStatus.None;
|
DownloadStatus = UpdateDownloadStatus.None;
|
||||||
|
|
||||||
if (currentDownload != null && currentDownload.IsBusy) {
|
if (currentDownload is { IsBusy: true }) {
|
||||||
currentDownload.CancelAsync(); // deletes file when cancelled
|
currentDownload.CancelAsync(); // deletes file when cancelled
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ public static CommandLineArgs FromStringArray(char entryChar, string[] array) {
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ReadStringArray(char entryChar, string[] array, CommandLineArgs targetArgs) {
|
private static void ReadStringArray(char entryChar, string[] array, CommandLineArgs targetArgs) {
|
||||||
for (int index = 0; index < array.Length; index++) {
|
for (int index = 0; index < array.Length; index++) {
|
||||||
string entry = array[index];
|
string entry = array[index];
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace TweetLib.Utils.Collections {
|
namespace TweetLib.Utils.Collections {
|
||||||
@ -8,6 +9,8 @@ namespace TweetLib.Utils.Collections {
|
|||||||
/// <typeparam name="K1">The type of the outer key.</typeparam>
|
/// <typeparam name="K1">The type of the outer key.</typeparam>
|
||||||
/// <typeparam name="K2">The type of the inner key.</typeparam>
|
/// <typeparam name="K2">The type of the inner key.</typeparam>
|
||||||
/// <typeparam name="V">The type of the values.</typeparam>
|
/// <typeparam name="V">The type of the values.</typeparam>
|
||||||
|
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
|
||||||
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
public sealed class TwoKeyDictionary<K1, K2, V> {
|
public sealed class TwoKeyDictionary<K1, K2, V> {
|
||||||
private readonly Dictionary<K1, Dictionary<K2, V>> dict;
|
private readonly Dictionary<K1, Dictionary<K2, V>> dict;
|
||||||
private readonly int innerCapacity;
|
private readonly int innerCapacity;
|
||||||
|
@ -30,10 +30,13 @@ public string InjectInto(string targetHTML) {
|
|||||||
case Position.Before:
|
case Position.Before:
|
||||||
cutIndex = index;
|
cutIndex = index;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Position.After:
|
case Position.After:
|
||||||
cutIndex = index + search.Length;
|
cutIndex = index + search.Length;
|
||||||
break;
|
break;
|
||||||
default: return targetHTML;
|
|
||||||
|
default:
|
||||||
|
return targetHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetHTML.Insert(cutIndex, html);
|
return targetHTML.Insert(cutIndex, html);
|
||||||
|
@ -21,6 +21,15 @@ private static string JoinIdentifier(string[] identifier) {
|
|||||||
return string.Join(KeySeparator.ToString(), identifier.Select(ValidateIdentifier));
|
return string.Join(KeySeparator.ToString(), identifier.Select(ValidateIdentifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ReadExactly(Stream stream, byte[] buffer) {
|
||||||
|
var length = buffer.Length;
|
||||||
|
var read = stream.Read(buffer, 0, length);
|
||||||
|
|
||||||
|
if (read != length) {
|
||||||
|
throw new IOException("Read fewer bytes than requested: " + read + " < " + length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly Stream stream;
|
private readonly Stream stream;
|
||||||
|
|
||||||
public CombinedFileStream(Stream stream) {
|
public CombinedFileStream(Stream stream) {
|
||||||
@ -79,13 +88,13 @@ private void WriteStreamImpl(string identifier, Stream sourceStream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte[] name = new byte[nameLength];
|
byte[] name = new byte[nameLength];
|
||||||
stream.Read(name, 0, nameLength);
|
ReadExactly(stream, name);
|
||||||
|
|
||||||
byte[] contentLength = new byte[4];
|
byte[] contentLength = new byte[4];
|
||||||
stream.Read(contentLength, 0, 4);
|
ReadExactly(stream, contentLength);
|
||||||
|
|
||||||
byte[] contents = new byte[BitConverter.ToInt32(contentLength, 0)];
|
byte[] contents = new byte[BitConverter.ToInt32(contentLength, 0)];
|
||||||
stream.Read(contents, 0, contents.Length);
|
ReadExactly(stream, contents);
|
||||||
|
|
||||||
return new Entry(Encoding.UTF8.GetString(name), contents);
|
return new Entry(Encoding.UTF8.GetString(name), contents);
|
||||||
}
|
}
|
||||||
@ -98,10 +107,10 @@ private void WriteStreamImpl(string identifier, Stream sourceStream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte[] name = new byte[nameLength];
|
byte[] name = new byte[nameLength];
|
||||||
stream.Read(name, 0, nameLength);
|
ReadExactly(stream, name);
|
||||||
|
|
||||||
byte[] contentLength = new byte[4];
|
byte[] contentLength = new byte[4];
|
||||||
stream.Read(contentLength, 0, 4);
|
ReadExactly(stream, contentLength);
|
||||||
|
|
||||||
stream.Position += BitConverter.ToInt32(contentLength, 0);
|
stream.Position += BitConverter.ToInt32(contentLength, 0);
|
||||||
|
|
||||||
@ -120,9 +129,7 @@ void IDisposable.Dispose() {
|
|||||||
public sealed class Entry {
|
public sealed class Entry {
|
||||||
private string Identifier { get; }
|
private string Identifier { get; }
|
||||||
|
|
||||||
public string KeyName {
|
public string KeyName => StringUtils.ExtractBefore(Identifier, KeySeparator);
|
||||||
get { return StringUtils.ExtractBefore(Identifier, KeySeparator); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string[] KeyValue {
|
public string[] KeyValue {
|
||||||
get {
|
get {
|
||||||
|
@ -9,7 +9,7 @@ public void Register(Type type, ITypeConverter converter) {
|
|||||||
converters[type] = converter;
|
converters[type] = converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITypeConverter? TryGet(Type type) {
|
internal ITypeConverter? TryGet(Type type) {
|
||||||
return converters.TryGetValue(type, out var converter) ? converter : null;
|
return converters.TryGetValue(type, out var converter) ? converter : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public FormPlayer(IntPtr handle, int dpi, int volume, string url, string token)
|
|||||||
|
|
||||||
Marshal.ReleaseComObject(media);
|
Marshal.ReleaseComObject(media);
|
||||||
|
|
||||||
return $"{(progress / 60).ToString("00")}:{(progress % 60).ToString("00")}";
|
return $"{(progress / 60):00}:{(progress % 60):00}";
|
||||||
});
|
});
|
||||||
|
|
||||||
labelTooltip.AttachTooltip(trackBarVolume, false, args => $"Volume : {trackBarVolume.Value}%");
|
labelTooltip.AttachTooltip(trackBarVolume, false, args => $"Volume : {trackBarVolume.Value}%");
|
||||||
|
@ -8,8 +8,8 @@ namespace TweetDuck.Video {
|
|||||||
static class Program {
|
static class Program {
|
||||||
// referenced in VideoPlayer
|
// referenced in VideoPlayer
|
||||||
// set by task manager -- public const int "CodeProcessKilled" = 1;
|
// set by task manager -- public const int "CodeProcessKilled" = 1;
|
||||||
public const int CodeInvalidArgs = 2;
|
private const int CodeInvalidArgs = 2;
|
||||||
public const int CodeLaunchFail = 3;
|
private const int CodeLaunchFail = 3;
|
||||||
public const int CodeMediaError = 4;
|
public const int CodeMediaError = 4;
|
||||||
public const int CodeOwnerGone = 5;
|
public const int CodeOwnerGone = 5;
|
||||||
public const int CodeUserRequested = 6;
|
public const int CodeUserRequested = 6;
|
||||||
|
@ -18,14 +18,17 @@ private static NotificationBrowser CreateBrowserImpl(IBrowserComponent browserCo
|
|||||||
|
|
||||||
protected override FormBorderStyle NotificationBorderStyle {
|
protected override FormBorderStyle NotificationBorderStyle {
|
||||||
get {
|
get {
|
||||||
|
var style = base.NotificationBorderStyle;
|
||||||
|
|
||||||
if (Config.NotificationSize == DesktopNotification.Size.Custom) {
|
if (Config.NotificationSize == DesktopNotification.Size.Custom) {
|
||||||
switch (base.NotificationBorderStyle) {
|
return style switch {
|
||||||
case FormBorderStyle.FixedSingle: return FormBorderStyle.Sizable;
|
FormBorderStyle.FixedSingle => FormBorderStyle.Sizable,
|
||||||
case FormBorderStyle.FixedToolWindow: return FormBorderStyle.SizableToolWindow;
|
FormBorderStyle.FixedToolWindow => FormBorderStyle.SizableToolWindow,
|
||||||
}
|
_ => style
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.NotificationBorderStyle;
|
return style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,8 @@ private static int FontSizeLevel {
|
|||||||
|
|
||||||
private readonly int timerBarHeight;
|
private readonly int timerBarHeight;
|
||||||
|
|
||||||
protected int timeLeft, totalTime;
|
private int timeLeft;
|
||||||
|
protected int totalTime;
|
||||||
protected bool pausedDuringNotification;
|
protected bool pausedDuringNotification;
|
||||||
|
|
||||||
private readonly NativeMethods.HookProc mouseHookDelegate;
|
private readonly NativeMethods.HookProc mouseHookDelegate;
|
||||||
|
@ -48,7 +48,7 @@ public bool HasNotifications {
|
|||||||
private readonly ContextMenu contextMenu;
|
private readonly ContextMenu contextMenu;
|
||||||
private bool hasNotifications;
|
private bool hasNotifications;
|
||||||
|
|
||||||
public TrayIcon() {
|
private TrayIcon() {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
this.contextMenu = new ContextMenu();
|
this.contextMenu = new ContextMenu();
|
||||||
|
@ -32,7 +32,7 @@ public static CommandLineArgs GetCurrentClean() {
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CommandLineArgs GetCurrentForInstaller() {
|
private static CommandLineArgs GetCurrentForInstaller() {
|
||||||
CommandLineArgs args = GetCurrentClean();
|
CommandLineArgs args = GetCurrentClean();
|
||||||
args.AddFlag(ArgUpdated);
|
args.AddFlag(ArgUpdated);
|
||||||
return args;
|
return args;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
using TweetLib.Utils.Data;
|
using TweetLib.Utils.Data;
|
||||||
|
|
||||||
namespace TweetDuck.Configuration {
|
namespace TweetDuck.Configuration {
|
||||||
|
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
||||||
sealed class UserConfig : BaseConfig<UserConfig>, IAppUserConfiguration {
|
sealed class UserConfig : BaseConfig<UserConfig>, IAppUserConfiguration {
|
||||||
public bool FirstRun { get; set; } = true;
|
public bool FirstRun { get; set; } = true;
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using TweetDuck.Management;
|
using TweetDuck.Management;
|
||||||
using TweetLib.Core;
|
using TweetLib.Core;
|
||||||
@ -22,7 +21,7 @@ public FormAbout() {
|
|||||||
labelIssues.Links.Add(new LinkLabel.Link(0, labelIssues.Text.Length, Lib.IssueTrackerUrl));
|
labelIssues.Links.Add(new LinkLabel.Link(0, labelIssues.Text.Length, Lib.IssueTrackerUrl));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pictureLogo.Image = Image.FromFile(Path.Combine(App.ResourcesPath, "images/logo.png"));
|
pictureLogo.Image = Image.FromFile(App.LogoPath);
|
||||||
} catch (Exception) {
|
} catch (Exception) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ sealed partial class FormPlugins : Form, FormManager.IAppDialog {
|
|||||||
|
|
||||||
private readonly PluginManager pluginManager;
|
private readonly PluginManager pluginManager;
|
||||||
|
|
||||||
public FormPlugins() {
|
private FormPlugins() {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
Text = Program.BrandName + " Plugins";
|
Text = Program.BrandName + " Plugins";
|
||||||
|
@ -24,7 +24,7 @@ public TabSettingsSounds(Action playSoundNotification) {
|
|||||||
|
|
||||||
tbCustomSound.Text = Config.NotificationSoundPath;
|
tbCustomSound.Text = Config.NotificationSoundPath;
|
||||||
tbCustomSound_TextChanged(tbCustomSound, EventArgs.Empty);
|
tbCustomSound_TextChanged(tbCustomSound, EventArgs.Empty);
|
||||||
NativeMethods.SendMessage(tbCustomSound.Handle, NativeMethods.EM_SETCUEBANNER, 0, "(default TweetDeck sound)");
|
NativeMethods.SetCueBanner(tbCustomSound, "(default TweetDeck sound)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnReady() {
|
public override void OnReady() {
|
||||||
|
@ -16,7 +16,7 @@ sealed partial class PluginControl : UserControl {
|
|||||||
|
|
||||||
private int nextHeight;
|
private int nextHeight;
|
||||||
|
|
||||||
public PluginControl() {
|
private PluginControl() {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ private static void Main() {
|
|||||||
ErrorHandler = reporter,
|
ErrorHandler = reporter,
|
||||||
SystemHandler = new SystemHandler(),
|
SystemHandler = new SystemHandler(),
|
||||||
MessageDialogs = new MessageDialogs(),
|
MessageDialogs = new MessageDialogs(),
|
||||||
FileDialogs = new FileDialogs(),
|
FileDialogs = new FileDialogs()
|
||||||
});
|
});
|
||||||
|
|
||||||
errorReporter = reporter;
|
errorReporter = reporter;
|
||||||
|
@ -8,16 +8,16 @@ namespace TweetDuck.Utils {
|
|||||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
static class NativeMethods {
|
static class NativeMethods {
|
||||||
public static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);
|
private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);
|
||||||
public static readonly IntPtr HOOK_HANDLED = new IntPtr(-1);
|
public static readonly IntPtr HOOK_HANDLED = new IntPtr(-1);
|
||||||
|
|
||||||
public const int HWND_TOPMOST = -1;
|
public const int HWND_TOPMOST = -1;
|
||||||
public const uint SWP_NOACTIVATE = 0x0010;
|
public const uint SWP_NOACTIVATE = 0x0010;
|
||||||
public const int WS_DISABLED = 0x08000000;
|
|
||||||
public const int GWL_STYLE = -16;
|
|
||||||
|
|
||||||
public const int SB_HORZ = 0;
|
public const int SB_HORZ = 0;
|
||||||
public const int EM_SETCUEBANNER = 0x1501;
|
|
||||||
|
private const int WS_DISABLED = 0x08000000;
|
||||||
|
private const int GWL_STYLE = -16;
|
||||||
|
private const int EM_SETCUEBANNER = 0x1501;
|
||||||
|
|
||||||
public const int WM_MOUSE_LL = 14;
|
public const int WM_MOUSE_LL = 14;
|
||||||
public const int WM_MOUSEWHEEL = 0x020A;
|
public const int WM_MOUSEWHEEL = 0x020A;
|
||||||
@ -57,10 +57,10 @@ private struct MSLLHOOKSTRUCT {
|
|||||||
private static extern bool SetWindowPos(int hWnd, int hWndOrder, int x, int y, int width, int height, uint flags);
|
private static extern bool SetWindowPos(int hWnd, int hWndOrder, int x, int y, int width, int height, uint flags);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
|
private static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern bool PostMessage(IntPtr hWnd, uint msg, UIntPtr wParam, IntPtr lParam);
|
private static extern bool PostMessage(IntPtr hWnd, uint msg, UIntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern uint RegisterWindowMessage(string messageName);
|
public static extern uint RegisterWindowMessage(string messageName);
|
||||||
@ -100,6 +100,10 @@ public static void SetFormDisabled(Form form, bool disabled) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetCueBanner(Control control, string cueText) {
|
||||||
|
SendMessage(control.Handle, EM_SETCUEBANNER, 0, cueText);
|
||||||
|
}
|
||||||
|
|
||||||
public static void BroadcastMessage(uint msg, uint wParam, int lParam) {
|
public static void BroadcastMessage(uint msg, uint wParam, int lParam) {
|
||||||
PostMessage(HWND_BROADCAST, msg, new UIntPtr(wParam), new IntPtr(lParam));
|
PostMessage(HWND_BROADCAST, msg, new UIntPtr(wParam), new IntPtr(lParam));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user