diff --git a/Configuration/SystemConfig.cs b/Configuration/SystemConfig.cs index 811b2856..cd289b4e 100644 --- a/Configuration/SystemConfig.cs +++ b/Configuration/SystemConfig.cs @@ -15,6 +15,9 @@ sealed class SystemConfig{ private bool _hardwareAcceleration = true; + public bool ClearCacheAutomatically { get; set; } = true; + public int ClearCacheThreshold { get; set; } = 250; + // SPECIAL PROPERTIES public bool HardwareAcceleration{ diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs index 44fb6500..774162bf 100644 --- a/Core/FormBrowser.cs +++ b/Core/FormBrowser.cs @@ -419,6 +419,8 @@ public void OpenSettings(Type startTab){ analytics.Dispose(); analytics = null; } + + BrowserCache.RefreshTimer(); if (form.ShouldReloadBrowser){ FormManager.TryFind<FormPlugins>()?.Close(); diff --git a/Core/Other/Settings/TabSettingsAdvanced.Designer.cs b/Core/Other/Settings/TabSettingsAdvanced.Designer.cs index c3d45f32..d2abcde8 100644 --- a/Core/Other/Settings/TabSettingsAdvanced.Designer.cs +++ b/Core/Other/Settings/TabSettingsAdvanced.Designer.cs @@ -33,12 +33,16 @@ private void InitializeComponent() { this.btnRestart = new System.Windows.Forms.Button(); this.btnOpenAppFolder = new System.Windows.Forms.Button(); this.btnOpenDataFolder = new System.Windows.Forms.Button(); + this.numClearCacheThreshold = new TweetDuck.Core.Controls.NumericUpDownEx(); + this.checkClearCacheAuto = new System.Windows.Forms.CheckBox(); this.labelApp = new System.Windows.Forms.Label(); this.panelApp = new System.Windows.Forms.Panel(); this.labelPerformance = new System.Windows.Forms.Label(); this.panelPerformance = new System.Windows.Forms.Panel(); + this.labelCache = new System.Windows.Forms.Label(); this.panelConfiguration = new System.Windows.Forms.Panel(); this.labelConfiguration = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.numClearCacheThreshold)).BeginInit(); this.panelApp.SuspendLayout(); this.panelPerformance.SuspendLayout(); this.panelConfiguration.SuspendLayout(); @@ -46,7 +50,7 @@ private void InitializeComponent() { // // btnClearCache // - this.btnClearCache.Location = new System.Drawing.Point(5, 28); + this.btnClearCache.Location = new System.Drawing.Point(5, 53); this.btnClearCache.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3); this.btnClearCache.Name = "btnClearCache"; this.btnClearCache.Size = new System.Drawing.Size(144, 23); @@ -130,6 +134,30 @@ private void InitializeComponent() { this.toolTip.SetToolTip(this.btnOpenDataFolder, "Opens the folder where your profile data is located."); this.btnOpenDataFolder.UseVisualStyleBackColor = true; // + // numClearCacheThreshold + // + this.numClearCacheThreshold.Increment = 50; + this.numClearCacheThreshold.Location = new System.Drawing.Point(227, 82); + this.numClearCacheThreshold.Maximum = 1000; + this.numClearCacheThreshold.Minimum = 100; + this.numClearCacheThreshold.Name = "numClearCacheThreshold"; + this.numClearCacheThreshold.Size = new System.Drawing.Size(72, 20); + this.numClearCacheThreshold.TabIndex = 4; + this.numClearCacheThreshold.TextSuffix = " MB"; + this.numClearCacheThreshold.Value = 250; + // + // checkClearCacheAuto + // + this.checkClearCacheAuto.AutoSize = true; + this.checkClearCacheAuto.Location = new System.Drawing.Point(6, 84); + this.checkClearCacheAuto.Margin = new System.Windows.Forms.Padding(6, 5, 3, 3); + this.checkClearCacheAuto.Name = "checkClearCacheAuto"; + this.checkClearCacheAuto.Size = new System.Drawing.Size(215, 17); + this.checkClearCacheAuto.TabIndex = 3; + this.checkClearCacheAuto.Text = "Clear Cache Automatically When Above"; + this.toolTip.SetToolTip(this.checkClearCacheAuto, "Automatically clears cache when its size exceeds the set threshold. Note that cache can only be cleared when closing TweetDuck."); + this.checkClearCacheAuto.UseVisualStyleBackColor = true; + // // labelApp // this.labelApp.AutoSize = true; @@ -169,20 +197,33 @@ private void InitializeComponent() { // this.panelPerformance.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.panelPerformance.Controls.Add(this.checkClearCacheAuto); + this.panelPerformance.Controls.Add(this.numClearCacheThreshold); + this.panelPerformance.Controls.Add(this.labelCache); this.panelPerformance.Controls.Add(this.checkHardwareAcceleration); this.panelPerformance.Controls.Add(this.btnClearCache); this.panelPerformance.Location = new System.Drawing.Point(9, 137); this.panelPerformance.Name = "panelPerformance"; - this.panelPerformance.Size = new System.Drawing.Size(322, 58); + this.panelPerformance.Size = new System.Drawing.Size(322, 105); this.panelPerformance.TabIndex = 3; // + // labelCache + // + this.labelCache.AutoSize = true; + this.labelCache.Location = new System.Drawing.Point(3, 37); + this.labelCache.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0); + this.labelCache.Name = "labelCache"; + this.labelCache.Size = new System.Drawing.Size(38, 13); + this.labelCache.TabIndex = 2; + this.labelCache.Text = "Cache"; + // // panelConfiguration // this.panelConfiguration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.panelConfiguration.Controls.Add(this.btnEditCSS); this.panelConfiguration.Controls.Add(this.btnEditCefArgs); - this.panelConfiguration.Location = new System.Drawing.Point(9, 242); + this.panelConfiguration.Location = new System.Drawing.Point(9, 289); this.panelConfiguration.Name = "panelConfiguration"; this.panelConfiguration.Size = new System.Drawing.Size(322, 29); this.panelConfiguration.TabIndex = 5; @@ -191,7 +232,7 @@ private void InitializeComponent() { // this.labelConfiguration.AutoSize = true; this.labelConfiguration.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238))); - this.labelConfiguration.Location = new System.Drawing.Point(6, 219); + this.labelConfiguration.Location = new System.Drawing.Point(6, 266); this.labelConfiguration.Margin = new System.Windows.Forms.Padding(0, 21, 0, 0); this.labelConfiguration.Name = "labelConfiguration"; this.labelConfiguration.Size = new System.Drawing.Size(104, 20); @@ -209,7 +250,8 @@ private void InitializeComponent() { this.Controls.Add(this.panelApp); this.Controls.Add(this.labelApp); this.Name = "TabSettingsAdvanced"; - this.Size = new System.Drawing.Size(340, 282); + this.Size = new System.Drawing.Size(340, 328); + ((System.ComponentModel.ISupportInitialize)(this.numClearCacheThreshold)).EndInit(); this.panelApp.ResumeLayout(false); this.panelPerformance.ResumeLayout(false); this.panelPerformance.PerformLayout(); @@ -236,5 +278,8 @@ private void InitializeComponent() { private System.Windows.Forms.Panel panelPerformance; private System.Windows.Forms.Panel panelConfiguration; private System.Windows.Forms.Label labelConfiguration; + private System.Windows.Forms.Label labelCache; + private Controls.NumericUpDownEx numClearCacheThreshold; + private System.Windows.Forms.CheckBox checkClearCacheAuto; } } diff --git a/Core/Other/Settings/TabSettingsAdvanced.cs b/Core/Other/Settings/TabSettingsAdvanced.cs index 1e1e9d3b..150439af 100644 --- a/Core/Other/Settings/TabSettingsAdvanced.cs +++ b/Core/Other/Settings/TabSettingsAdvanced.cs @@ -25,16 +25,22 @@ public TabSettingsAdvanced(Action<string> reinjectBrowserCSS){ checkHardwareAcceleration.Enabled = false; checkHardwareAcceleration.Checked = false; } + + checkClearCacheAuto.Checked = SysConfig.ClearCacheAutomatically; + numClearCacheThreshold.Enabled = checkClearCacheAuto.Checked; + numClearCacheThreshold.SetValueSafe(SysConfig.ClearCacheThreshold); - BrowserCache.CalculateCacheSize(task => { + BrowserCache.GetCacheSize(task => { string text = task.Status == TaskStatus.RanToCompletion ? (int)Math.Ceiling(task.Result/(1024.0*1024.0))+" MB" : "unknown"; this.InvokeSafe(() => btnClearCache.Text = $"Clear Cache ({text})"); }); } public override void OnReady(){ - btnClearCache.Click += btnClearCache_Click; checkHardwareAcceleration.CheckedChanged += checkHardwareAcceleration_CheckedChanged; + + btnClearCache.Click += btnClearCache_Click; + checkClearCacheAuto.CheckedChanged += checkClearCacheAuto_CheckedChanged; btnEditCefArgs.Click += btnEditCefArgs_Click; btnEditCSS.Click += btnEditCSS_Click; @@ -46,6 +52,8 @@ public override void OnReady(){ } public override void OnClosing(){ + SysConfig.ClearCacheAutomatically = checkClearCacheAuto.Checked; + SysConfig.ClearCacheThreshold = (int)numClearCacheThreshold.Value; SysConfig.Save(); } @@ -55,6 +63,10 @@ private void btnClearCache_Click(object sender, EventArgs e){ FormMessage.Information("Clear Cache", "Cache will be automatically cleared when TweetDuck exits.", FormMessage.OK); } + private void checkClearCacheAuto_CheckedChanged(object sender, EventArgs e){ + numClearCacheThreshold.Enabled = checkClearCacheAuto.Checked; + } + private void checkHardwareAcceleration_CheckedChanged(object sender, EventArgs e){ SysConfig.HardwareAcceleration = checkHardwareAcceleration.Checked; PromptRestart(); // calls OnClosing diff --git a/Core/Utils/BrowserCache.cs b/Core/Utils/BrowserCache.cs index 070b64d5..927befe3 100644 --- a/Core/Utils/BrowserCache.cs +++ b/Core/Utils/BrowserCache.cs @@ -1,36 +1,59 @@ using System; -using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using System.Linq; +using System.Threading; namespace TweetDuck.Core.Utils{ static class BrowserCache{ - private static bool ClearOnExit { get; set; } - public static readonly string CacheFolder = Path.Combine(Program.StoragePath, "Cache"); - private static IEnumerable<FileInfo> CacheFiles => new DirectoryInfo(CacheFolder).EnumerateFiles(); + + private static bool ClearOnExit; + private static Timer AutoClearTimer; - public static void CalculateCacheSize(Action<Task<long>> callbackBytes){ - Task<long> task = new Task<long>(() => { - return CacheFiles.Select(file => { - try{ - return file.Length; - }catch{ - return 0L; - } - }).Sum(); - }); - + private static long CalculateCacheSize(){ + return new DirectoryInfo(CacheFolder).EnumerateFiles().Select(file => { + try{ + return file.Length; + }catch{ + return 0L; + } + }).Sum(); + } + + public static void GetCacheSize(Action<Task<long>> callbackBytes){ + Task<long> task = new Task<long>(CalculateCacheSize); task.ContinueWith(callbackBytes); task.Start(); } + + public static void RefreshTimer(){ + bool shouldRun = Program.SystemConfig.ClearCacheAutomatically && !ClearOnExit; + + if (!shouldRun && AutoClearTimer != null){ + AutoClearTimer.Dispose(); + AutoClearTimer = null; + } + else if (shouldRun && AutoClearTimer == null){ + AutoClearTimer = new Timer(state => { + if (AutoClearTimer != null && CalculateCacheSize() >= Program.SystemConfig.ClearCacheThreshold*1024L*1024L){ + SetClearOnExit(); + } + }, null, TimeSpan.FromSeconds(30), TimeSpan.FromHours(4)); + } + } public static void SetClearOnExit(){ ClearOnExit = true; + RefreshTimer(); } public static void Exit(){ + if (AutoClearTimer != null){ + AutoClearTimer.Dispose(); + AutoClearTimer = null; + } + if (ClearOnExit){ try{ Directory.Delete(CacheFolder, true); diff --git a/Program.cs b/Program.cs index 47f5e6c8..1e84af49 100644 --- a/Program.cs +++ b/Program.cs @@ -127,6 +127,7 @@ private static void Main(){ WindowsUtils.TryDeleteFolderWhenAble(InstallerPath, 8000); } + BrowserCache.RefreshTimer(); CefSharpSettings.WcfEnabled = false; CefSettings settings = new CefSettings{