From 0960dab048422f247f4607de9c790914bee3f48e Mon Sep 17 00:00:00 2001 From: Kramer Campbell Date: Sun, 4 Feb 2024 02:31:55 -0800 Subject: [PATCH 1/6] Add S3 uploader --- DiscordBee.cs | 45 +- DiscordBee.csproj | 16 + DiscordTools/Assets/Uploader/S3Uploader.cs | 87 ++ S3Client/S3Client.cs | 118 +++ S3Client/S3Config.cs | 50 + S3Client/Types/S3Image.cs | 8 + Settings.cs | 71 ++ UI/S3SettingsWindow.Designer.cs | 330 ++++++ UI/S3SettingsWindow.cs | 280 +++++ UI/S3SettingsWindow.resx | 120 +++ UI/SettingsWindow.Designer.cs | 1085 +++++++++++--------- UI/SettingsWindow.cs | 67 +- 12 files changed, 1766 insertions(+), 511 deletions(-) create mode 100644 DiscordTools/Assets/Uploader/S3Uploader.cs create mode 100644 S3Client/S3Client.cs create mode 100644 S3Client/S3Config.cs create mode 100644 S3Client/Types/S3Image.cs create mode 100644 UI/S3SettingsWindow.Designer.cs create mode 100644 UI/S3SettingsWindow.cs create mode 100644 UI/S3SettingsWindow.resx diff --git a/DiscordBee.cs b/DiscordBee.cs index 9da9812..4bd319b 100644 --- a/DiscordBee.cs +++ b/DiscordBee.cs @@ -4,6 +4,7 @@ namespace MusicBeePlugin using MusicBeePlugin.DiscordTools; using MusicBeePlugin.DiscordTools.Assets; using MusicBeePlugin.DiscordTools.Assets.Uploader; + using MusicBeePlugin.S3Client; using MusicBeePlugin.UI; using System; using System.Collections.Generic; @@ -31,6 +32,7 @@ public partial class Plugin private readonly Timer _updateTimer = new Timer(300); private string _imgurAssetCachePath; private string _imgurAlbum; + private string _s3AssetCachePath; public Plugin() { @@ -80,13 +82,32 @@ public PluginInfo Initialise(IntPtr apiInterfacePtr) var settingsFilePath = $"{workingDir}\\{_about.Name}.settings"; _imgurAssetCachePath = $"{workingDir}\\{_about.Name}-Imgur.cache"; _imgurAlbum = $"{workingDir}\\{_about.Name}-Imgur.album"; + _s3AssetCachePath = $"{workingDir}\\{_about.Name}-S3.cache"; _settings = Settings.GetInstance(settingsFilePath); _settings.SettingChanged += SettingChangedCallback; _discordClient.ArtworkUploadEnabled = _settings.UploadArtwork; _discordClient.DiscordId = _settings.DiscordAppId; - UpdateAssetManager(_imgurAssetCachePath, new ImgurUploader(_imgurAlbum, _settings.ImgurClientId)); + + switch (_settings.ArtworkUploader) + { + case "Imgur": + UpdateAssetManager(_imgurAssetCachePath, new ImgurUploader(_imgurAlbum, _settings.ImgurClientId)); + break; + case "Amazon S3": + UpdateAssetManager(_s3AssetCachePath, new S3Uploader(new S3Config + { + AccessKeyId = _settings.S3AccessKeyId, + SecretAccessKey = _settings.S3SecretAccessKey, + Endpoint = _settings.S3Endpoint, + BucketName = _settings.S3BucketName, + Prefix = _settings.S3Prefix, + CustomDomain = _settings.S3CustomDomain + })); + break; + } + ToolStripMenuItem mainMenuItem = (ToolStripMenuItem)_mbApiInterface.MB_AddMenuItem($"mnuTools/{_about.Name}", null, null); mainMenuItem.DropDown.Items.Add("Uploader Health", null, ShowUploaderHealth); @@ -138,10 +159,30 @@ private void SettingChangedCallback(object sender, Settings.SettingChangedEventA { _discordClient.ArtworkUploadEnabled = _settings.UploadArtwork; } - if (e.SettingProperty.Equals("ImgurClientId")) + if (_settings.ArtworkUploader.Equals("Imgur") && e.SettingProperty.Equals("ImgurClientId")) { UpdateAssetManager(_imgurAssetCachePath, new ImgurUploader(_imgurAlbum, _settings.ImgurClientId)); } + if (_settings.ArtworkUploader.Equals("Amazon S3")) + { + if (e.SettingProperty.Equals("S3AccessKeyId") || + e.SettingProperty.Equals("S3SecretAccessKey") || + e.SettingProperty.Equals("S3Endpoint") || + e.SettingProperty.Equals("S3BucketName") || + e.SettingProperty.Equals("S3Prefix") || + e.SettingProperty.Equals("S3CustomDomain")) + { + UpdateAssetManager(_s3AssetCachePath, new S3Uploader(new S3Config + { + AccessKeyId = _settings.S3AccessKeyId, + SecretAccessKey = _settings.S3SecretAccessKey, + Endpoint = _settings.S3Endpoint, + BucketName = _settings.S3BucketName, + Prefix = _settings.S3Prefix, + CustomDomain = _settings.S3CustomDomain + })); + } + } } public string GetVersionString() diff --git a/DiscordBee.csproj b/DiscordBee.csproj index 544aaa5..455cf7d 100644 --- a/DiscordBee.csproj +++ b/DiscordBee.csproj @@ -96,6 +96,7 @@ + @@ -106,6 +107,9 @@ + + + @@ -118,6 +122,12 @@ + + Form + + + S3SettingsWindow.cs + Form @@ -163,6 +173,9 @@ PlaceholderTableWindow.cs + + S3SettingsWindow.cs + SettingsWindow.cs @@ -171,6 +184,9 @@ + + 3.7.305.22 + 1.1.3.18 diff --git a/DiscordTools/Assets/Uploader/S3Uploader.cs b/DiscordTools/Assets/Uploader/S3Uploader.cs new file mode 100644 index 0000000..f9de8f1 --- /dev/null +++ b/DiscordTools/Assets/Uploader/S3Uploader.cs @@ -0,0 +1,87 @@ +namespace MusicBeePlugin.DiscordTools.Assets.Uploader +{ + using MusicBeePlugin.S3Client; + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.IO; + using System.Threading; + using System.Threading.Tasks; + + public class S3Uploader : IAssetUploader + { + private readonly S3Client _client; + private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); + + public S3Uploader(S3Config config) + { + _client = new S3Client(config); + } + + public Task DeleteAsset(AlbumCoverData assetData) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + _client.Dispose(); + } + + public async Task> GetAssets() + { + var ret = new Dictionary(); + var images = await _client.GetAlbumImages(); + + foreach (var image in images) + { + var hash = Path.GetFileName(image.Key); + if (string.IsNullOrEmpty(hash)) + { + continue; + } + ret[hash] = image.Link; + } + + return ret; + } + + public async Task Init() + { + Debug.WriteLine(" ---> Waiting for semaphore"); + await _semaphore.WaitAsync(); + Debug.WriteLine(" <--- Waiting for semaphore"); + try + { + // Nothing to do. + } + finally + { + Debug.WriteLine(" ---> Releasing semaphore"); + _semaphore.Release(); + } + return true; + } + + public bool IsAssetCached(AlbumCoverData assetData) + { + return false; + } + + public UploaderHealthInfo GetHealth() + { + // The S3 API does not have rate limit headers, so we assume it's always healthy + var health = new UploaderHealthInfo + { + IsHealthy = true + }; + return health; + } + + public async Task UploadAsset(AlbumCoverData assetData) + { + var uploaded = await _client.UploadImage(assetData.Hash, assetData.ImageB64); + return new UploadResult { Hash = assetData.Hash, Link = uploaded.Link }; + } + } +} diff --git a/S3Client/S3Client.cs b/S3Client/S3Client.cs new file mode 100644 index 0000000..3afcee5 --- /dev/null +++ b/S3Client/S3Client.cs @@ -0,0 +1,118 @@ +namespace MusicBeePlugin.S3Client +{ + using Amazon.S3; + using Amazon.S3.Model; + using MusicBeePlugin.S3Client.Types; + using System; + using System.Drawing; + using System.Drawing.Imaging; + using System.Linq; + using System.Threading.Tasks; + + public class S3Client : IDisposable + { + private readonly S3Config _config; + private readonly AmazonS3Client _client; + + public S3Client(S3Config config) + { + _config = config; + var clientConfig = new AmazonS3Config + { + ServiceURL = config.Endpoint, + }; + _client = new AmazonS3Client(config.AccessKeyId, config.SecretAccessKey, clientConfig); + } + + public async Task GetAlbumImages() + { + var listRequest = new ListObjectsV2Request + { + BucketName = _config.BucketName, + Prefix = _config.Prefix, + }; + + var response = await _client.ListObjectsV2Async(listRequest); + return response.S3Objects.Select(obj => new S3Image + { + Key = obj.Key, + Link = $"{GetBaseUrl()}/{obj.Key}", + }).ToArray(); + } + + public async Task UploadImage(string hash, string dataB64) + { + var key = $"{_config.Prefix}/{hash}"; + var imageStream = new System.IO.MemoryStream(Convert.FromBase64String(dataB64)); + + // Get content type of image for S3 + string contentType = "image/unknown"; + using (var image = Image.FromStream(imageStream)) + { + Guid guid = image.RawFormat.Guid; + foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders()) + { + if (codec.FormatID == guid) + { + contentType = codec.MimeType; + break; + } + } + } + + var putRequest = new PutObjectRequest + { + BucketName = _config.BucketName, + Key = $"{_config.Prefix}/{hash}", + ContentType = contentType, + InputStream = imageStream, + CannedACL = S3CannedACL.PublicRead, + }; + + var response = await _client.PutObjectAsync(putRequest); + if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) + { + return new S3Image + { + Key = key, + Link = $"{GetBaseUrl()}/{key}", + }; + } + else + { + return null; + } + } + + public async Task TestConnection() + { + // Check if an S3 request can be successfully made + try + { + var listRequest = new ListObjectsV2Request + { + BucketName = _config.BucketName, + Prefix = _config.Prefix, + }; + + var response = await _client.ListObjectsV2Async(listRequest); + return response.HttpStatusCode == System.Net.HttpStatusCode.OK; + } + catch + { + return false; + } + } + + public void Dispose() + { + _client?.Dispose(); + GC.SuppressFinalize(this); + } + + private string GetBaseUrl() + { + return _config.CustomDomain ?? _config.Endpoint; + } + } +} diff --git a/S3Client/S3Config.cs b/S3Client/S3Config.cs new file mode 100644 index 0000000..2f4b5dc --- /dev/null +++ b/S3Client/S3Config.cs @@ -0,0 +1,50 @@ +namespace MusicBeePlugin.S3Client +{ + using System; + using System.Reflection; + + public class S3Config + { + public string AccessKeyId { get; set; } + public string SecretAccessKey { get; set; } + + private readonly string _endpoint; + public string Endpoint + { + get => _endpoint; + set => PrefixSchemeIfNecessary("_endpoint", value); + } + + public string BucketName { get; set; } + public string Prefix { get; set; } + + private readonly string _customDomain; + public string CustomDomain { + get => _customDomain; + set => PrefixSchemeIfNecessary("_customDomain", value); + } + + private void PrefixSchemeIfNecessary(string fieldName, string value) + { + FieldInfo target = GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + if (target == null) + { + return; + } + + if (string.IsNullOrEmpty(value)) + { + target.SetValue(this, value); + return; + } + + if (value.StartsWith($"{Uri.UriSchemeHttp}://") || value.StartsWith($"{Uri.UriSchemeHttps}://")) + { + target.SetValue(this, value); + return; + } + + target.SetValue(this, $"{Uri.UriSchemeHttps}://{value}"); + } + } +} diff --git a/S3Client/Types/S3Image.cs b/S3Client/Types/S3Image.cs new file mode 100644 index 0000000..897c84c --- /dev/null +++ b/S3Client/Types/S3Image.cs @@ -0,0 +1,8 @@ +namespace MusicBeePlugin.S3Client.Types +{ + public class S3Image + { + public string Key { get; set; } + public string Link { get; set; } + } +} diff --git a/Settings.cs b/Settings.cs index 82bc38f..59e0340 100644 --- a/Settings.cs +++ b/Settings.cs @@ -27,6 +27,13 @@ public class Settings {"DiscordAppId", "409394531948298250"}, // prod //{"DiscordAppId", "408977077799354379"}, // dev {"ImgurClientId", "09bef4c058080cd"}, + {"ArtworkUploader", "Imgur"}, + {"S3AccessKeyId", ""}, + {"S3SecretAccessKey", ""}, + {"S3Endpoint", "s3.amazonaws.com"}, + {"S3BucketName", ""}, + {"S3Prefix", "DiscordBee"}, + {"S3CustomDomain", ""}, }; public event EventHandler SettingChanged; @@ -123,6 +130,54 @@ public string ImgurClientId } } + [DataMember] private string _s3AccessKeyId; + + public string S3AccessKeyId + { + get => _s3AccessKeyId ?? defaults["S3AccessKeyId"]; + set => SetIfChanged("_s3AccessKeyId", value); + } + + [DataMember] private string _s3SecretAccessKey; + + public string S3SecretAccessKey + { + get => _s3SecretAccessKey ?? defaults["S3SecretAccessKey"]; + set => SetIfChanged("_s3SecretAccessKey", value); + } + + [DataMember] private string _s3Endpoint; + + public string S3Endpoint + { + get => _s3Endpoint ?? defaults["S3Endpoint"]; + set => SetIfChanged("_s3Endpoint", value); + } + + [DataMember] private string _s3BucketName; + + public string S3BucketName + { + get => _s3BucketName ?? defaults["S3BucketName"]; + set => SetIfChanged("_s3BucketName", value); + } + + [DataMember] private string _s3Prefix; + + public string S3Prefix + { + get => _s3Prefix ?? defaults["S3Prefix"]; + set => SetIfChanged("_s3Prefix", value); + } + + [DataMember] private string _s3CustomDomain; + + public string S3CustomDomain + { + get => _s3CustomDomain ?? defaults["S3CustomDomain"]; + set => SetIfChanged("_s3CustomDomain", value); + } + [DataMember] private bool? _updatePresenceWhenStopped; public bool UpdatePresenceWhenStopped @@ -179,6 +234,22 @@ public bool UploadArtwork set => SetIfChanged("_uploadArtwork", value); } + [DataMember] private string _artworkUploader; + + public string ArtworkUploader + { + get => _artworkUploader ?? defaults["ArtworkUploader"]; + set + { + if (value?.Equals(defaults["ArtworkUploader"]) == true) + { + _artworkUploader = null; + return; + } + SetIfChanged("_artworkUploader", value); + } + } + [DataMember] private string _buttonLabel; public string ButtonLabel diff --git a/UI/S3SettingsWindow.Designer.cs b/UI/S3SettingsWindow.Designer.cs new file mode 100644 index 0000000..f15eb00 --- /dev/null +++ b/UI/S3SettingsWindow.Designer.cs @@ -0,0 +1,330 @@ +namespace MusicBeePlugin.UI +{ + partial class S3SettingsWindow + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.panel2 = new System.Windows.Forms.Panel(); + this.labelS3AccessKeyId = new System.Windows.Forms.Label(); + this.textBoxS3AccessKeyId = new System.Windows.Forms.TextBox(); + this.panel3 = new System.Windows.Forms.Panel(); + this.buttonSaveClose = new System.Windows.Forms.Button(); + this.textBoxS3SecretAccessKey = new System.Windows.Forms.TextBox(); + this.labelS3SecretAccessKey = new System.Windows.Forms.Label(); + this.textBoxS3Endpoint = new System.Windows.Forms.TextBox(); + this.labelS3Endpoint = new System.Windows.Forms.Label(); + this.textBoxS3BucketName = new System.Windows.Forms.TextBox(); + this.labelS3BucketName = new System.Windows.Forms.Label(); + this.textBoxS3Prefix = new System.Windows.Forms.TextBox(); + this.labelS3Prefix = new System.Windows.Forms.Label(); + this.textBoxS3CustomDomain = new System.Windows.Forms.TextBox(); + this.labelS3CustomDomain = new System.Windows.Forms.Label(); + this.labelUrlPreview = new System.Windows.Forms.Label(); + this.textBoxUrlPreview = new System.Windows.Forms.TextBox(); + this.buttonTest = new System.Windows.Forms.Button(); + this.panel2.SuspendLayout(); + this.panel3.SuspendLayout(); + this.SuspendLayout(); + // + // panel2 + // + this.panel2.AutoSize = true; + this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel2.BackColor = System.Drawing.Color.Transparent; + this.panel2.Controls.Add(this.labelUrlPreview); + this.panel2.Controls.Add(this.labelS3CustomDomain); + this.panel2.Controls.Add(this.labelS3Prefix); + this.panel2.Controls.Add(this.textBoxUrlPreview); + this.panel2.Controls.Add(this.textBoxS3CustomDomain); + this.panel2.Controls.Add(this.textBoxS3Prefix); + this.panel2.Controls.Add(this.labelS3BucketName); + this.panel2.Controls.Add(this.textBoxS3BucketName); + this.panel2.Controls.Add(this.labelS3Endpoint); + this.panel2.Controls.Add(this.textBoxS3Endpoint); + this.panel2.Controls.Add(this.labelS3SecretAccessKey); + this.panel2.Controls.Add(this.textBoxS3SecretAccessKey); + this.panel2.Controls.Add(this.labelS3AccessKeyId); + this.panel2.Controls.Add(this.textBoxS3AccessKeyId); + this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel2.Location = new System.Drawing.Point(0, 0); + this.panel2.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.panel2.MinimumSize = new System.Drawing.Size(0, 154); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(786, 329); + this.panel2.TabIndex = 3; + // + // labelS3AccessKeyId + // + this.labelS3AccessKeyId.AutoSize = true; + this.labelS3AccessKeyId.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelS3AccessKeyId.ForeColor = System.Drawing.Color.Black; + this.labelS3AccessKeyId.Location = new System.Drawing.Point(13, 22); + this.labelS3AccessKeyId.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelS3AccessKeyId.Name = "labelS3AccessKeyId"; + this.labelS3AccessKeyId.Size = new System.Drawing.Size(131, 22); + this.labelS3AccessKeyId.TabIndex = 19; + this.labelS3AccessKeyId.Text = "Access Key ID:"; + // + // textBoxS3AccessKeyId + // + this.textBoxS3AccessKeyId.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxS3AccessKeyId.Location = new System.Drawing.Point(182, 17); + this.textBoxS3AccessKeyId.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxS3AccessKeyId.Name = "textBoxS3AccessKeyId"; + this.textBoxS3AccessKeyId.Size = new System.Drawing.Size(576, 33); + this.textBoxS3AccessKeyId.TabIndex = 0; + this.textBoxS3AccessKeyId.TextChanged += new System.EventHandler(this.textBoxS3AccessKeyId_TextChanged); + // + // panel3 + // + this.panel3.AutoScroll = true; + this.panel3.AutoSize = true; + this.panel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel3.BackColor = System.Drawing.Color.Transparent; + this.panel3.Controls.Add(this.buttonTest); + this.panel3.Controls.Add(this.buttonSaveClose); + this.panel3.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel3.Location = new System.Drawing.Point(0, 329); + this.panel3.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.panel3.MinimumSize = new System.Drawing.Size(0, 46); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(786, 46); + this.panel3.TabIndex = 4; + // + // buttonSaveClose + // + this.buttonSaveClose.AutoSize = true; + this.buttonSaveClose.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.buttonSaveClose.Dock = System.Windows.Forms.DockStyle.Right; + this.buttonSaveClose.Location = new System.Drawing.Point(640, 0); + this.buttonSaveClose.Margin = new System.Windows.Forms.Padding(15); + this.buttonSaveClose.Name = "buttonSaveClose"; + this.buttonSaveClose.Padding = new System.Windows.Forms.Padding(8); + this.buttonSaveClose.Size = new System.Drawing.Size(146, 46); + this.buttonSaveClose.TabIndex = 8; + this.buttonSaveClose.Text = "Save and Close"; + this.buttonSaveClose.UseVisualStyleBackColor = true; + this.buttonSaveClose.Click += new System.EventHandler(this.buttonSaveClose_Click); + // + // textBoxS3SecretAccessKey + // + this.textBoxS3SecretAccessKey.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxS3SecretAccessKey.Location = new System.Drawing.Point(182, 60); + this.textBoxS3SecretAccessKey.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxS3SecretAccessKey.Name = "textBoxS3SecretAccessKey"; + this.textBoxS3SecretAccessKey.PasswordChar = '*'; + this.textBoxS3SecretAccessKey.Size = new System.Drawing.Size(576, 33); + this.textBoxS3SecretAccessKey.TabIndex = 1; + this.textBoxS3SecretAccessKey.TextChanged += new System.EventHandler(this.textBoxS3SecretAccessKey_TextChanged); + // + // labelS3SecretAccessKey + // + this.labelS3SecretAccessKey.AutoSize = true; + this.labelS3SecretAccessKey.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelS3SecretAccessKey.ForeColor = System.Drawing.Color.Black; + this.labelS3SecretAccessKey.Location = new System.Drawing.Point(13, 64); + this.labelS3SecretAccessKey.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelS3SecretAccessKey.Name = "labelS3SecretAccessKey"; + this.labelS3SecretAccessKey.Size = new System.Drawing.Size(166, 22); + this.labelS3SecretAccessKey.TabIndex = 19; + this.labelS3SecretAccessKey.Text = "Secret Access Key:"; + // + // textBoxS3Endpoint + // + this.textBoxS3Endpoint.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxS3Endpoint.Location = new System.Drawing.Point(182, 103); + this.textBoxS3Endpoint.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxS3Endpoint.Name = "textBoxS3Endpoint"; + this.textBoxS3Endpoint.Size = new System.Drawing.Size(576, 33); + this.textBoxS3Endpoint.TabIndex = 2; + this.textBoxS3Endpoint.TextChanged += new System.EventHandler(this.textBoxS3Endpoint_TextChanged); + // + // labelS3Endpoint + // + this.labelS3Endpoint.AutoSize = true; + this.labelS3Endpoint.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelS3Endpoint.ForeColor = System.Drawing.Color.Black; + this.labelS3Endpoint.Location = new System.Drawing.Point(13, 108); + this.labelS3Endpoint.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelS3Endpoint.Name = "labelS3Endpoint"; + this.labelS3Endpoint.Size = new System.Drawing.Size(86, 22); + this.labelS3Endpoint.TabIndex = 19; + this.labelS3Endpoint.Text = "Endpoint:"; + // + // textBoxS3BucketName + // + this.textBoxS3BucketName.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxS3BucketName.Location = new System.Drawing.Point(182, 146); + this.textBoxS3BucketName.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxS3BucketName.Name = "textBoxS3BucketName"; + this.textBoxS3BucketName.Size = new System.Drawing.Size(576, 33); + this.textBoxS3BucketName.TabIndex = 3; + this.textBoxS3BucketName.TextChanged += new System.EventHandler(this.textBoxS3BucketName_TextChanged); + // + // labelS3BucketName + // + this.labelS3BucketName.AutoSize = true; + this.labelS3BucketName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelS3BucketName.ForeColor = System.Drawing.Color.Black; + this.labelS3BucketName.Location = new System.Drawing.Point(13, 152); + this.labelS3BucketName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelS3BucketName.Name = "labelS3BucketName"; + this.labelS3BucketName.Size = new System.Drawing.Size(122, 22); + this.labelS3BucketName.TabIndex = 19; + this.labelS3BucketName.Text = "Bucket Name:"; + // + // textBoxS3Prefix + // + this.textBoxS3Prefix.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxS3Prefix.Location = new System.Drawing.Point(182, 189); + this.textBoxS3Prefix.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxS3Prefix.Name = "textBoxS3Prefix"; + this.textBoxS3Prefix.Size = new System.Drawing.Size(576, 33); + this.textBoxS3Prefix.TabIndex = 4; + this.textBoxS3Prefix.TextChanged += new System.EventHandler(this.textBoxS3Prefix_TextChanged); + // + // labelS3Prefix + // + this.labelS3Prefix.AutoSize = true; + this.labelS3Prefix.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelS3Prefix.ForeColor = System.Drawing.Color.Black; + this.labelS3Prefix.Location = new System.Drawing.Point(13, 195); + this.labelS3Prefix.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelS3Prefix.Name = "labelS3Prefix"; + this.labelS3Prefix.Size = new System.Drawing.Size(61, 22); + this.labelS3Prefix.TabIndex = 19; + this.labelS3Prefix.Text = "Prefix:"; + // + // textBoxS3CustomDomain + // + this.textBoxS3CustomDomain.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxS3CustomDomain.Location = new System.Drawing.Point(182, 232); + this.textBoxS3CustomDomain.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxS3CustomDomain.Name = "textBoxS3CustomDomain"; + this.textBoxS3CustomDomain.Size = new System.Drawing.Size(576, 33); + this.textBoxS3CustomDomain.TabIndex = 5; + this.textBoxS3CustomDomain.TextChanged += new System.EventHandler(this.textBoxS3CustomDomain_TextChanged); + // + // labelS3CustomDomain + // + this.labelS3CustomDomain.AutoSize = true; + this.labelS3CustomDomain.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelS3CustomDomain.ForeColor = System.Drawing.Color.Black; + this.labelS3CustomDomain.Location = new System.Drawing.Point(13, 238); + this.labelS3CustomDomain.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelS3CustomDomain.Name = "labelS3CustomDomain"; + this.labelS3CustomDomain.Size = new System.Drawing.Size(142, 22); + this.labelS3CustomDomain.TabIndex = 19; + this.labelS3CustomDomain.Text = "Custom Domain:"; + // + // labelUrlPreview + // + this.labelUrlPreview.AutoSize = true; + this.labelUrlPreview.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelUrlPreview.ForeColor = System.Drawing.Color.Black; + this.labelUrlPreview.Location = new System.Drawing.Point(13, 279); + this.labelUrlPreview.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelUrlPreview.Name = "labelUrlPreview"; + this.labelUrlPreview.Size = new System.Drawing.Size(120, 22); + this.labelUrlPreview.TabIndex = 19; + this.labelUrlPreview.Text = "URL Preview:"; + // + // textBoxUrlPreview + // + this.textBoxUrlPreview.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxUrlPreview.Location = new System.Drawing.Point(182, 273); + this.textBoxUrlPreview.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxUrlPreview.Name = "textBoxUrlPreview"; + this.textBoxUrlPreview.ReadOnly = true; + this.textBoxUrlPreview.Size = new System.Drawing.Size(576, 33); + this.textBoxUrlPreview.TabIndex = 6; + // + // buttonTest + // + this.buttonTest.AutoSize = true; + this.buttonTest.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.buttonTest.Dock = System.Windows.Forms.DockStyle.Left; + this.buttonTest.Location = new System.Drawing.Point(0, 0); + this.buttonTest.Margin = new System.Windows.Forms.Padding(15); + this.buttonTest.Name = "buttonTest"; + this.buttonTest.Padding = new System.Windows.Forms.Padding(8); + this.buttonTest.Size = new System.Drawing.Size(151, 46); + this.buttonTest.TabIndex = 7; + this.buttonTest.Text = "Test Connection"; + this.buttonTest.UseVisualStyleBackColor = true; + this.buttonTest.Click += new System.EventHandler(this.buttonTest_Click); + // + // S3SettingsWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(786, 375); + this.Controls.Add(this.panel2); + this.Controls.Add(this.panel3); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(774, 391); + this.Name = "S3SettingsWindow"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Amazon S3 Settings"; + this.panel2.ResumeLayout(false); + this.panel2.PerformLayout(); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Label labelS3AccessKeyId; + private System.Windows.Forms.TextBox textBoxS3AccessKeyId; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.Button buttonSaveClose; + private System.Windows.Forms.Label labelS3Prefix; + private System.Windows.Forms.TextBox textBoxS3Prefix; + private System.Windows.Forms.Label labelS3BucketName; + private System.Windows.Forms.TextBox textBoxS3BucketName; + private System.Windows.Forms.Label labelS3Endpoint; + private System.Windows.Forms.TextBox textBoxS3Endpoint; + private System.Windows.Forms.Label labelS3SecretAccessKey; + private System.Windows.Forms.TextBox textBoxS3SecretAccessKey; + private System.Windows.Forms.Label labelS3CustomDomain; + private System.Windows.Forms.TextBox textBoxS3CustomDomain; + private System.Windows.Forms.Label labelUrlPreview; + private System.Windows.Forms.TextBox textBoxUrlPreview; + private System.Windows.Forms.Button buttonTest; + } +} diff --git a/UI/S3SettingsWindow.cs b/UI/S3SettingsWindow.cs new file mode 100644 index 0000000..af6f13b --- /dev/null +++ b/UI/S3SettingsWindow.cs @@ -0,0 +1,280 @@ +namespace MusicBeePlugin.UI +{ + using MusicBeePlugin.S3Client; + using System; + using System.Drawing; + using System.Windows.Forms; + + public partial class S3SettingsWindow : Form + { + private readonly Settings _settings; + + public S3SettingsWindow(Settings settings) + { + _settings = settings; + InitializeComponent(); + UpdateValues(_settings); + + Shown += OnShown; + VisibleChanged += OnVisibleChanged; + } + + private void OnVisibleChanged(object sender, EventArgs eventArgs) + { + if (Visible) + { + UpdateValues(_settings); + } + } + + private void OnShown(object sender, EventArgs eventArgs) + { + UpdateValues(_settings); + } + + private void UpdateValues(Settings settings) + { + textBoxS3AccessKeyId.Text = settings.S3AccessKeyId; + textBoxS3SecretAccessKey.Text = settings.S3SecretAccessKey; + textBoxS3Endpoint.Text = settings.S3Endpoint; + textBoxS3BucketName.Text = settings.S3BucketName; + textBoxS3Prefix.Text = settings.S3Prefix; + textBoxS3CustomDomain.Text = settings.S3CustomDomain; + + ValidateInputs(); + } + + private void UpdateUrlPreview() + { + if (string.IsNullOrWhiteSpace(textBoxS3BucketName.Text)) + { + textBoxUrlPreview.Text = ""; + return; + } + + var endpoint = textBoxS3Endpoint.Text; + var customDomain = textBoxS3CustomDomain.Text; + + // Detect insecure scheme and default to secure HTTPS if not present + var insecure = customDomain.StartsWith($"{Uri.UriSchemeHttp}://") || + string.IsNullOrWhiteSpace(customDomain) && endpoint.StartsWith($"{Uri.UriSchemeHttp}://"); + + // Strip schemes from endpoint and custom domain + endpoint = endpoint.Replace($"{Uri.UriSchemeHttp}://", "").Replace($"{Uri.UriSchemeHttps}://", ""); + customDomain = customDomain.Replace($"{Uri.UriSchemeHttp}://", "").Replace($"{Uri.UriSchemeHttps}://", ""); + + var scheme = $"{(insecure ? Uri.UriSchemeHttp : Uri.UriSchemeHttps)}://"; + var baseUrl = string.IsNullOrWhiteSpace(textBoxS3CustomDomain.Text) ? $"{endpoint}/{textBoxS3BucketName.Text}" : customDomain; + var prefix = string.IsNullOrWhiteSpace(textBoxS3Prefix.Text) ? "" : $"{textBoxS3Prefix.Text}/"; + textBoxUrlPreview.Text = $"{scheme}{baseUrl}/{prefix}example"; + } + + private bool ValidateInputs() + { + // Validate the entire form for all errors. Does not enforce any type of format as they differ between various S3 implementations. + int errors = 0; + + bool validateAccessKeyId() + { + if (string.IsNullOrWhiteSpace(textBoxS3AccessKeyId.Text)) + { + textBoxS3AccessKeyId.BackColor = Color.PaleVioletRed; + return false; + } + + textBoxS3AccessKeyId.BackColor = Color.White; + return true; + } + + if (!validateAccessKeyId()) + { + errors++; + } + + bool validateSecretAccessKey() + { + if (string.IsNullOrWhiteSpace(textBoxS3SecretAccessKey.Text)) + { + textBoxS3SecretAccessKey.BackColor = Color.PaleVioletRed; + return false; + } + + textBoxS3SecretAccessKey.BackColor = Color.White; + return true; + } + + if (!validateSecretAccessKey()) + { + errors++; + } + + bool validateEndpoint() + { + if (string.IsNullOrWhiteSpace(textBoxS3Endpoint.Text)) + { + textBoxS3Endpoint.BackColor = Color.PaleVioletRed; + return false; + } + + var endpoint = textBoxS3Endpoint.Text; + if (!endpoint.StartsWith($"{Uri.UriSchemeHttp}://") && !endpoint.StartsWith($"{Uri.UriSchemeHttps}://")) + { + endpoint = $"{Uri.UriSchemeHttps}://{endpoint}"; + } + + if (!ValidationHelpers.ValidateUri(endpoint)) + { + textBoxS3Endpoint.BackColor = Color.PaleVioletRed; + return false; + } + + textBoxS3Endpoint.BackColor = Color.White; + return true; + } + + if (!validateEndpoint()) + { + errors++; + } + + bool validateBucketName() + { + if (string.IsNullOrWhiteSpace(textBoxS3BucketName.Text)) + { + textBoxS3BucketName.BackColor = Color.PaleVioletRed; + return false; + } + + textBoxS3BucketName.BackColor = Color.White; + return true; + } + + if (!validateBucketName()) + { + errors++; + } + + bool validateCustomDomain() + { + var customDomain = textBoxS3CustomDomain.Text; + if (!customDomain.StartsWith($"{Uri.UriSchemeHttp}://") && !customDomain.StartsWith($"{Uri.UriSchemeHttps}://")) + { + customDomain = $"{Uri.UriSchemeHttps}://{customDomain}"; + } + + if (!ValidationHelpers.ValidateUri(customDomain)) + { + textBoxS3CustomDomain.BackColor = Color.PaleVioletRed; + return false; + } + + textBoxS3CustomDomain.BackColor = Color.White; + return true; + } + + if (textBoxS3CustomDomain.Text.Length > 0 && !validateCustomDomain()) + { + errors++; + } + + if (errors > 0) + { + return false; + } + + ResetErrorIndications(); + + return true; + } + + private void ResetErrorIndications() + { + textBoxS3AccessKeyId.BackColor = SystemColors.Window; + textBoxS3SecretAccessKey.BackColor = SystemColors.Window; + textBoxS3Endpoint.BackColor = SystemColors.Window; + textBoxS3BucketName.BackColor = SystemColors.Window; + textBoxS3Prefix.BackColor = SystemColors.Window; + textBoxS3CustomDomain.BackColor = SystemColors.Window; + } + + private void textBoxS3AccessKeyId_TextChanged(object sender, EventArgs e) + { + ValidateInputs(); + } + + private void textBoxS3SecretAccessKey_TextChanged(object sender, EventArgs e) + { + ValidateInputs(); + } + + private void textBoxS3Endpoint_TextChanged(object sender, EventArgs e) + { + UpdateUrlPreview(); + ValidateInputs(); + } + + private void textBoxS3BucketName_TextChanged(object sender, EventArgs e) + { + UpdateUrlPreview(); + ValidateInputs(); + } + + private void textBoxS3Prefix_TextChanged(object sender, EventArgs e) + { + UpdateUrlPreview(); + ValidateInputs(); + } + + private void textBoxS3CustomDomain_TextChanged(object sender, EventArgs e) + { + UpdateUrlPreview(); + ValidateInputs(); + } + + private async void buttonTest_Click(object sender, EventArgs e) + { + buttonTest.Enabled = false; + buttonTest.Text = "Testing..."; + + var s3Client = new S3Client(new S3Config + { + AccessKeyId = textBoxS3AccessKeyId.Text, + SecretAccessKey = textBoxS3SecretAccessKey.Text, + Endpoint = textBoxS3Endpoint.Text, + BucketName = textBoxS3BucketName.Text, + Prefix = textBoxS3Prefix.Text, + CustomDomain = textBoxS3CustomDomain.Text + }); + + if (await s3Client.TestConnection()) + { + MessageBox.Show("Connection successfully established to S3 bucket.", "Test Connection Result", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + else + { + MessageBox.Show("A connection could not be successfully made to the S3 bucket. Please check your credentials and configuration and try again.", "Test Connection Result", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + buttonTest.Enabled = true; + buttonTest.Text = "Test Connection"; + } + + private void buttonSaveClose_Click(object sender, EventArgs e) + { + if (!ValidateInputs()) + { + return; + } + + _settings.S3AccessKeyId = textBoxS3AccessKeyId.Text; + _settings.S3SecretAccessKey = textBoxS3SecretAccessKey.Text; + _settings.S3Endpoint = textBoxS3Endpoint.Text; + _settings.S3BucketName = textBoxS3BucketName.Text; + _settings.S3Prefix = textBoxS3Prefix.Text; + _settings.S3CustomDomain = textBoxS3CustomDomain.Text; + + ((SettingsWindow) Owner).ValidateInputs(); + Close(); + } + } +} diff --git a/UI/S3SettingsWindow.resx b/UI/S3SettingsWindow.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/UI/S3SettingsWindow.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/UI/SettingsWindow.Designer.cs b/UI/SettingsWindow.Designer.cs index af52651..5c23c14 100644 --- a/UI/SettingsWindow.Designer.cs +++ b/UI/SettingsWindow.Designer.cs @@ -28,514 +28,584 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.textBoxSmallImage = new System.Windows.Forms.TextBox(); - this.label4 = new System.Windows.Forms.Label(); - this.textBoxTrackCnt = new System.Windows.Forms.TextBox(); - this.label3 = new System.Windows.Forms.Label(); - this.textBoxTrackNo = new System.Windows.Forms.TextBox(); - this.label2 = new System.Windows.Forms.Label(); - this.textBoxState = new System.Windows.Forms.TextBox(); - this.textBoxDetails = new System.Windows.Forms.TextBox(); - this.label1 = new System.Windows.Forms.Label(); - this.textBoxLargeImage = new System.Windows.Forms.TextBox(); - this.checkBoxTextOnly = new System.Windows.Forms.CheckBox(); - this.checkBoxShowRemainingTime = new System.Windows.Forms.CheckBox(); - this.checkBoxPresenceUpdate = new System.Windows.Forms.CheckBox(); - this.textBoxSeparator = new System.Windows.Forms.TextBox(); - this.label5 = new System.Windows.Forms.Label(); - this.buttonRestoreDefaults = new System.Windows.Forms.Button(); - this.buttonSaveClose = new System.Windows.Forms.Button(); - this.buttonPlaceholders = new System.Windows.Forms.Button(); - this.panel2 = new System.Windows.Forms.Panel(); - this.labelImgurClientId = new System.Windows.Forms.Label(); - this.textBoxImgurClientId = new System.Windows.Forms.TextBox(); - this.customButtonToggle = new System.Windows.Forms.CheckBox(); - this.checkBoxShowOnlyNonPlayingState = new System.Windows.Forms.CheckBox(); - this.checkBoxShowPlayState = new System.Windows.Forms.CheckBox(); - this.checkBoxShowTime = new System.Windows.Forms.CheckBox(); - this.checkBoxArtworkUpload = new System.Windows.Forms.CheckBox(); - this.labelDiscordAppId = new System.Windows.Forms.Label(); - this.textBoxDiscordAppId = new System.Windows.Forms.TextBox(); - this.panel3 = new System.Windows.Forms.Panel(); - this.panel4 = new System.Windows.Forms.Panel(); - this.label9 = new System.Windows.Forms.Label(); - this.customButtonUrl = new System.Windows.Forms.TextBox(); - this.label8 = new System.Windows.Forms.Label(); - this.customButtonLabel = new System.Windows.Forms.TextBox(); - this.panel2.SuspendLayout(); - this.panel3.SuspendLayout(); - this.panel4.SuspendLayout(); - this.SuspendLayout(); - // - // textBoxSmallImage - // - this.textBoxSmallImage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.textBoxSmallImage.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxSmallImage.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.textBoxSmallImage.Location = new System.Drawing.Point(12, 71); - this.textBoxSmallImage.Name = "textBoxSmallImage"; - this.textBoxSmallImage.Size = new System.Drawing.Size(90, 25); - this.textBoxSmallImage.TabIndex = 9; - this.textBoxSmallImage.Text = "Small Image Text"; - // - // label4 - // - this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.label4.AutoSize = true; - this.label4.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.label4.Location = new System.Drawing.Point(492, 66); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(13, 17); - this.label4.TabIndex = 8; - this.label4.Text = ")"; - // - // textBoxTrackCnt - // - this.textBoxTrackCnt.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxTrackCnt.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.textBoxTrackCnt.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxTrackCnt.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.textBoxTrackCnt.Location = new System.Drawing.Point(414, 63); - this.textBoxTrackCnt.Name = "textBoxTrackCnt"; - this.textBoxTrackCnt.Size = new System.Drawing.Size(74, 25); - this.textBoxTrackCnt.TabIndex = 7; - this.textBoxTrackCnt.Text = "PartyMax"; - // - // label3 - // - this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.label3.AutoSize = true; - this.label3.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.label3.Location = new System.Drawing.Point(388, 66); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(20, 17); - this.label3.TabIndex = 6; - this.label3.Text = "of"; - // - // textBoxTrackNo - // - this.textBoxTrackNo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxTrackNo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.textBoxTrackNo.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxTrackNo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.textBoxTrackNo.Location = new System.Drawing.Point(310, 63); - this.textBoxTrackNo.Name = "textBoxTrackNo"; - this.textBoxTrackNo.Size = new System.Drawing.Size(74, 25); - this.textBoxTrackNo.TabIndex = 5; - this.textBoxTrackNo.Text = "PartyNo"; - // - // label2 - // - this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.label2.AutoSize = true; - this.label2.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.label2.Location = new System.Drawing.Point(291, 66); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(13, 17); - this.label2.TabIndex = 4; - this.label2.Text = "("; - // - // textBoxState - // - this.textBoxState.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.textBoxSmallImage = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.textBoxTrackCnt = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.textBoxTrackNo = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.textBoxState = new System.Windows.Forms.TextBox(); + this.textBoxDetails = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.textBoxLargeImage = new System.Windows.Forms.TextBox(); + this.checkBoxTextOnly = new System.Windows.Forms.CheckBox(); + this.checkBoxShowRemainingTime = new System.Windows.Forms.CheckBox(); + this.checkBoxPresenceUpdate = new System.Windows.Forms.CheckBox(); + this.textBoxSeparator = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.buttonRestoreDefaults = new System.Windows.Forms.Button(); + this.buttonSaveClose = new System.Windows.Forms.Button(); + this.buttonPlaceholders = new System.Windows.Forms.Button(); + this.panel2 = new System.Windows.Forms.Panel(); + this.labelArtworkUploader = new System.Windows.Forms.Label(); + this.comboBoxArtworkUploader = new System.Windows.Forms.ComboBox(); + this.labelImgurClientId = new System.Windows.Forms.Label(); + this.textBoxImgurClientId = new System.Windows.Forms.TextBox(); + this.customButtonToggle = new System.Windows.Forms.CheckBox(); + this.checkBoxShowOnlyNonPlayingState = new System.Windows.Forms.CheckBox(); + this.checkBoxShowPlayState = new System.Windows.Forms.CheckBox(); + this.checkBoxShowTime = new System.Windows.Forms.CheckBox(); + this.checkBoxArtworkUpload = new System.Windows.Forms.CheckBox(); + this.labelDiscordAppId = new System.Windows.Forms.Label(); + this.textBoxDiscordAppId = new System.Windows.Forms.TextBox(); + this.buttonS3Settings = new System.Windows.Forms.Button(); + this.panel3 = new System.Windows.Forms.Panel(); + this.panel4 = new System.Windows.Forms.Panel(); + this.label9 = new System.Windows.Forms.Label(); + this.customButtonUrl = new System.Windows.Forms.TextBox(); + this.label8 = new System.Windows.Forms.Label(); + this.customButtonLabel = new System.Windows.Forms.TextBox(); + this.panel2.SuspendLayout(); + this.panel3.SuspendLayout(); + this.panel4.SuspendLayout(); + this.SuspendLayout(); + // + // textBoxSmallImage + // + this.textBoxSmallImage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.textBoxSmallImage.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxSmallImage.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.textBoxSmallImage.Location = new System.Drawing.Point(18, 109); + this.textBoxSmallImage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxSmallImage.Name = "textBoxSmallImage"; + this.textBoxSmallImage.Size = new System.Drawing.Size(133, 33); + this.textBoxSmallImage.TabIndex = 9; + this.textBoxSmallImage.Text = "Small Image Text"; + // + // label4 + // + this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label4.AutoSize = true; + this.label4.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.label4.Location = new System.Drawing.Point(738, 102); + this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(20, 26); + this.label4.TabIndex = 8; + this.label4.Text = ")"; + // + // textBoxTrackCnt + // + this.textBoxTrackCnt.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxTrackCnt.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.textBoxTrackCnt.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxTrackCnt.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.textBoxTrackCnt.Location = new System.Drawing.Point(621, 97); + this.textBoxTrackCnt.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxTrackCnt.Name = "textBoxTrackCnt"; + this.textBoxTrackCnt.Size = new System.Drawing.Size(109, 33); + this.textBoxTrackCnt.TabIndex = 7; + this.textBoxTrackCnt.Text = "PartyMax"; + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.label3.Location = new System.Drawing.Point(582, 102); + this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(32, 26); + this.label3.TabIndex = 6; + this.label3.Text = "of"; + // + // textBoxTrackNo + // + this.textBoxTrackNo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxTrackNo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.textBoxTrackNo.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxTrackNo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.textBoxTrackNo.Location = new System.Drawing.Point(465, 97); + this.textBoxTrackNo.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxTrackNo.Name = "textBoxTrackNo"; + this.textBoxTrackNo.Size = new System.Drawing.Size(109, 33); + this.textBoxTrackNo.TabIndex = 5; + this.textBoxTrackNo.Text = "PartyNo"; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoSize = true; + this.label2.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.label2.Location = new System.Drawing.Point(436, 102); + this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(20, 26); + this.label2.TabIndex = 4; + this.label2.Text = "("; + // + // textBoxState + // + this.textBoxState.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxState.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.textBoxState.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxState.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.textBoxState.Location = new System.Drawing.Point(108, 63); - this.textBoxState.Name = "textBoxState"; - this.textBoxState.Size = new System.Drawing.Size(177, 25); - this.textBoxState.TabIndex = 3; - this.textBoxState.Text = "Presence state"; - // - // textBoxDetails - // - this.textBoxDetails.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.textBoxState.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.textBoxState.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxState.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.textBoxState.Location = new System.Drawing.Point(162, 97); + this.textBoxState.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxState.Name = "textBoxState"; + this.textBoxState.Size = new System.Drawing.Size(264, 33); + this.textBoxState.TabIndex = 3; + this.textBoxState.Text = "Presence state"; + // + // textBoxDetails + // + this.textBoxDetails.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxDetails.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.textBoxDetails.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxDetails.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.textBoxDetails.Location = new System.Drawing.Point(108, 32); - this.textBoxDetails.Name = "textBoxDetails"; - this.textBoxDetails.Size = new System.Drawing.Size(276, 25); - this.textBoxDetails.TabIndex = 2; - this.textBoxDetails.Text = "Presence details"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.label1.Location = new System.Drawing.Point(108, 10); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(84, 19); - this.label1.TabIndex = 1; - this.label1.Text = "MusicBee"; - // - // textBoxLargeImage - // - this.textBoxLargeImage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.textBoxLargeImage.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxLargeImage.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.textBoxLargeImage.Location = new System.Drawing.Point(12, 9); - this.textBoxLargeImage.Multiline = true; - this.textBoxLargeImage.Name = "textBoxLargeImage"; - this.textBoxLargeImage.Size = new System.Drawing.Size(90, 60); - this.textBoxLargeImage.TabIndex = 0; - this.textBoxLargeImage.Text = "Large Image Text"; - // - // checkBoxTextOnly - // - this.checkBoxTextOnly.AutoSize = true; - this.checkBoxTextOnly.ForeColor = System.Drawing.Color.Black; - this.checkBoxTextOnly.Location = new System.Drawing.Point(266, 91); - this.checkBoxTextOnly.Margin = new System.Windows.Forms.Padding(4); - this.checkBoxTextOnly.Name = "checkBoxTextOnly"; - this.checkBoxTextOnly.Padding = new System.Windows.Forms.Padding(2); - this.checkBoxTextOnly.Size = new System.Drawing.Size(176, 21); - this.checkBoxTextOnly.TabIndex = 7; - this.checkBoxTextOnly.Text = "Remove images from presence"; - this.checkBoxTextOnly.UseVisualStyleBackColor = true; - // - // checkBoxShowRemainingTime - // - this.checkBoxShowRemainingTime.AutoSize = true; - this.checkBoxShowRemainingTime.ForeColor = System.Drawing.Color.Black; - this.checkBoxShowRemainingTime.Location = new System.Drawing.Point(266, 64); - this.checkBoxShowRemainingTime.Margin = new System.Windows.Forms.Padding(4); - this.checkBoxShowRemainingTime.Name = "checkBoxShowRemainingTime"; - this.checkBoxShowRemainingTime.Padding = new System.Windows.Forms.Padding(2); - this.checkBoxShowRemainingTime.Size = new System.Drawing.Size(216, 21); - this.checkBoxShowRemainingTime.TabIndex = 6; - this.checkBoxShowRemainingTime.Text = "Show remaining instead of elapsed time"; - this.checkBoxShowRemainingTime.UseVisualStyleBackColor = true; - // - // checkBoxPresenceUpdate - // - this.checkBoxPresenceUpdate.AutoSize = true; - this.checkBoxPresenceUpdate.ForeColor = System.Drawing.Color.Black; - this.checkBoxPresenceUpdate.Location = new System.Drawing.Point(266, 6); - this.checkBoxPresenceUpdate.Margin = new System.Windows.Forms.Padding(4); - this.checkBoxPresenceUpdate.Name = "checkBoxPresenceUpdate"; - this.checkBoxPresenceUpdate.Padding = new System.Windows.Forms.Padding(2); - this.checkBoxPresenceUpdate.Size = new System.Drawing.Size(224, 21); - this.checkBoxPresenceUpdate.TabIndex = 5; - this.checkBoxPresenceUpdate.Text = "Show presence when no music is playing"; - this.checkBoxPresenceUpdate.UseVisualStyleBackColor = true; - // - // textBoxSeparator - // - this.textBoxSeparator.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxSeparator.Location = new System.Drawing.Point(87, 3); - this.textBoxSeparator.Name = "textBoxSeparator"; - this.textBoxSeparator.Size = new System.Drawing.Size(87, 25); - this.textBoxSeparator.TabIndex = 4; - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label5.ForeColor = System.Drawing.Color.Black; - this.label5.Location = new System.Drawing.Point(14, 7); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(70, 15); - this.label5.TabIndex = 0; - this.label5.Text = "Separators:"; - // - // buttonRestoreDefaults - // - this.buttonRestoreDefaults.AutoSize = true; - this.buttonRestoreDefaults.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.buttonRestoreDefaults.Dock = System.Windows.Forms.DockStyle.Right; - this.buttonRestoreDefaults.Location = new System.Drawing.Point(316, 0); - this.buttonRestoreDefaults.Margin = new System.Windows.Forms.Padding(10); - this.buttonRestoreDefaults.Name = "buttonRestoreDefaults"; - this.buttonRestoreDefaults.Padding = new System.Windows.Forms.Padding(5); - this.buttonRestoreDefaults.Size = new System.Drawing.Size(106, 30); - this.buttonRestoreDefaults.TabIndex = 2; - this.buttonRestoreDefaults.Text = "Restore Defaults"; - this.buttonRestoreDefaults.UseVisualStyleBackColor = true; - this.buttonRestoreDefaults.Click += new System.EventHandler(this.buttonRestoreDefaults_Click); - // - // buttonSaveClose - // - this.buttonSaveClose.AutoSize = true; - this.buttonSaveClose.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.buttonSaveClose.Dock = System.Windows.Forms.DockStyle.Right; - this.buttonSaveClose.Location = new System.Drawing.Point(422, 0); - this.buttonSaveClose.Margin = new System.Windows.Forms.Padding(10); - this.buttonSaveClose.Name = "buttonSaveClose"; - this.buttonSaveClose.Padding = new System.Windows.Forms.Padding(5); - this.buttonSaveClose.Size = new System.Drawing.Size(102, 30); - this.buttonSaveClose.TabIndex = 0; - this.buttonSaveClose.Text = "Save and Close"; - this.buttonSaveClose.UseVisualStyleBackColor = true; - this.buttonSaveClose.Click += new System.EventHandler(this.buttonSaveClose_Click); - // - // buttonPlaceholders - // - this.buttonPlaceholders.AutoSize = true; - this.buttonPlaceholders.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.buttonPlaceholders.Dock = System.Windows.Forms.DockStyle.Left; - this.buttonPlaceholders.Location = new System.Drawing.Point(0, 0); - this.buttonPlaceholders.Margin = new System.Windows.Forms.Padding(10); - this.buttonPlaceholders.Name = "buttonPlaceholders"; - this.buttonPlaceholders.Padding = new System.Windows.Forms.Padding(5); - this.buttonPlaceholders.Size = new System.Drawing.Size(88, 30); - this.buttonPlaceholders.TabIndex = 1; - this.buttonPlaceholders.Text = "Placeholders"; - this.buttonPlaceholders.UseVisualStyleBackColor = true; - this.buttonPlaceholders.Click += new System.EventHandler(this.buttonPlaceholders_Click); - // - // panel2 - // - this.panel2.AutoSize = true; - this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel2.BackColor = System.Drawing.Color.Transparent; - this.panel2.Controls.Add(this.labelImgurClientId); - this.panel2.Controls.Add(this.textBoxImgurClientId); - this.panel2.Controls.Add(this.customButtonToggle); - this.panel2.Controls.Add(this.checkBoxShowOnlyNonPlayingState); - this.panel2.Controls.Add(this.checkBoxShowPlayState); - this.panel2.Controls.Add(this.checkBoxShowTime); - this.panel2.Controls.Add(this.checkBoxArtworkUpload); - this.panel2.Controls.Add(this.labelDiscordAppId); - this.panel2.Controls.Add(this.textBoxDiscordAppId); - this.panel2.Controls.Add(this.label5); - this.panel2.Controls.Add(this.textBoxSeparator); - this.panel2.Controls.Add(this.checkBoxShowRemainingTime); - this.panel2.Controls.Add(this.checkBoxTextOnly); - this.panel2.Controls.Add(this.checkBoxPresenceUpdate); - this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; - this.panel2.Location = new System.Drawing.Point(0, 157); - this.panel2.MinimumSize = new System.Drawing.Size(0, 100); - this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(524, 204); - this.panel2.TabIndex = 1; - // - // labelImgurClientId - // - this.labelImgurClientId.AutoSize = true; - this.labelImgurClientId.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelImgurClientId.ForeColor = System.Drawing.Color.Black; - this.labelImgurClientId.Location = new System.Drawing.Point(14, 65); - this.labelImgurClientId.Name = "labelImgurClientId"; - this.labelImgurClientId.Size = new System.Drawing.Size(88, 15); - this.labelImgurClientId.TabIndex = 19; - this.labelImgurClientId.Text = "Imgur Client ID"; - // - // textBoxImgurClientId - // - this.textBoxImgurClientId.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxImgurClientId.Location = new System.Drawing.Point(108, 62); - this.textBoxImgurClientId.Name = "textBoxImgurClientId"; - this.textBoxImgurClientId.Size = new System.Drawing.Size(151, 25); - this.textBoxImgurClientId.TabIndex = 20; - this.textBoxImgurClientId.TextChanged += new System.EventHandler(this.textBoxImgurClientId_TextChanged); - // - // customButtonToggle - // - this.customButtonToggle.AutoSize = true; - this.customButtonToggle.ForeColor = System.Drawing.Color.Black; - this.customButtonToggle.Location = new System.Drawing.Point(266, 118); - this.customButtonToggle.Margin = new System.Windows.Forms.Padding(4); - this.customButtonToggle.Name = "customButtonToggle"; - this.customButtonToggle.Padding = new System.Windows.Forms.Padding(2); - this.customButtonToggle.Size = new System.Drawing.Size(135, 21); - this.customButtonToggle.TabIndex = 18; - this.customButtonToggle.Text = "Enable Custom Button"; - this.customButtonToggle.UseVisualStyleBackColor = true; - // - // checkBoxShowOnlyNonPlayingState - // - this.checkBoxShowOnlyNonPlayingState.AutoSize = true; - this.checkBoxShowOnlyNonPlayingState.Checked = true; - this.checkBoxShowOnlyNonPlayingState.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxShowOnlyNonPlayingState.ForeColor = System.Drawing.Color.Black; - this.checkBoxShowOnlyNonPlayingState.Location = new System.Drawing.Point(17, 145); - this.checkBoxShowOnlyNonPlayingState.Margin = new System.Windows.Forms.Padding(4); - this.checkBoxShowOnlyNonPlayingState.Name = "checkBoxShowOnlyNonPlayingState"; - this.checkBoxShowOnlyNonPlayingState.Padding = new System.Windows.Forms.Padding(2); - this.checkBoxShowOnlyNonPlayingState.Size = new System.Drawing.Size(210, 21); - this.checkBoxShowOnlyNonPlayingState.TabIndex = 13; - this.checkBoxShowOnlyNonPlayingState.Text = "Don\'t show playing state when playing"; - this.checkBoxShowOnlyNonPlayingState.UseVisualStyleBackColor = true; - // - // checkBoxShowPlayState - // - this.checkBoxShowPlayState.AutoSize = true; - this.checkBoxShowPlayState.Checked = true; - this.checkBoxShowPlayState.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxShowPlayState.ForeColor = System.Drawing.Color.Black; - this.checkBoxShowPlayState.Location = new System.Drawing.Point(17, 118); - this.checkBoxShowPlayState.Margin = new System.Windows.Forms.Padding(4); - this.checkBoxShowPlayState.Name = "checkBoxShowPlayState"; - this.checkBoxShowPlayState.Padding = new System.Windows.Forms.Padding(2); - this.checkBoxShowPlayState.Size = new System.Drawing.Size(195, 21); - this.checkBoxShowPlayState.TabIndex = 12; - this.checkBoxShowPlayState.Text = "Show playing state on album cover"; - this.checkBoxShowPlayState.UseVisualStyleBackColor = true; - // - // checkBoxShowTime - // - this.checkBoxShowTime.AutoSize = true; - this.checkBoxShowTime.Checked = true; - this.checkBoxShowTime.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxShowTime.ForeColor = System.Drawing.Color.Black; - this.checkBoxShowTime.Location = new System.Drawing.Point(266, 34); - this.checkBoxShowTime.Margin = new System.Windows.Forms.Padding(4); - this.checkBoxShowTime.Name = "checkBoxShowTime"; - this.checkBoxShowTime.Padding = new System.Windows.Forms.Padding(2); - this.checkBoxShowTime.Size = new System.Drawing.Size(79, 21); - this.checkBoxShowTime.TabIndex = 11; - this.checkBoxShowTime.Text = "Show time"; - this.checkBoxShowTime.UseVisualStyleBackColor = true; - // - // checkBoxArtworkUpload - // - this.checkBoxArtworkUpload.AutoSize = true; - this.checkBoxArtworkUpload.BackColor = System.Drawing.Color.Transparent; - this.checkBoxArtworkUpload.ForeColor = System.Drawing.Color.Black; - this.checkBoxArtworkUpload.Location = new System.Drawing.Point(17, 91); - this.checkBoxArtworkUpload.Margin = new System.Windows.Forms.Padding(4); - this.checkBoxArtworkUpload.Name = "checkBoxArtworkUpload"; - this.checkBoxArtworkUpload.Padding = new System.Windows.Forms.Padding(2); - this.checkBoxArtworkUpload.Size = new System.Drawing.Size(130, 21); - this.checkBoxArtworkUpload.TabIndex = 10; - this.checkBoxArtworkUpload.Text = "Upload album covers"; - this.checkBoxArtworkUpload.UseVisualStyleBackColor = false; - this.checkBoxArtworkUpload.CheckedChanged += new System.EventHandler(this.checkBoxArtworkUpload_CheckedChanged); - // - // labelDiscordAppId - // - this.labelDiscordAppId.AutoSize = true; - this.labelDiscordAppId.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelDiscordAppId.ForeColor = System.Drawing.Color.Black; - this.labelDiscordAppId.Location = new System.Drawing.Point(14, 35); - this.labelDiscordAppId.Name = "labelDiscordAppId"; - this.labelDiscordAppId.Size = new System.Drawing.Size(91, 15); - this.labelDiscordAppId.TabIndex = 8; - this.labelDiscordAppId.Text = "Discord App ID:"; - // - // textBoxDiscordAppId - // - this.textBoxDiscordAppId.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxDiscordAppId.Location = new System.Drawing.Point(108, 32); - this.textBoxDiscordAppId.Name = "textBoxDiscordAppId"; - this.textBoxDiscordAppId.Size = new System.Drawing.Size(151, 25); - this.textBoxDiscordAppId.TabIndex = 9; - this.textBoxDiscordAppId.TextChanged += new System.EventHandler(this.textBoxDiscordAppId_TextChanged); - // - // panel3 - // - this.panel3.AutoScroll = true; - this.panel3.AutoSize = true; - this.panel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel3.BackColor = System.Drawing.Color.Transparent; - this.panel3.Controls.Add(this.buttonRestoreDefaults); - this.panel3.Controls.Add(this.buttonPlaceholders); - this.panel3.Controls.Add(this.buttonSaveClose); - this.panel3.Dock = System.Windows.Forms.DockStyle.Bottom; - this.panel3.Location = new System.Drawing.Point(0, 361); - this.panel3.MinimumSize = new System.Drawing.Size(0, 30); - this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(524, 30); - this.panel3.TabIndex = 2; - // - // panel4 - // - this.panel4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.panel4.Controls.Add(this.label9); - this.panel4.Controls.Add(this.customButtonUrl); - this.panel4.Controls.Add(this.label8); - this.panel4.Controls.Add(this.customButtonLabel); - this.panel4.Controls.Add(this.textBoxSmallImage); - this.panel4.Controls.Add(this.textBoxLargeImage); - this.panel4.Controls.Add(this.label4); - this.panel4.Controls.Add(this.label1); - this.panel4.Controls.Add(this.textBoxTrackCnt); - this.panel4.Controls.Add(this.textBoxDetails); - this.panel4.Controls.Add(this.label3); - this.panel4.Controls.Add(this.textBoxState); - this.panel4.Controls.Add(this.textBoxTrackNo); - this.panel4.Controls.Add(this.label2); - this.panel4.Dock = System.Windows.Forms.DockStyle.Top; - this.panel4.Location = new System.Drawing.Point(0, 0); - this.panel4.Name = "panel4"; - this.panel4.Size = new System.Drawing.Size(524, 157); - this.panel4.TabIndex = 1; - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label9.ForeColor = System.Drawing.Color.White; - this.label9.Location = new System.Drawing.Point(198, 99); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(241, 15); - this.label9.TabIndex = 19; - this.label9.Text = "Custom Button Url (Supports Placeholders)"; - // - // customButtonUrl - // - this.customButtonUrl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.textBoxDetails.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.textBoxDetails.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxDetails.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.textBoxDetails.Location = new System.Drawing.Point(162, 49); + this.textBoxDetails.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxDetails.Name = "textBoxDetails"; + this.textBoxDetails.Size = new System.Drawing.Size(412, 33); + this.textBoxDetails.TabIndex = 2; + this.textBoxDetails.Text = "Presence details"; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Font = new System.Drawing.Font("Arial", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.label1.Location = new System.Drawing.Point(162, 15); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(125, 29); + this.label1.TabIndex = 1; + this.label1.Text = "MusicBee"; + // + // textBoxLargeImage + // + this.textBoxLargeImage.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.textBoxLargeImage.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxLargeImage.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.textBoxLargeImage.Location = new System.Drawing.Point(18, 14); + this.textBoxLargeImage.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxLargeImage.Multiline = true; + this.textBoxLargeImage.Name = "textBoxLargeImage"; + this.textBoxLargeImage.Size = new System.Drawing.Size(133, 90); + this.textBoxLargeImage.TabIndex = 0; + this.textBoxLargeImage.Text = "Large Image Text"; + // + // checkBoxTextOnly + // + this.checkBoxTextOnly.AutoSize = true; + this.checkBoxTextOnly.ForeColor = System.Drawing.Color.Black; + this.checkBoxTextOnly.Location = new System.Drawing.Point(399, 140); + this.checkBoxTextOnly.Margin = new System.Windows.Forms.Padding(6); + this.checkBoxTextOnly.Name = "checkBoxTextOnly"; + this.checkBoxTextOnly.Padding = new System.Windows.Forms.Padding(3); + this.checkBoxTextOnly.Size = new System.Drawing.Size(261, 30); + this.checkBoxTextOnly.TabIndex = 7; + this.checkBoxTextOnly.Text = "Remove images from presence"; + this.checkBoxTextOnly.UseVisualStyleBackColor = true; + // + // checkBoxShowRemainingTime + // + this.checkBoxShowRemainingTime.AutoSize = true; + this.checkBoxShowRemainingTime.ForeColor = System.Drawing.Color.Black; + this.checkBoxShowRemainingTime.Location = new System.Drawing.Point(399, 98); + this.checkBoxShowRemainingTime.Margin = new System.Windows.Forms.Padding(6); + this.checkBoxShowRemainingTime.Name = "checkBoxShowRemainingTime"; + this.checkBoxShowRemainingTime.Padding = new System.Windows.Forms.Padding(3); + this.checkBoxShowRemainingTime.Size = new System.Drawing.Size(322, 30); + this.checkBoxShowRemainingTime.TabIndex = 6; + this.checkBoxShowRemainingTime.Text = "Show remaining instead of elapsed time"; + this.checkBoxShowRemainingTime.UseVisualStyleBackColor = true; + // + // checkBoxPresenceUpdate + // + this.checkBoxPresenceUpdate.AutoSize = true; + this.checkBoxPresenceUpdate.ForeColor = System.Drawing.Color.Black; + this.checkBoxPresenceUpdate.Location = new System.Drawing.Point(399, 9); + this.checkBoxPresenceUpdate.Margin = new System.Windows.Forms.Padding(6); + this.checkBoxPresenceUpdate.Name = "checkBoxPresenceUpdate"; + this.checkBoxPresenceUpdate.Padding = new System.Windows.Forms.Padding(3); + this.checkBoxPresenceUpdate.Size = new System.Drawing.Size(328, 30); + this.checkBoxPresenceUpdate.TabIndex = 5; + this.checkBoxPresenceUpdate.Text = "Show presence when no music is playing"; + this.checkBoxPresenceUpdate.UseVisualStyleBackColor = true; + // + // textBoxSeparator + // + this.textBoxSeparator.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxSeparator.Location = new System.Drawing.Point(130, 5); + this.textBoxSeparator.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxSeparator.Name = "textBoxSeparator"; + this.textBoxSeparator.Size = new System.Drawing.Size(128, 33); + this.textBoxSeparator.TabIndex = 4; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.ForeColor = System.Drawing.Color.Black; + this.label5.Location = new System.Drawing.Point(21, 11); + this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(103, 22); + this.label5.TabIndex = 0; + this.label5.Text = "Separators:"; + // + // buttonRestoreDefaults + // + this.buttonRestoreDefaults.AutoSize = true; + this.buttonRestoreDefaults.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.buttonRestoreDefaults.Dock = System.Windows.Forms.DockStyle.Right; + this.buttonRestoreDefaults.Location = new System.Drawing.Point(484, 0); + this.buttonRestoreDefaults.Margin = new System.Windows.Forms.Padding(15); + this.buttonRestoreDefaults.Name = "buttonRestoreDefaults"; + this.buttonRestoreDefaults.Padding = new System.Windows.Forms.Padding(8); + this.buttonRestoreDefaults.Size = new System.Drawing.Size(156, 46); + this.buttonRestoreDefaults.TabIndex = 2; + this.buttonRestoreDefaults.Text = "Restore Defaults"; + this.buttonRestoreDefaults.UseVisualStyleBackColor = true; + this.buttonRestoreDefaults.Click += new System.EventHandler(this.buttonRestoreDefaults_Click); + // + // buttonSaveClose + // + this.buttonSaveClose.AutoSize = true; + this.buttonSaveClose.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.buttonSaveClose.Dock = System.Windows.Forms.DockStyle.Right; + this.buttonSaveClose.Location = new System.Drawing.Point(640, 0); + this.buttonSaveClose.Margin = new System.Windows.Forms.Padding(15); + this.buttonSaveClose.Name = "buttonSaveClose"; + this.buttonSaveClose.Padding = new System.Windows.Forms.Padding(8); + this.buttonSaveClose.Size = new System.Drawing.Size(146, 46); + this.buttonSaveClose.TabIndex = 0; + this.buttonSaveClose.Text = "Save and Close"; + this.buttonSaveClose.UseVisualStyleBackColor = true; + this.buttonSaveClose.Click += new System.EventHandler(this.buttonSaveClose_Click); + // + // buttonPlaceholders + // + this.buttonPlaceholders.AutoSize = true; + this.buttonPlaceholders.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.buttonPlaceholders.Dock = System.Windows.Forms.DockStyle.Left; + this.buttonPlaceholders.Location = new System.Drawing.Point(0, 0); + this.buttonPlaceholders.Margin = new System.Windows.Forms.Padding(15); + this.buttonPlaceholders.Name = "buttonPlaceholders"; + this.buttonPlaceholders.Padding = new System.Windows.Forms.Padding(8); + this.buttonPlaceholders.Size = new System.Drawing.Size(126, 46); + this.buttonPlaceholders.TabIndex = 1; + this.buttonPlaceholders.Text = "Placeholders"; + this.buttonPlaceholders.UseVisualStyleBackColor = true; + this.buttonPlaceholders.Click += new System.EventHandler(this.buttonPlaceholders_Click); + // + // panel2 + // + this.panel2.AutoSize = true; + this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel2.BackColor = System.Drawing.Color.Transparent; + this.panel2.Controls.Add(this.labelArtworkUploader); + this.panel2.Controls.Add(this.comboBoxArtworkUploader); + this.panel2.Controls.Add(this.labelImgurClientId); + this.panel2.Controls.Add(this.textBoxImgurClientId); + this.panel2.Controls.Add(this.customButtonToggle); + this.panel2.Controls.Add(this.checkBoxShowOnlyNonPlayingState); + this.panel2.Controls.Add(this.checkBoxShowPlayState); + this.panel2.Controls.Add(this.checkBoxShowTime); + this.panel2.Controls.Add(this.checkBoxArtworkUpload); + this.panel2.Controls.Add(this.labelDiscordAppId); + this.panel2.Controls.Add(this.textBoxDiscordAppId); + this.panel2.Controls.Add(this.label5); + this.panel2.Controls.Add(this.textBoxSeparator); + this.panel2.Controls.Add(this.checkBoxShowRemainingTime); + this.panel2.Controls.Add(this.checkBoxTextOnly); + this.panel2.Controls.Add(this.checkBoxPresenceUpdate); + this.panel2.Controls.Add(this.buttonS3Settings); + this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel2.Location = new System.Drawing.Point(0, 242); + this.panel2.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.panel2.MinimumSize = new System.Drawing.Size(0, 154); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(786, 314); + this.panel2.TabIndex = 1; + // + // labelArtworkUploader + // + this.labelArtworkUploader.AutoSize = true; + this.labelArtworkUploader.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelArtworkUploader.ForeColor = System.Drawing.Color.Black; + this.labelArtworkUploader.Location = new System.Drawing.Point(21, 136); + this.labelArtworkUploader.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelArtworkUploader.Name = "labelArtworkUploader"; + this.labelArtworkUploader.Size = new System.Drawing.Size(154, 22); + this.labelArtworkUploader.TabIndex = 22; + this.labelArtworkUploader.Text = "Artwork Uploader:"; + // + // comboBoxArtworkUploader + // + this.comboBoxArtworkUploader.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxArtworkUploader.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.comboBoxArtworkUploader.FormattingEnabled = true; + this.comboBoxArtworkUploader.Items.AddRange(new object[] { + "Imgur", + "Amazon S3"}); + this.comboBoxArtworkUploader.Location = new System.Drawing.Point(182, 130); + this.comboBoxArtworkUploader.Name = "comboBoxArtworkUploader"; + this.comboBoxArtworkUploader.Size = new System.Drawing.Size(204, 34); + this.comboBoxArtworkUploader.TabIndex = 21; + this.comboBoxArtworkUploader.SelectedIndexChanged += new System.EventHandler(this.comboBoxArtworkUploader_SelectedIndexChanged); + // + // labelImgurClientId + // + this.labelImgurClientId.AutoSize = true; + this.labelImgurClientId.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelImgurClientId.ForeColor = System.Drawing.Color.Black; + this.labelImgurClientId.Location = new System.Drawing.Point(21, 182); + this.labelImgurClientId.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelImgurClientId.Name = "labelImgurClientId"; + this.labelImgurClientId.Size = new System.Drawing.Size(132, 22); + this.labelImgurClientId.TabIndex = 19; + this.labelImgurClientId.Text = "Imgur Client ID:"; + // + // textBoxImgurClientId + // + this.textBoxImgurClientId.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxImgurClientId.Location = new System.Drawing.Point(162, 177); + this.textBoxImgurClientId.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxImgurClientId.Name = "textBoxImgurClientId"; + this.textBoxImgurClientId.Size = new System.Drawing.Size(224, 33); + this.textBoxImgurClientId.TabIndex = 20; + this.textBoxImgurClientId.TextChanged += new System.EventHandler(this.textBoxImgurClientId_TextChanged); + // + // customButtonToggle + // + this.customButtonToggle.AutoSize = true; + this.customButtonToggle.ForeColor = System.Drawing.Color.Black; + this.customButtonToggle.Location = new System.Drawing.Point(399, 182); + this.customButtonToggle.Margin = new System.Windows.Forms.Padding(6); + this.customButtonToggle.Name = "customButtonToggle"; + this.customButtonToggle.Padding = new System.Windows.Forms.Padding(3); + this.customButtonToggle.Size = new System.Drawing.Size(202, 30); + this.customButtonToggle.TabIndex = 18; + this.customButtonToggle.Text = "Enable Custom Button"; + this.customButtonToggle.UseVisualStyleBackColor = true; + // + // checkBoxShowOnlyNonPlayingState + // + this.checkBoxShowOnlyNonPlayingState.AutoSize = true; + this.checkBoxShowOnlyNonPlayingState.Checked = true; + this.checkBoxShowOnlyNonPlayingState.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxShowOnlyNonPlayingState.ForeColor = System.Drawing.Color.Black; + this.checkBoxShowOnlyNonPlayingState.Location = new System.Drawing.Point(26, 267); + this.checkBoxShowOnlyNonPlayingState.Margin = new System.Windows.Forms.Padding(6); + this.checkBoxShowOnlyNonPlayingState.Name = "checkBoxShowOnlyNonPlayingState"; + this.checkBoxShowOnlyNonPlayingState.Padding = new System.Windows.Forms.Padding(3); + this.checkBoxShowOnlyNonPlayingState.Size = new System.Drawing.Size(308, 30); + this.checkBoxShowOnlyNonPlayingState.TabIndex = 13; + this.checkBoxShowOnlyNonPlayingState.Text = "Don\'t show playing state when playing"; + this.checkBoxShowOnlyNonPlayingState.UseVisualStyleBackColor = true; + // + // checkBoxShowPlayState + // + this.checkBoxShowPlayState.AutoSize = true; + this.checkBoxShowPlayState.Checked = true; + this.checkBoxShowPlayState.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxShowPlayState.ForeColor = System.Drawing.Color.Black; + this.checkBoxShowPlayState.Location = new System.Drawing.Point(26, 226); + this.checkBoxShowPlayState.Margin = new System.Windows.Forms.Padding(6); + this.checkBoxShowPlayState.Name = "checkBoxShowPlayState"; + this.checkBoxShowPlayState.Padding = new System.Windows.Forms.Padding(3); + this.checkBoxShowPlayState.Size = new System.Drawing.Size(285, 30); + this.checkBoxShowPlayState.TabIndex = 12; + this.checkBoxShowPlayState.Text = "Show playing state on album cover"; + this.checkBoxShowPlayState.UseVisualStyleBackColor = true; + // + // checkBoxShowTime + // + this.checkBoxShowTime.AutoSize = true; + this.checkBoxShowTime.Checked = true; + this.checkBoxShowTime.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxShowTime.ForeColor = System.Drawing.Color.Black; + this.checkBoxShowTime.Location = new System.Drawing.Point(399, 52); + this.checkBoxShowTime.Margin = new System.Windows.Forms.Padding(6); + this.checkBoxShowTime.Name = "checkBoxShowTime"; + this.checkBoxShowTime.Padding = new System.Windows.Forms.Padding(3); + this.checkBoxShowTime.Size = new System.Drawing.Size(115, 30); + this.checkBoxShowTime.TabIndex = 11; + this.checkBoxShowTime.Text = "Show time"; + this.checkBoxShowTime.UseVisualStyleBackColor = true; + // + // checkBoxArtworkUpload + // + this.checkBoxArtworkUpload.AutoSize = true; + this.checkBoxArtworkUpload.BackColor = System.Drawing.Color.Transparent; + this.checkBoxArtworkUpload.ForeColor = System.Drawing.Color.Black; + this.checkBoxArtworkUpload.Location = new System.Drawing.Point(26, 95); + this.checkBoxArtworkUpload.Margin = new System.Windows.Forms.Padding(6); + this.checkBoxArtworkUpload.Name = "checkBoxArtworkUpload"; + this.checkBoxArtworkUpload.Padding = new System.Windows.Forms.Padding(3); + this.checkBoxArtworkUpload.Size = new System.Drawing.Size(189, 30); + this.checkBoxArtworkUpload.TabIndex = 10; + this.checkBoxArtworkUpload.Text = "Upload album covers"; + this.checkBoxArtworkUpload.UseVisualStyleBackColor = false; + this.checkBoxArtworkUpload.CheckedChanged += new System.EventHandler(this.checkBoxArtworkUpload_CheckedChanged); + // + // labelDiscordAppId + // + this.labelDiscordAppId.AutoSize = true; + this.labelDiscordAppId.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelDiscordAppId.ForeColor = System.Drawing.Color.Black; + this.labelDiscordAppId.Location = new System.Drawing.Point(21, 54); + this.labelDiscordAppId.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.labelDiscordAppId.Name = "labelDiscordAppId"; + this.labelDiscordAppId.Size = new System.Drawing.Size(135, 22); + this.labelDiscordAppId.TabIndex = 8; + this.labelDiscordAppId.Text = "Discord App ID:"; + // + // textBoxDiscordAppId + // + this.textBoxDiscordAppId.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBoxDiscordAppId.Location = new System.Drawing.Point(162, 49); + this.textBoxDiscordAppId.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBoxDiscordAppId.Name = "textBoxDiscordAppId"; + this.textBoxDiscordAppId.Size = new System.Drawing.Size(224, 33); + this.textBoxDiscordAppId.TabIndex = 9; + this.textBoxDiscordAppId.TextChanged += new System.EventHandler(this.textBoxDiscordAppId_TextChanged); + // + // buttonS3Settings + // + this.buttonS3Settings.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.buttonS3Settings.Location = new System.Drawing.Point(24, 176); + this.buttonS3Settings.Margin = new System.Windows.Forms.Padding(15); + this.buttonS3Settings.Name = "buttonS3Settings"; + this.buttonS3Settings.Padding = new System.Windows.Forms.Padding(4); + this.buttonS3Settings.Size = new System.Drawing.Size(362, 38); + this.buttonS3Settings.TabIndex = 23; + this.buttonS3Settings.Text = "Configure S3 Settings"; + this.buttonS3Settings.UseVisualStyleBackColor = true; + this.buttonS3Settings.Visible = false; + this.buttonS3Settings.Click += new System.EventHandler(this.buttonS3Settings_Click); + // + // panel3 + // + this.panel3.AutoScroll = true; + this.panel3.AutoSize = true; + this.panel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel3.BackColor = System.Drawing.Color.Transparent; + this.panel3.Controls.Add(this.buttonRestoreDefaults); + this.panel3.Controls.Add(this.buttonPlaceholders); + this.panel3.Controls.Add(this.buttonSaveClose); + this.panel3.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel3.Location = new System.Drawing.Point(0, 556); + this.panel3.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.panel3.MinimumSize = new System.Drawing.Size(0, 46); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(786, 46); + this.panel3.TabIndex = 2; + // + // panel4 + // + this.panel4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.panel4.Controls.Add(this.label9); + this.panel4.Controls.Add(this.customButtonUrl); + this.panel4.Controls.Add(this.label8); + this.panel4.Controls.Add(this.customButtonLabel); + this.panel4.Controls.Add(this.textBoxSmallImage); + this.panel4.Controls.Add(this.textBoxLargeImage); + this.panel4.Controls.Add(this.label4); + this.panel4.Controls.Add(this.label1); + this.panel4.Controls.Add(this.textBoxTrackCnt); + this.panel4.Controls.Add(this.textBoxDetails); + this.panel4.Controls.Add(this.label3); + this.panel4.Controls.Add(this.textBoxState); + this.panel4.Controls.Add(this.textBoxTrackNo); + this.panel4.Controls.Add(this.label2); + this.panel4.Dock = System.Windows.Forms.DockStyle.Top; + this.panel4.Location = new System.Drawing.Point(0, 0); + this.panel4.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(786, 242); + this.panel4.TabIndex = 1; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label9.ForeColor = System.Drawing.Color.White; + this.label9.Location = new System.Drawing.Point(297, 152); + this.label9.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(354, 22); + this.label9.TabIndex = 19; + this.label9.Text = "Custom Button Url (Supports Placeholders)"; + // + // customButtonUrl + // + this.customButtonUrl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.customButtonUrl.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.customButtonUrl.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.customButtonUrl.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.customButtonUrl.Location = new System.Drawing.Point(198, 117); - this.customButtonUrl.Name = "customButtonUrl"; - this.customButtonUrl.Size = new System.Drawing.Size(290, 25); - this.customButtonUrl.TabIndex = 20; - this.customButtonUrl.TextChanged += new System.EventHandler(this.customButtonUrl_TextChanged); - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label8.ForeColor = System.Drawing.Color.White; - this.label8.Location = new System.Drawing.Point(9, 99); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(124, 15); - this.label8.TabIndex = 19; - this.label8.Text = "Custom Button Label:"; - // - // customButtonLabel - // - this.customButtonLabel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); - this.customButtonLabel.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.customButtonLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); - this.customButtonLabel.Location = new System.Drawing.Point(12, 117); - this.customButtonLabel.Name = "customButtonLabel"; - this.customButtonLabel.Size = new System.Drawing.Size(177, 25); - this.customButtonLabel.TabIndex = 10; - // - // SettingsWindow - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.AutoSize = true; - this.BackColor = System.Drawing.Color.White; - this.ClientSize = new System.Drawing.Size(524, 391); - this.Controls.Add(this.panel2); - this.Controls.Add(this.panel3); - this.Controls.Add(this.panel4); - this.MinimumSize = new System.Drawing.Size(523, 274); - this.Name = "SettingsWindow"; - this.ShowIcon = false; - this.Text = "DiscordBee Settings"; - this.panel2.ResumeLayout(false); - this.panel2.PerformLayout(); - this.panel3.ResumeLayout(false); - this.panel3.PerformLayout(); - this.panel4.ResumeLayout(false); - this.panel4.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); + this.customButtonUrl.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.customButtonUrl.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.customButtonUrl.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.customButtonUrl.Location = new System.Drawing.Point(297, 180); + this.customButtonUrl.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.customButtonUrl.Name = "customButtonUrl"; + this.customButtonUrl.Size = new System.Drawing.Size(433, 33); + this.customButtonUrl.TabIndex = 20; + this.customButtonUrl.TextChanged += new System.EventHandler(this.customButtonUrl_TextChanged); + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label8.ForeColor = System.Drawing.Color.White; + this.label8.Location = new System.Drawing.Point(14, 152); + this.label8.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(182, 22); + this.label8.TabIndex = 19; + this.label8.Text = "Custom Button Label:"; + // + // customButtonLabel + // + this.customButtonLabel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(114)))), ((int)(((byte)(137)))), ((int)(((byte)(218))))); + this.customButtonLabel.Font = new System.Drawing.Font("Arial", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.customButtonLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(230)))), ((int)(((byte)(246))))); + this.customButtonLabel.Location = new System.Drawing.Point(18, 180); + this.customButtonLabel.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.customButtonLabel.Name = "customButtonLabel"; + this.customButtonLabel.Size = new System.Drawing.Size(264, 33); + this.customButtonLabel.TabIndex = 10; + // + // SettingsWindow + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(786, 602); + this.Controls.Add(this.panel2); + this.Controls.Add(this.panel3); + this.Controls.Add(this.panel4); + this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.MinimumSize = new System.Drawing.Size(774, 391); + this.Name = "SettingsWindow"; + this.ShowIcon = false; + this.Text = "DiscordBee Settings"; + this.panel2.ResumeLayout(false); + this.panel2.PerformLayout(); + this.panel3.ResumeLayout(false); + this.panel3.PerformLayout(); + this.panel4.ResumeLayout(false); + this.panel4.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); } @@ -575,5 +645,8 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox checkBoxShowOnlyNonPlayingState; private System.Windows.Forms.Label labelImgurClientId; private System.Windows.Forms.TextBox textBoxImgurClientId; - } + private System.Windows.Forms.Label labelArtworkUploader; + private System.Windows.Forms.ComboBox comboBoxArtworkUploader; + private System.Windows.Forms.Button buttonS3Settings; + } } diff --git a/UI/SettingsWindow.cs b/UI/SettingsWindow.cs index 2784dc4..1c0c564 100644 --- a/UI/SettingsWindow.cs +++ b/UI/SettingsWindow.cs @@ -1,7 +1,9 @@ namespace MusicBeePlugin.UI { using System; + using System.Collections.Generic; using System.Drawing; + using System.Linq; using System.Windows.Forms; public partial class SettingsWindow : Form @@ -66,6 +68,7 @@ private void UpdateValues(Settings settings) checkBoxShowPlayState.Checked = settings.ShowPlayState; checkBoxShowOnlyNonPlayingState.Checked = settings.ShowOnlyNonPlayingState; checkBoxArtworkUpload.Checked = settings.UploadArtwork; + comboBoxArtworkUploader.SelectedIndex = comboBoxArtworkUploader.FindString(settings.ArtworkUploader); customButtonLabel.Text = settings.ButtonLabel; customButtonUrl.Text = settings.ButtonUrl; customButtonToggle.Checked = settings.ShowButton; @@ -110,6 +113,7 @@ private void buttonSaveClose_Click(object sender, EventArgs e) _settings.ShowPlayState = checkBoxShowPlayState.Checked; _settings.ShowOnlyNonPlayingState = checkBoxShowOnlyNonPlayingState.Checked; _settings.UploadArtwork = checkBoxArtworkUpload.Checked; + _settings.ArtworkUploader = comboBoxArtworkUploader.SelectedItem.ToString(); _settings.ButtonUrl = customButtonUrl.Text; _settings.ButtonLabel = customButtonLabel.Text; _settings.ShowButton = customButtonToggle.Checked; @@ -124,7 +128,7 @@ private void buttonSaveClose_Click(object sender, EventArgs e) Hide(); } - private bool ValidateInputs() + internal bool ValidateInputs() { bool ContainsDigitsOnly(string s) { @@ -168,9 +172,41 @@ bool validateImgurClientId() return true; } - if (checkBoxArtworkUpload.Checked && textBoxImgurClientId.Text.Length > 0 && !validateImgurClientId()) + bool validateS3() { - return false; + if (string.IsNullOrWhiteSpace(_settings.S3AccessKeyId) || + string.IsNullOrWhiteSpace(_settings.S3SecretAccessKey) || + string.IsNullOrWhiteSpace(_settings.S3BucketName)) + { + buttonS3Settings.BackColor = Color.PaleVioletRed; + return false; + } + buttonS3Settings.BackColor = Color.White; + return true; + } + + if (checkBoxArtworkUpload.Checked && comboBoxArtworkUploader.SelectedItem != null) + { + comboBoxArtworkUploader.BackColor = Color.White; + + switch (comboBoxArtworkUploader.SelectedItem.ToString()) + { + case "Imgur": + if (textBoxImgurClientId.Text.Length > 0 && !validateImgurClientId()) + { + return false; + } + break; + case "Amazon S3": + if (!validateS3()) + { + return false; + } + break; + default: + comboBoxArtworkUploader.BackColor = Color.PaleVioletRed; + return false; + } } bool validateUri() @@ -199,6 +235,7 @@ private void ResetErrorIndications() { textBoxDiscordAppId.BackColor = SystemColors.Window; textBoxImgurClientId.BackColor = SystemColors.Window; + buttonS3Settings.BackColor = SystemColors.Window; customButtonUrl.BackColor = Color.FromArgb(114, 137, 218); } @@ -221,5 +258,29 @@ private void textBoxImgurClientId_TextChanged(object sender, EventArgs e) { ValidateInputs(); } + + private void comboBoxArtworkUploader_SelectedIndexChanged(object sender, EventArgs e) + { + ValidateInputs(); + + if (comboBoxArtworkUploader.SelectedIndex == comboBoxArtworkUploader.FindString("Amazon S3")) + { + labelImgurClientId.Visible = false; + textBoxImgurClientId.Visible = false; + buttonS3Settings.Visible = true; + } + else + { + labelImgurClientId.Visible = true; + textBoxImgurClientId.Visible = true; + buttonS3Settings.Visible = false; + } + } + + private void buttonS3Settings_Click(object sender, EventArgs e) + { + var s3SettingsWindow = new S3SettingsWindow(_settings); + s3SettingsWindow.ShowDialog(this); + } } } From cdd36fd448e18c02621f41ffec22eb6baf974796 Mon Sep 17 00:00:00 2001 From: suflors Date: Wed, 28 Aug 2024 04:05:19 -0700 Subject: [PATCH 2/6] Added additional logic in GetBaseUrl() as what was present did not work for me. --- S3Client/S3Client.cs | 20 +++++++++++++++++--- UI/SettingsWindow.cs | 15 ++++++--------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/S3Client/S3Client.cs b/S3Client/S3Client.cs index 3afcee5..d58f5d1 100644 --- a/S3Client/S3Client.cs +++ b/S3Client/S3Client.cs @@ -77,8 +77,7 @@ public async Task UploadImage(string hash, string dataB64) Key = key, Link = $"{GetBaseUrl()}/{key}", }; - } - else + } else { return null; } @@ -112,7 +111,22 @@ public void Dispose() private string GetBaseUrl() { - return _config.CustomDomain ?? _config.Endpoint; + string url = _config.CustomDomain ?? _config.Endpoint; + + // I was considering removing the url setting above entirely, as it doesn't seem to work. But it may just be my problem, so if it fails, continue to setting it through getting the bucket + if (string.IsNullOrEmpty(url)) + { + // Fetch the bucket region + var regionResponse = _client.GetBucketLocationAsync(new GetBucketLocationRequest + { + BucketName = _config.BucketName + }).GetAwaiter().GetResult(); + + var region = regionResponse.Location?.Value ?? "us-east-1"; // Default to us-east-1 if region is null + url = $"https://{_config.BucketName}.s3.{region}.amazonaws.com"; + } + + return url; } } } diff --git a/UI/SettingsWindow.cs b/UI/SettingsWindow.cs index 1c0c564..dfde960 100644 --- a/UI/SettingsWindow.cs +++ b/UI/SettingsWindow.cs @@ -1,9 +1,7 @@ namespace MusicBeePlugin.UI { using System; - using System.Collections.Generic; using System.Drawing; - using System.Linq; using System.Windows.Forms; public partial class SettingsWindow : Form @@ -263,17 +261,16 @@ private void comboBoxArtworkUploader_SelectedIndexChanged(object sender, EventAr { ValidateInputs(); - if (comboBoxArtworkUploader.SelectedIndex == comboBoxArtworkUploader.FindString("Amazon S3")) - { - labelImgurClientId.Visible = false; - textBoxImgurClientId.Visible = false; - buttonS3Settings.Visible = true; - } - else + if (comboBoxArtworkUploader.SelectedIndex == comboBoxArtworkUploader.FindString("Imgur")) { labelImgurClientId.Visible = true; textBoxImgurClientId.Visible = true; buttonS3Settings.Visible = false; + } else if (comboBoxArtworkUploader.SelectedIndex == comboBoxArtworkUploader.FindString("Amazon S3")) + { + labelImgurClientId.Visible = false; + textBoxImgurClientId.Visible = false; + buttonS3Settings.Visible = true; } } From cdc356978ec82a41f408529d00d17a847ea077ff Mon Sep 17 00:00:00 2001 From: suflors Date: Thu, 29 Aug 2024 02:57:10 -0700 Subject: [PATCH 3/6] nitpick: C# style guide, } should be on its own line Co-authored-by: Kramer Campbell --- UI/SettingsWindow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UI/SettingsWindow.cs b/UI/SettingsWindow.cs index dfde960..8e4b5e4 100644 --- a/UI/SettingsWindow.cs +++ b/UI/SettingsWindow.cs @@ -266,7 +266,8 @@ private void comboBoxArtworkUploader_SelectedIndexChanged(object sender, EventAr labelImgurClientId.Visible = true; textBoxImgurClientId.Visible = true; buttonS3Settings.Visible = false; - } else if (comboBoxArtworkUploader.SelectedIndex == comboBoxArtworkUploader.FindString("Amazon S3")) + } + else if (comboBoxArtworkUploader.SelectedIndex == comboBoxArtworkUploader.FindString("Amazon S3")) { labelImgurClientId.Visible = false; textBoxImgurClientId.Visible = false; From e948de00d05ca9440007efac864522a377de8906 Mon Sep 17 00:00:00 2001 From: suflors Date: Thu, 29 Aug 2024 17:05:23 -0700 Subject: [PATCH 4/6] Add S3Endpoint to validateS3(). Co-authored-by: Kramer Campbell --- UI/SettingsWindow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UI/SettingsWindow.cs b/UI/SettingsWindow.cs index 8e4b5e4..2ed1131 100644 --- a/UI/SettingsWindow.cs +++ b/UI/SettingsWindow.cs @@ -174,7 +174,8 @@ bool validateS3() { if (string.IsNullOrWhiteSpace(_settings.S3AccessKeyId) || string.IsNullOrWhiteSpace(_settings.S3SecretAccessKey) || - string.IsNullOrWhiteSpace(_settings.S3BucketName)) + string.IsNullOrWhiteSpace(_settings.S3BucketName) || + string.IsNullOrWhiteSpace(_settings.S3Endpoint)) { buttonS3Settings.BackColor = Color.PaleVioletRed; return false; From ef7e1bdda533920deb8c584fb8bbde3001c83350 Mon Sep 17 00:00:00 2001 From: suflors Date: Thu, 29 Aug 2024 18:37:05 -0700 Subject: [PATCH 5/6] Update GetBaseUrl() Co-authored-by: Kramer Campbell --- S3Client/S3Client.cs | 29 +++++++++++++++-------------- Settings.cs | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/S3Client/S3Client.cs b/S3Client/S3Client.cs index d58f5d1..a3480a5 100644 --- a/S3Client/S3Client.cs +++ b/S3Client/S3Client.cs @@ -36,7 +36,7 @@ public async Task GetAlbumImages() return response.S3Objects.Select(obj => new S3Image { Key = obj.Key, - Link = $"{GetBaseUrl()}/{obj.Key}", + Link = $"{GetBaseUrl()}{obj.Key}", }).ToArray(); } @@ -75,7 +75,7 @@ public async Task UploadImage(string hash, string dataB64) return new S3Image { Key = key, - Link = $"{GetBaseUrl()}/{key}", + Link = $"{GetBaseUrl()}{key}", }; } else { @@ -111,22 +111,23 @@ public void Dispose() private string GetBaseUrl() { - string url = _config.CustomDomain ?? _config.Endpoint; + if (!string.IsNullOrEmpty(_config.CustomDomain)) + { + return _config.CustomDomain; + } - // I was considering removing the url setting above entirely, as it doesn't seem to work. But it may just be my problem, so if it fails, continue to setting it through getting the bucket - if (string.IsNullOrEmpty(url)) + // Fetch the bucket region + var regionResponse = _client.GetBucketLocationAsync(new GetBucketLocationRequest { - // Fetch the bucket region - var regionResponse = _client.GetBucketLocationAsync(new GetBucketLocationRequest - { - BucketName = _config.BucketName - }).GetAwaiter().GetResult(); + BucketName = _config.BucketName + }).GetAwaiter().GetResult(); - var region = regionResponse.Location?.Value ?? "us-east-1"; // Default to us-east-1 if region is null - url = $"https://{_config.BucketName}.s3.{region}.amazonaws.com"; - } + var region = regionResponse.Location?.Value ?? "us-east-1"; // Default to us-east-1 if region is null - return url; + // Prefix the bucket name to the endpoint's host + var endpoint = new UriBuilder(_config.Endpoint); + endpoint.Host = $"{_config.BucketName}.{endpoint.Host}"; + return endpoint.Uri.ToString(); } } } diff --git a/Settings.cs b/Settings.cs index 59e0340..580653a 100644 --- a/Settings.cs +++ b/Settings.cs @@ -30,7 +30,7 @@ public class Settings {"ArtworkUploader", "Imgur"}, {"S3AccessKeyId", ""}, {"S3SecretAccessKey", ""}, - {"S3Endpoint", "s3.amazonaws.com"}, + {"S3Endpoint", "s3.us-east-1.com"}, {"S3BucketName", ""}, {"S3Prefix", "DiscordBee"}, {"S3CustomDomain", ""}, From dd877e3f93e0cb215b61d715363cfdfbf257ddd9 Mon Sep 17 00:00:00 2001 From: suflors Date: Thu, 29 Aug 2024 19:00:09 -0700 Subject: [PATCH 6/6] Added private _baseUrl to the constructor for S3Client, updated UpdateUrlPreview() to show a proper example. --- S3Client/S3Client.cs | 6 ++++-- UI/S3SettingsWindow.cs | 9 ++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/S3Client/S3Client.cs b/S3Client/S3Client.cs index a3480a5..02f3a42 100644 --- a/S3Client/S3Client.cs +++ b/S3Client/S3Client.cs @@ -13,6 +13,7 @@ public class S3Client : IDisposable { private readonly S3Config _config; private readonly AmazonS3Client _client; + private readonly string _baseUrl; public S3Client(S3Config config) { @@ -22,6 +23,7 @@ public S3Client(S3Config config) ServiceURL = config.Endpoint, }; _client = new AmazonS3Client(config.AccessKeyId, config.SecretAccessKey, clientConfig); + _baseUrl = GetBaseUrl(); } public async Task GetAlbumImages() @@ -36,7 +38,7 @@ public async Task GetAlbumImages() return response.S3Objects.Select(obj => new S3Image { Key = obj.Key, - Link = $"{GetBaseUrl()}{obj.Key}", + Link = $"{_baseUrl}{obj.Key}", }).ToArray(); } @@ -75,7 +77,7 @@ public async Task UploadImage(string hash, string dataB64) return new S3Image { Key = key, - Link = $"{GetBaseUrl()}{key}", + Link = $"{_baseUrl}{key}", }; } else { diff --git a/UI/S3SettingsWindow.cs b/UI/S3SettingsWindow.cs index af6f13b..e698036 100644 --- a/UI/S3SettingsWindow.cs +++ b/UI/S3SettingsWindow.cs @@ -64,7 +64,7 @@ private void UpdateUrlPreview() customDomain = customDomain.Replace($"{Uri.UriSchemeHttp}://", "").Replace($"{Uri.UriSchemeHttps}://", ""); var scheme = $"{(insecure ? Uri.UriSchemeHttp : Uri.UriSchemeHttps)}://"; - var baseUrl = string.IsNullOrWhiteSpace(textBoxS3CustomDomain.Text) ? $"{endpoint}/{textBoxS3BucketName.Text}" : customDomain; + var baseUrl = string.IsNullOrWhiteSpace(textBoxS3CustomDomain.Text) ? $"{textBoxS3BucketName.Text}.{endpoint}" : customDomain; var prefix = string.IsNullOrWhiteSpace(textBoxS3Prefix.Text) ? "" : $"{textBoxS3Prefix.Text}/"; textBoxUrlPreview.Text = $"{scheme}{baseUrl}/{prefix}example"; } @@ -184,7 +184,7 @@ bool validateCustomDomain() ResetErrorIndications(); - return true; + return true; } private void ResetErrorIndications() @@ -249,8 +249,7 @@ private async void buttonTest_Click(object sender, EventArgs e) if (await s3Client.TestConnection()) { MessageBox.Show("Connection successfully established to S3 bucket.", "Test Connection Result", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - else + } else { MessageBox.Show("A connection could not be successfully made to the S3 bucket. Please check your credentials and configuration and try again.", "Test Connection Result", MessageBoxButtons.OK, MessageBoxIcon.Error); } @@ -273,7 +272,7 @@ private void buttonSaveClose_Click(object sender, EventArgs e) _settings.S3Prefix = textBoxS3Prefix.Text; _settings.S3CustomDomain = textBoxS3CustomDomain.Text; - ((SettingsWindow) Owner).ValidateInputs(); + ((SettingsWindow)Owner).ValidateInputs(); Close(); } }