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

Compare commits

..

3 Commits

Author SHA1 Message Date
a58a1b347a Show a deprecation notice on launch
References #360
2023-07-17 01:04:49 +02:00
37303ddf02 Fix doubled border in Settings dialog 2023-07-17 00:58:50 +02:00
f8417706e1 Update CefSharp to 109 2023-07-16 21:40:55 +02:00
32 changed files with 81 additions and 559 deletions

View File

@@ -12,8 +12,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetImpl.CefSharp", "windo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.WinForms.Legacy", "windows\TweetLib.WinForms.Legacy\TweetLib.WinForms.Legacy.csproj", "{B54E732A-4090-4DAA-9ABD-311368C17B68}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.Api", "lib\TweetLib.Api\TweetLib.Api.csproj", "{85596C10-F76E-4619-9CC6-6C1593880F83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.Communication", "lib\TweetLib.Communication\TweetLib.Communication.csproj", "{72473763-4B9D-4FB6-A923-9364B2680F06}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.Core", "lib\TweetLib.Core\TweetLib.Core.csproj", "{93BA3CB4-A812-4949-B07D-8D393FB38937}"
@@ -56,10 +54,6 @@ Global
{B54E732A-4090-4DAA-9ABD-311368C17B68}.Debug|x86.Build.0 = Debug|x86
{B54E732A-4090-4DAA-9ABD-311368C17B68}.Release|x86.ActiveCfg = Release|x86
{B54E732A-4090-4DAA-9ABD-311368C17B68}.Release|x86.Build.0 = Release|x86
{85596C10-F76E-4619-9CC6-6C1593880F83}.Debug|x86.ActiveCfg = Debug|x86
{85596C10-F76E-4619-9CC6-6C1593880F83}.Debug|x86.Build.0 = Debug|x86
{85596C10-F76E-4619-9CC6-6C1593880F83}.Release|x86.ActiveCfg = Release|x86
{85596C10-F76E-4619-9CC6-6C1593880F83}.Release|x86.Build.0 = Release|x86
{72473763-4B9D-4FB6-A923-9364B2680F06}.Debug|x86.ActiveCfg = Debug|x86
{72473763-4B9D-4FB6-A923-9364B2680F06}.Debug|x86.Build.0 = Debug|x86
{72473763-4B9D-4FB6-A923-9364B2680F06}.Release|x86.ActiveCfg = Release|x86

View File

@@ -1,37 +0,0 @@
namespace TweetLib.Api.Data {
public readonly struct NamespacedResource {
public Resource Namespace { get; }
public Resource Path { get; }
public NamespacedResource(Resource ns, Resource path) {
Namespace = ns;
Path = path;
}
private bool Equals(NamespacedResource other) {
return Namespace.Equals(other.Namespace) && Path.Equals(other.Path);
}
public override bool Equals(object? obj) {
return obj is NamespacedResource other && Equals(other);
}
public static bool operator ==(NamespacedResource left, NamespacedResource right) {
return left.Equals(right);
}
public static bool operator !=(NamespacedResource left, NamespacedResource right) {
return !left.Equals(right);
}
public override int GetHashCode() {
unchecked {
return (Namespace.GetHashCode() * 397) ^ Path.GetHashCode();
}
}
public override string ToString() {
return $"{Namespace}:{Path}";
}
}
}

View File

@@ -1,28 +0,0 @@
namespace TweetLib.Api.Data.Notification {
/// <summary>
/// Allows extensions to decide which screen to use for notifications.
///
/// Every registered provider becomes available in the Options dialog and has to be explicitly selected by the user. Only one provider
/// can be active at any given time.
/// </summary>
public interface IDesktopNotificationScreenProvider {
/// <summary>
/// A unique identifier of this provider. Only needs to be unique within the scope of this plugin.
/// </summary>
Resource Id { get; }
/// <summary>
/// Text displayed in the user interface.
/// </summary>
string DisplayName { get; }
/// <summary>
/// Returns a screen that will be used to display the next desktop notification.
///
/// If the return value is <c>null</c> or a screen that is not present in <see cref="IScreenLayout.AllScreens" />, desktop
/// notifications will be temporarily paused and this method will be called again after an unspecified amount of time (but
/// not sooner than 1 second since the last call).
/// </summary>
IScreen? PickScreen(IScreenLayout layout);
}
}

View File

@@ -1,7 +0,0 @@
namespace TweetLib.Api.Data.Notification {
public interface IScreen {
ScreenBounds Bounds { get; }
string Name { get; }
bool IsPrimary { get; }
}
}

View File

@@ -1,9 +0,0 @@
using System.Collections.Generic;
namespace TweetLib.Api.Data.Notification {
public interface IScreenLayout {
IScreen PrimaryScreen { get; }
IScreen TweetDuckScreen { get; }
List<IScreen> AllScreens { get; }
}
}

View File

@@ -1,18 +0,0 @@
namespace TweetLib.Api.Data.Notification {
public readonly struct ScreenBounds {
public int X1 { get; }
public int Y1 { get; }
public int Width { get; }
public int Height { get; }
public int X2 => X1 + Width;
public int Y2 => Y1 + Height;
public ScreenBounds(int x1, int y1, int width, int height) {
X1 = x1;
Y1 = y1;
Width = width;
Height = height;
}
}
}

View File

@@ -1,43 +0,0 @@
using System;
using System.Text.RegularExpressions;
namespace TweetLib.Api.Data {
public readonly struct Resource {
private const string ValidCharacterPattern = "^[a-z0-9_]+$";
private static readonly Regex ValidCharacterRegex = new Regex(ValidCharacterPattern, RegexOptions.Compiled);
public string Name { get; }
public Resource(string name) {
if (!ValidCharacterRegex.IsMatch(name)) {
throw new ArgumentException("Resource name must match the regex: " + ValidCharacterPattern);
}
Name = name;
}
private bool Equals(Resource other) {
return Name == other.Name;
}
public override bool Equals(object? obj) {
return obj is Resource other && Equals(other);
}
public static bool operator ==(Resource left, Resource right) {
return left.Equals(right);
}
public static bool operator !=(Resource left, Resource right) {
return !left.Equals(right);
}
public override int GetHashCode() {
return Name.GetHashCode();
}
public override string ToString() {
return Name;
}
}
}

View File

@@ -1,5 +0,0 @@
namespace TweetLib.Api {
public interface ITweetDuckApi {
T? FindService<T>() where T : class, ITweetDuckService;
}
}

View File

@@ -1,3 +0,0 @@
namespace TweetLib.Api {
public interface ITweetDuckService {}
}

View File

@@ -1,7 +0,0 @@
using TweetLib.Api.Data.Notification;
namespace TweetLib.Api.Service {
public interface INotificationService : ITweetDuckService {
void RegisterDesktopNotificationScreenProvider(IDesktopNotificationScreenProvider provider);
}
}

View File

@@ -1,15 +0,0 @@
using TweetLib.Api.Data;
namespace TweetLib.Api {
public abstract class TweetDuckExtension {
/// <summary>
/// Unique identifier of the extension.
/// </summary>
public abstract Resource Id { get; }
/// <summary>
/// Called when the extension is loaded on startup, or enabled at runtime.
/// </summary>
public abstract void Enable(ITweetDuckApi api);
}
}

View File

@@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Configurations>Debug;Release</Configurations>
<Platforms>x86;x64</Platforms>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\Version.cs" Link="Version.cs" />
</ItemGroup>
</Project>

View File

@@ -5,8 +5,6 @@ using TweetLib.Browser.Request;
using TweetLib.Core.Application;
using TweetLib.Core.Features;
using TweetLib.Core.Features.Plugins;
using TweetLib.Core.Resources;
using TweetLib.Core.Systems.Api;
using TweetLib.Core.Systems.Configuration;
using TweetLib.Core.Systems.Logging;
using TweetLib.Utils.Static;
@@ -23,11 +21,8 @@ namespace TweetLib.Core {
internal static readonly string PluginPath = Path.Combine(ProgramPath, "plugins");
internal static readonly string GuidePath = Path.Combine(ProgramPath, "guide");
public static readonly string ExtensionPath = Path.Combine(ProgramPath, "extensions");
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 ApiImplementation Api { get; } = new ();
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 ConfigManager ConfigManager { get; } = Setup.CreateConfigManager(StoragePath);

View File

@@ -1,41 +0,0 @@
using System;
using System.IO;
using System.Reflection;
using TweetLib.Api;
using TweetLib.Core.Systems.Api;
namespace TweetLib.Core.Features.Extensions {
public static class ExtensionLoader {
public static void LoadAllInFolder(string extensionFolder) {
if (!Directory.Exists(extensionFolder)) {
return;
}
try {
foreach (string file in Directory.EnumerateFiles(extensionFolder, "*.dll", SearchOption.TopDirectoryOnly)) {
try {
Assembly assembly = Assembly.LoadFile(file);
foreach (Type type in assembly.GetTypes()) {
if (typeof(TweetDuckExtension).IsAssignableFrom(type) && Activator.CreateInstance(type) is TweetDuckExtension extension) {
EnableExtension(extension);
}
}
} catch (Exception e) {
App.ErrorHandler.HandleException("Extension Error", "Could not load extension: " + Path.GetFileNameWithoutExtension(file), true, e);
}
}
} catch (DirectoryNotFoundException) {
// ignore
} catch (Exception e) {
App.ErrorHandler.HandleException("Extension Error", "Could not load extensions.", true, e);
}
}
private static void EnableExtension(TweetDuckExtension extension) {
ApiImplementation apiImplementation = App.Api;
apiImplementation.CurrentExtension = extension;
extension.Enable(apiImplementation);
apiImplementation.CurrentExtension = null;
}
}
}

View File

@@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using TweetLib.Api;
namespace TweetLib.Core.Systems.Api {
public class ApiImplementation : ITweetDuckApi {
public TweetDuckExtension? CurrentExtension { get; internal set; }
private readonly Dictionary<Type, ITweetDuckService> services = new Dictionary<Type, ITweetDuckService>();
internal ApiImplementation() {}
public void RegisterService<T>(T service) where T : class, ITweetDuckService {
if (!typeof(T).IsInterface) {
throw new ArgumentException("Api service implementation must be registered with its interface type.");
}
services.Add(typeof(T), service);
}
public T? FindService<T>() where T : class, ITweetDuckService {
return services.TryGetValue(typeof(T), out ITweetDuckService? service) ? service as T : null;
}
}
}

View File

@@ -10,7 +10,7 @@ using TweetLib.Utils.Static;
namespace TweetLib.Core.Systems.Configuration {
public abstract class ConfigManager {
public static TypeConverterRegistry ConverterRegistry { get; } = new ();
protected static TypeConverterRegistry ConverterRegistry { get; } = new ();
static ConfigManager() {
ConverterRegistry.Register(typeof(WindowState), new BasicTypeConverter<WindowState> {

View File

@@ -14,7 +14,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TweetLib.Api\TweetLib.Api.csproj" />
<ProjectReference Include="..\TweetLib.Browser\TweetLib.Browser.csproj" />
<ProjectReference Include="..\TweetLib.Utils\TweetLib.Utils.csproj" />
</ItemGroup>

View File

@@ -32,7 +32,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CefSharp.Common.NETCore" Version="107.1.90" />
<PackageReference Include="CefSharp.Common.NETCore" Version="109.1.110" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,21 +0,0 @@
using System;
using TweetDuck.Application.Service;
using TweetLib.Api;
using TweetLib.Api.Data;
using TweetLib.Api.Service;
using TweetLib.Core;
namespace TweetDuck.Application {
static class ApiServices {
public static NotificationService Notifications { get; } = new NotificationService();
public static void Register() {
App.Api.RegisterService<INotificationService>(Notifications);
}
internal static NamespacedResource Namespace(Resource path) {
TweetDuckExtension currentExtension = App.Api.CurrentExtension ?? throw new InvalidOperationException("Cannot use API services outside of designated method calls.");
return new NamespacedResource(currentExtension.Id, path);
}
}
}

View File

@@ -1,33 +0,0 @@
using System.Collections.Generic;
using TweetLib.Api.Data;
using TweetLib.Api.Data.Notification;
using TweetLib.Api.Service;
namespace TweetDuck.Application.Service {
sealed class NotificationService : INotificationService {
private readonly List<NamespacedProvider> desktopNotificationScreenProviders = new ();
public void RegisterDesktopNotificationScreenProvider(IDesktopNotificationScreenProvider provider) {
desktopNotificationScreenProviders.Add(new NamespacedProvider(ApiServices.Namespace(provider.Id), provider));
}
public List<NamespacedProvider> GetDesktopNotificationScreenProviders() {
return desktopNotificationScreenProviders;
}
public sealed class NamespacedProvider : IDesktopNotificationScreenProvider {
public NamespacedResource NamespacedId { get; }
private readonly IDesktopNotificationScreenProvider provider;
public NamespacedProvider(NamespacedResource id, IDesktopNotificationScreenProvider provider) {
this.NamespacedId = id;
this.provider = provider;
}
public Resource Id => provider.Id;
public string DisplayName => provider.DisplayName;
public IScreen? PickScreen(IScreenLayout layout) => provider.PickScreen(layout);
}
}
}

View File

@@ -22,7 +22,15 @@ namespace TweetDuck.Browser.Notification {
protected virtual Point PrimaryLocation {
get {
Screen screen = Config.NotificationDisplay.PickScreen(owner);
Screen screen;
if (Config.NotificationDisplay > 0 && Config.NotificationDisplay <= Screen.AllScreens.Length) {
screen = Screen.AllScreens[Config.NotificationDisplay - 1];
}
else {
screen = Screen.FromControl(owner);
}
int edgeDist = Config.NotificationEdgeDistance;
switch (Config.NotificationPosition) {

View File

@@ -1,173 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using TweetDuck.Application;
using TweetDuck.Application.Service;
using TweetLib.Api.Data;
using TweetLib.Api.Data.Notification;
using TweetLib.Utils.Serialization.Converters;
using TweetLib.Utils.Static;
namespace TweetDuck.Browser.Notification {
abstract class NotificationScreen {
public static List<NotificationScreen> All {
get {
var list = new List<NotificationScreen> {
SameAsTweetDuck.Instance
};
for (int index = 1; index <= Screen.AllScreens.Length; index++) {
list.Add(new Static(index));
}
foreach (var provider in ApiServices.Notifications.GetDesktopNotificationScreenProviders()) {
list.Add(new Provided(provider.NamespacedId));
}
return list;
}
}
public abstract string DisplayName { get; }
private NotificationScreen() {}
public abstract Screen PickScreen(FormBrowser mainWindow);
protected abstract string Serialize();
public sealed class SameAsTweetDuck : NotificationScreen {
public static SameAsTweetDuck Instance { get; } = new SameAsTweetDuck();
public override string DisplayName => "(Same as TweetDuck)";
private SameAsTweetDuck() {}
public override Screen PickScreen(FormBrowser mainWindow) {
return Screen.FromControl(mainWindow);
}
protected override string Serialize() {
return "0";
}
public override bool Equals(object? obj) {
return obj is SameAsTweetDuck;
}
public override int GetHashCode() {
return 1828695039;
}
}
private sealed class Static : NotificationScreen {
public override string DisplayName {
get {
Screen? screen = Screen;
if (screen == null) {
return $"Unknown ({screenIndex})";
}
return screen.DeviceName.TrimStart('\\', '.') + $" ({screen.Bounds.Width}x{screen.Bounds.Height})";
}
}
private Screen? Screen => screenIndex >= 1 && screenIndex <= Screen.AllScreens.Length ? Screen.AllScreens[screenIndex - 1] : null;
private readonly int screenIndex;
public Static(int screenIndex) {
this.screenIndex = screenIndex;
}
public override Screen PickScreen(FormBrowser mainWindow) {
return Screen ?? SameAsTweetDuck.Instance.PickScreen(mainWindow);
}
protected override string Serialize() {
return screenIndex.ToString();
}
public override bool Equals(object? obj) {
return obj is Static other && screenIndex == other.screenIndex;
}
public override int GetHashCode() {
return 31 * screenIndex;
}
}
private sealed class Provided : NotificationScreen {
public override string DisplayName => Provider?.DisplayName ?? $"Unknown ({resource})";
private readonly NamespacedResource resource;
private NotificationService.NamespacedProvider? provider;
private NotificationService.NamespacedProvider? Provider => provider ??= ApiServices.Notifications.GetDesktopNotificationScreenProviders().Find(p => p.NamespacedId == resource);
public Provided(NamespacedResource resource) {
this.resource = resource;
}
public override Screen PickScreen(FormBrowser mainWindow) {
IScreen? pick = Provider?.PickScreen(new WindowsFormsScreenLayout(mainWindow));
return pick is WindowsFormsScreen screen ? screen.Screen : SameAsTweetDuck.Instance.PickScreen(mainWindow); // TODO
}
protected override string Serialize() {
return resource.Namespace + ":" + resource.Path;
}
public override bool Equals(object? obj) {
return obj is Provided other && resource == other.resource;
}
public override int GetHashCode() {
return resource.GetHashCode();
}
private sealed class WindowsFormsScreenLayout : IScreenLayout {
public IScreen PrimaryScreen => new WindowsFormsScreen(Screen.PrimaryScreen);
public IScreen TweetDuckScreen => new WindowsFormsScreen(Screen.FromControl(mainWindow));
public List<IScreen> AllScreens => Screen.AllScreens.Select(static screen => new WindowsFormsScreen(screen)).ToList<IScreen>();
private readonly FormBrowser mainWindow;
public WindowsFormsScreenLayout(FormBrowser mainWindow) {
this.mainWindow = mainWindow;
}
}
private sealed class WindowsFormsScreen : IScreen {
public Screen Screen { get; }
public ScreenBounds Bounds { get; }
public string Name => Screen.DeviceName;
public bool IsPrimary => Screen.Primary;
public WindowsFormsScreen(Screen screen) {
this.Screen = screen;
this.Bounds = new ScreenBounds(screen.Bounds.X, screen.Bounds.Y, screen.Bounds.Width, screen.Bounds.Height);
}
}
}
public static readonly BasicTypeConverter<NotificationScreen> Converter = new() {
ConvertToString = static value => value.Serialize(),
ConvertToObject = static value => {
if (value == "0") {
return SameAsTweetDuck.Instance;
}
else if (int.TryParse(value, out int index)) {
return new Static(index);
}
var resource = StringUtils.SplitInTwo(value, ':');
if (resource != null) {
return new Provided(new NamespacedResource(new Resource(resource.Value.before), new Resource(resource.Value.after)));
}
return SameAsTweetDuck.Instance;
}
};
}
}

View File

@@ -9,6 +9,7 @@ namespace TweetDuck.Configuration {
public const string ArgIgnoreGDPR = "-nogdpr";
public const string ArgHttpVideo = "-httpvideo";
public const string ArgFreeze = "-freeze";
public const string ArgHideDeprecation = "-hidedeprecation";
// internal args
public const string ArgRestart = "-restart";

View File

@@ -2,7 +2,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using TweetDuck.Browser;
using TweetDuck.Browser.Notification;
using TweetDuck.Controls;
using TweetLib.Core;
using TweetLib.Core.Application;
@@ -67,7 +66,7 @@ namespace TweetDuck.Configuration {
public DesktopNotification.Position NotificationPosition { get; set; } = DesktopNotification.Position.TopRight;
public Point CustomNotificationPosition { get; set; } = ControlExtensions.InvisibleLocation;
public NotificationScreen NotificationDisplay { get; set; } = NotificationScreen.SameAsTweetDuck.Instance;
public int NotificationDisplay { get; set; } = 0;
public int NotificationEdgeDistance { get; set; } = 8;
public int NotificationWindowOpacity { get; set; } = 100;

View File

@@ -0,0 +1,36 @@
using System;
using System.Windows.Forms;
using TweetLib.Core;
namespace TweetDuck.Dialogs;
static class DeprecationNoticeDialog {
public static bool Show() {
const string contents = """
TweetDuck is no longer being maintained:
- Twitter has been constantly breaking TweetDeck and therefore also breaking TweetDuck.
- Twitter will be replacing TweetDeck with a new version that is incompatible with most of the app's features.
- Twitter is planning to put TweetDeck behind a subscription paywall.
There will be no more updates.
Continue at your own risk.
""";
using FormMessage message = new FormMessage("TweetDuck Deprecation Notice", contents, MessageBoxIcon.Warning);
message.AddButton("Exit", DialogResult.Cancel, ControlType.Cancel);
message.AddButton("Continue", DialogResult.OK, ControlType.Accept | ControlType.Focused);
Button btnLearnMore = message.CreateButton("Learn More", x: 9, width: 106);
btnLearnMore.Anchor |= AnchorStyles.Left;
btnLearnMore.Margin = new Padding(0, 0, 48, 0);
btnLearnMore.Click += OnBtnLearnMoreClick;
message.AddActionControl(btnLearnMore);
return message.ShowDialog() == DialogResult.OK;
}
private static void OnBtnLearnMoreClick(object? sender, EventArgs args) {
App.SystemHandler.OpenBrowser(Program.Website + "/deprecation");
}
}

View File

@@ -124,15 +124,7 @@ namespace TweetDuck.Dialogs {
}
public Button AddButton(string title, DialogResult result = DialogResult.OK, ControlType type = ControlType.None) {
Button button = new Button {
Anchor = AnchorStyles.Bottom,
Font = SystemFonts.MessageBoxFont,
Location = new Point(0, 12),
Size = new Size(BrowserUtils.Scale(88, dpiScale), BrowserUtils.Scale(26, dpiScale)),
TabIndex = 256 - buttonCount,
Text = title,
UseVisualStyleBackColor = true
};
Button button = CreateButton(title);
button.Click += (_, _) => {
ClickedButton = button;
@@ -162,6 +154,18 @@ namespace TweetDuck.Dialogs {
return button;
}
public Button CreateButton(string title, int x = 0, int width = 88) {
return new Button {
Anchor = AnchorStyles.Bottom,
Font = SystemFonts.MessageBoxFont,
Location = new Point(x, 12),
Size = new Size(BrowserUtils.Scale(width, dpiScale), BrowserUtils.Scale(26, dpiScale)),
TabIndex = 256 - buttonCount,
Text = title,
UseVisualStyleBackColor = true
};
}
public void AddActionControl(Control control) {
panelActions.Controls.Add(control);

View File

@@ -50,10 +50,10 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.panelContents.AutoScroll = true;
this.panelContents.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panelContents.Location = new System.Drawing.Point(135, 12);
this.panelContents.Location = new System.Drawing.Point(134, 12);
this.panelContents.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
this.panelContents.Name = "panelContents";
this.panelContents.Size = new System.Drawing.Size(662, 482);
this.panelContents.Size = new System.Drawing.Size(663, 482);
this.panelContents.TabIndex = 1;
//
// panelButtons

View File

@@ -86,21 +86,13 @@ namespace TweetDuck.Dialogs.Settings {
}
comboBoxDisplay.Enabled = trackBarEdgeDistance.Enabled = !radioLocCustom.Checked;
comboBoxDisplay.Items.Add("(Same as TweetDuck)");
bool foundScreen = false;
foreach (var screen in NotificationScreen.All) {
comboBoxDisplay.Items.Add(new NotificationScreenItem(screen));
if (screen.Equals(Config.NotificationDisplay)) {
comboBoxDisplay.SelectedIndex = comboBoxDisplay.Items.Count - 1;
foundScreen = true;
}
foreach (Screen screen in Screen.AllScreens) {
comboBoxDisplay.Items.Add($"{screen.DeviceName.TrimStart('\\', '.')} ({screen.Bounds.Width}x{screen.Bounds.Height})");
}
if (!foundScreen) {
comboBoxDisplay.Items.Add(new NotificationScreenItem(Config.NotificationDisplay));
comboBoxDisplay.SelectedIndex = comboBoxDisplay.Items.Count - 1;
}
comboBoxDisplay.SelectedIndex = Math.Min(comboBoxDisplay.Items.Count - 1, Config.NotificationDisplay);
trackBarEdgeDistance.SetValueSafe(Config.NotificationEdgeDistance);
labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value + " px";
@@ -287,7 +279,7 @@ namespace TweetDuck.Dialogs.Settings {
}
private void comboBoxDisplay_SelectedValueChanged(object? sender, EventArgs e) {
Config.NotificationDisplay = ((NotificationScreenItem) comboBoxDisplay.SelectedItem).Screen;
Config.NotificationDisplay = comboBoxDisplay.SelectedIndex;
notification.ShowExampleNotification(false);
}
@@ -297,21 +289,6 @@ namespace TweetDuck.Dialogs.Settings {
notification.ShowExampleNotification(false);
}
private class NotificationScreenItem {
public NotificationScreen Screen { get; }
private readonly string displayName;
public NotificationScreenItem(NotificationScreen screen) {
this.Screen = screen;
this.displayName = screen.DisplayName;
}
public override string ToString() {
return displayName;
}
}
#endregion
#region Size

View File

@@ -6,7 +6,6 @@ using CefSharp.WinForms;
using TweetDuck.Application;
using TweetDuck.Browser;
using TweetDuck.Browser.Base;
using TweetDuck.Browser.Notification;
using TweetDuck.Configuration;
using TweetDuck.Dialogs;
using TweetDuck.Management;
@@ -17,7 +16,6 @@ using TweetLib.Browser.CEF.Utils;
using TweetLib.Browser.Request;
using TweetLib.Core;
using TweetLib.Core.Application;
using TweetLib.Core.Features.Extensions;
using TweetLib.Core.Features.Plugins;
using TweetLib.Core.Features.Plugins.Config;
using TweetLib.Core.Features.TweetDeck;
@@ -92,7 +90,6 @@ namespace TweetDuck {
public string? ResourceRewriteRules => Arguments.GetValue(Arguments.ArgFreeze);
public ConfigManager CreateConfigManager(string storagePath) {
ConfigManager.ConverterRegistry.Register(typeof(NotificationScreen), NotificationScreen.Converter);
return new ConfigManager<UserConfig, SystemConfig>(storagePath, Config);
}
@@ -111,6 +108,10 @@ namespace TweetDuck {
if (Config.System.Migrate()) {
Config.System.Save();
}
if (!Arguments.HasFlag(Arguments.ArgHideDeprecation) && !DeprecationNoticeDialog.Show()) {
Environment.Exit(0);
}
}
public void Launch(ResourceCache resourceCache, PluginManager pluginManager) {
@@ -140,9 +141,6 @@ namespace TweetDuck {
Cef.Initialize(settings, false, new BrowserProcessHandler());
Win.Application.ApplicationExit += static (_, _) => ExitCleanup();
ApiServices.Register();
ExtensionLoader.LoadAllInFolder(App.ExtensionPath);
var updateCheckClient = new UpdateCheckClient(Path.Combine(storagePath, InstallerFolder));
var mainForm = new FormBrowser(resourceCache, pluginManager, updateCheckClient, lockManager.WindowRestoreMessage);
Win.Application.Run(mainForm);

View File

@@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using TweetDuck.Dialogs;
using TweetDuck.Management;
@@ -36,16 +35,10 @@ namespace TweetDuck {
btnIgnore.Enabled = canIgnore;
form.ActiveControl = canIgnore ? btnIgnore : btnExit;
Button btnOpenLog = new Button {
Anchor = AnchorStyles.Bottom | AnchorStyles.Left,
Enabled = loggedSuccessfully,
Font = SystemFonts.MessageBoxFont,
Location = new Point(9, 12),
Margin = new Padding(0, 0, 48, 0),
Size = new Size(106, 26),
Text = "Show Error Log",
UseVisualStyleBackColor = true
};
Button btnOpenLog = form.CreateButton("Show Error Log", x: 9, width: 106);
btnOpenLog.Anchor |= AnchorStyles.Left;
btnOpenLog.Enabled = loggedSuccessfully;
btnOpenLog.Margin = new Padding(0, 0, 48, 0);
btnOpenLog.Click += static (_, _) => {
if (!OpenLogFile()) {

View File

@@ -36,11 +36,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CefSharp.WinForms.NETCore" Version="107.1.90" />
<PackageReference Include="CefSharp.WinForms.NETCore" Version="109.1.110" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\lib\TweetLib.Api\TweetLib.Api.csproj" />
<ProjectReference Include="..\..\lib\TweetLib.Browser.CEF\TweetLib.Browser.CEF.csproj" />
<ProjectReference Include="..\..\lib\TweetLib.Browser\TweetLib.Browser.csproj" />
<ProjectReference Include="..\..\lib\TweetLib.Communication\TweetLib.Communication.csproj" />

View File

@@ -28,7 +28,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CefSharp.WinForms.NETCore" Version="107.1.90" />
<PackageReference Include="CefSharp.WinForms.NETCore" Version="109.1.110" />
</ItemGroup>
<ItemGroup>