mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-05-06 05:34:05 +02:00
Update and add analytics data points & increase report interval to 14 days
This commit is contained in:
parent
cb9f75e968
commit
50e39164bd
@ -16,7 +16,7 @@
|
||||
using TweetDuck.Updates;
|
||||
|
||||
namespace TweetDuck.Core{
|
||||
sealed partial class FormBrowser : Form{
|
||||
sealed partial class FormBrowser : Form, AnalyticsFile.IProvider{
|
||||
private static UserConfig Config => Program.UserConfig;
|
||||
|
||||
public bool IsWaiting{
|
||||
@ -219,7 +219,7 @@ private void plugins_Reloaded(object sender, PluginErrorEventArgs e){
|
||||
}
|
||||
|
||||
if (isLoaded){
|
||||
ReloadToTweetDeck();
|
||||
browser.ReloadToTweetDeck();
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,6 +295,7 @@ public void ReinjectCustomCSS(string css){
|
||||
|
||||
public void ReloadToTweetDeck(){
|
||||
browser.ReloadToTweetDeck();
|
||||
AnalyticsFile.CountBrowserReloads.Trigger();
|
||||
}
|
||||
|
||||
public void TriggerTweetScreenshot(){
|
||||
@ -311,6 +312,7 @@ public void PlaySoundNotification(){
|
||||
|
||||
public void ApplyROT13(){
|
||||
browser.ApplyROT13();
|
||||
AnalyticsFile.CountUsedROT13.Trigger();
|
||||
}
|
||||
|
||||
// callback handlers
|
||||
|
@ -11,6 +11,7 @@
|
||||
using TweetDuck.Core.Management;
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Other;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
abstract class ContextMenuBase : IContextMenuHandler{
|
||||
@ -44,6 +45,12 @@ private static string GetMediaLink(IContextMenuParams parameters){
|
||||
private string[] lastHighlightedTweetAuthors;
|
||||
private string[] lastHighlightedTweetImageList;
|
||||
|
||||
private readonly AnalyticsFile.IProvider analytics;
|
||||
|
||||
protected ContextMenuBase(AnalyticsFile.IProvider analytics){
|
||||
this.analytics = analytics;
|
||||
}
|
||||
|
||||
public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
if (!TwitterUtils.IsTweetDeckWebsite(frame) || browser.IsLoading){
|
||||
lastHighlightedTweetAuthors = StringUtils.EmptyArray;
|
||||
@ -97,26 +104,29 @@ public virtual void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser bro
|
||||
}
|
||||
|
||||
public virtual bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags){
|
||||
Control control = browserControl.AsControl();
|
||||
|
||||
switch(commandId){
|
||||
case MenuOpenLinkUrl:
|
||||
OpenBrowser(browserControl.AsControl(), IsLink ? ContextInfo.Value : parameters.LinkUrl);
|
||||
OpenBrowser(control, IsLink ? ContextInfo.Value : parameters.LinkUrl);
|
||||
break;
|
||||
|
||||
case MenuCopyLinkUrl:
|
||||
SetClipboardText(browserControl.AsControl(), IsLink ? ContextInfo.Value : parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(control, IsLink ? ContextInfo.Value : parameters.UnfilteredLinkUrl);
|
||||
break;
|
||||
|
||||
case MenuCopyUsername:
|
||||
Match match = TwitterUtils.RegexAccount.Match(parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(browserControl.AsControl(), match.Success ? match.Groups[1].Value : parameters.UnfilteredLinkUrl);
|
||||
SetClipboardText(control, match.Success ? match.Groups[1].Value : parameters.UnfilteredLinkUrl);
|
||||
control.InvokeAsyncSafe(analytics.AnalyticsFile.CountCopiedUsernames.Trigger);
|
||||
break;
|
||||
|
||||
case MenuOpenMediaUrl:
|
||||
OpenBrowser(browserControl.AsControl(), TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality));
|
||||
OpenBrowser(control, TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuCopyMediaUrl:
|
||||
SetClipboardText(browserControl.AsControl(), TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality));
|
||||
SetClipboardText(control, TwitterUtils.GetMediaLink(GetMediaLink(parameters), ImageQuality));
|
||||
break;
|
||||
|
||||
case MenuViewImage:
|
||||
@ -138,6 +148,8 @@ void ViewFile(){
|
||||
ViewFile();
|
||||
}
|
||||
else{
|
||||
control.InvokeAsyncSafe(analytics.AnalyticsFile.CountViewedImages.Trigger);
|
||||
|
||||
BrowserUtils.DownloadFileAsync(TwitterUtils.GetMediaLink(url, ImageQuality), file, ViewFile, ex => {
|
||||
FormMessage.Error("Image Download", "An error occurred while downloading the image: "+ex.Message, FormMessage.OK);
|
||||
});
|
||||
@ -147,15 +159,18 @@ void ViewFile(){
|
||||
|
||||
case MenuSaveMedia:
|
||||
if (IsVideo){
|
||||
control.InvokeAsyncSafe(analytics.AnalyticsFile.CountDownloadedVideos.Trigger);
|
||||
TwitterUtils.DownloadVideo(GetMediaLink(parameters), lastHighlightedTweetAuthors.LastOrDefault());
|
||||
}
|
||||
else{
|
||||
control.InvokeAsyncSafe(analytics.AnalyticsFile.CountDownloadedImages.Trigger);
|
||||
TwitterUtils.DownloadImage(GetMediaLink(parameters), lastHighlightedTweetAuthors.LastOrDefault(), ImageQuality);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MenuSaveTweetImages:
|
||||
control.InvokeAsyncSafe(analytics.AnalyticsFile.CountDownloadedImages.Trigger);
|
||||
TwitterUtils.DownloadImages(lastHighlightedTweetImageList, lastHighlightedTweetAuthors.LastOrDefault(), ImageQuality);
|
||||
break;
|
||||
|
||||
|
@ -30,7 +30,7 @@ sealed class ContextMenuBrowser : ContextMenuBase{
|
||||
private string lastHighlightedTweetUrl;
|
||||
private string lastHighlightedQuoteUrl;
|
||||
|
||||
public ContextMenuBrowser(FormBrowser form){
|
||||
public ContextMenuBrowser(FormBrowser form) : base(form){
|
||||
this.form = form;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
using CefSharp;
|
||||
using TweetDuck.Core.Other.Analytics;
|
||||
|
||||
namespace TweetDuck.Core.Handling{
|
||||
sealed class ContextMenuGuide : ContextMenuBase{
|
||||
public ContextMenuGuide(AnalyticsFile.IProvider analytics) : base(analytics){}
|
||||
|
||||
public override void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model){
|
||||
model.Clear();
|
||||
base.OnBeforeContextMenu(browserControl, browser, frame, parameters, model);
|
||||
|
@ -13,7 +13,7 @@ sealed class ContextMenuNotification : ContextMenuBase{
|
||||
private readonly FormNotificationBase form;
|
||||
private readonly bool enableCustomMenu;
|
||||
|
||||
public ContextMenuNotification(FormNotificationBase form, bool enableCustomMenu){
|
||||
public ContextMenuNotification(FormNotificationBase form, bool enableCustomMenu) : base(form){
|
||||
this.form = form;
|
||||
this.enableCustomMenu = enableCustomMenu;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public bool Running{
|
||||
|
||||
public event EventHandler ProcessExited;
|
||||
|
||||
private readonly Form owner;
|
||||
private readonly FormBrowser owner;
|
||||
private string lastUrl;
|
||||
private string lastUsername;
|
||||
|
||||
@ -30,7 +30,7 @@ public bool Running{
|
||||
private DuplexPipe.Server currentPipe;
|
||||
private bool isClosing;
|
||||
|
||||
public VideoPlayer(Form owner){
|
||||
public VideoPlayer(FormBrowser owner){
|
||||
this.owner = owner;
|
||||
this.owner.FormClosing += owner_FormClosing;
|
||||
}
|
||||
@ -83,6 +83,7 @@ private void currentPipe_DataIn(object sender, DuplexPipe.PipeReadEventArgs e){
|
||||
break;
|
||||
|
||||
case "download":
|
||||
owner.AnalyticsFile.CountDownloadedVideos.Trigger();
|
||||
TwitterUtils.DownloadVideo(lastUrl, lastUsername);
|
||||
break;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
using TweetDuck.Core.Utils;
|
||||
|
||||
namespace TweetDuck.Core.Notification{
|
||||
partial class FormNotificationBase : Form{
|
||||
partial class FormNotificationBase : Form, AnalyticsFile.IProvider{
|
||||
protected static int FontSizeLevel{
|
||||
get{
|
||||
switch(TweetDeckBridge.FontSize){
|
||||
|
@ -46,6 +46,12 @@ static AnalyticsFile(){
|
||||
public Counter CountNotificationExtraMouseButtons { get; private set; } = 0;
|
||||
public Counter CountNotificationKeyboardShortcuts { get; private set; } = 0;
|
||||
|
||||
public Counter CountBrowserReloads { get; private set; } = 0;
|
||||
public Counter CountCopiedUsernames { get; private set; } = 0;
|
||||
public Counter CountViewedImages { get; private set; } = 0;
|
||||
public Counter CountDownloadedImages { get; private set; } = 0;
|
||||
public Counter CountDownloadedVideos { get; private set; } = 0;
|
||||
public Counter CountUsedROT13 { get; private set; } = 0;
|
||||
|
||||
public Counter CountTweetScreenshots { get; private set; } = 0;
|
||||
public Counter CountTweetDetails { get; private set; } = 0;
|
||||
@ -96,6 +102,10 @@ public static AnalyticsFile Load(string file){
|
||||
return config;
|
||||
}
|
||||
|
||||
public interface IProvider{
|
||||
AnalyticsFile AnalyticsFile { get; }
|
||||
}
|
||||
|
||||
public sealed class Counter{
|
||||
public int Value { get; private set; }
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
namespace TweetDuck.Core.Other.Analytics{
|
||||
sealed class AnalyticsManager : IDisposable{
|
||||
private static readonly TimeSpan CollectionInterval = TimeSpan.FromDays(7);
|
||||
private static readonly TimeSpan CollectionInterval = TimeSpan.FromDays(14);
|
||||
private static readonly Uri CollectionUrl = new Uri("https://tweetduck.chylex.com/breadcrumb/report");
|
||||
|
||||
public AnalyticsFile File { get; }
|
||||
|
@ -12,6 +12,7 @@
|
||||
using TweetDuck.Core.Notification;
|
||||
using TweetDuck.Core.Utils;
|
||||
using TweetDuck.Plugins;
|
||||
using TweetDuck.Plugins.Enums;
|
||||
|
||||
namespace TweetDuck.Core.Other.Analytics{
|
||||
static class AnalyticsReportGenerator{
|
||||
@ -36,15 +37,24 @@ public static AnalyticsReport Create(AnalyticsFile file, ExternalInfo info, Plug
|
||||
{ "Screen Resolution" , info.Resolution ?? "(unknown)" },
|
||||
{ "Screen DPI" , info.DPI != null ? Exact(info.DPI.Value) : "(unknown)" },
|
||||
0,
|
||||
{ "Hardware Acceleration" , Bool(SysConfig.HardwareAcceleration) },
|
||||
{ "Hardware Acceleration" , Bool(SysConfig.HardwareAcceleration) },
|
||||
{ "Clear Cache Automatically" , Bool(SysConfig.ClearCacheAutomatically) },
|
||||
{ "Clear Cache Threshold" , Exact(SysConfig.ClearCacheThreshold) },
|
||||
0,
|
||||
{ "Expand Links" , Bool(UserConfig.ExpandLinksOnHover) },
|
||||
{ "Switch Account Selectors" , Bool(UserConfig.SwitchAccountSelectors) },
|
||||
{ "Search In First Column" , Bool(UserConfig.OpenSearchInFirstColumn) },
|
||||
{ "Keep Like Follow Dialogs Open" , Bool(UserConfig.KeepLikeFollowDialogsOpen) },
|
||||
{ "Best Image Quality" , Bool(UserConfig.BestImageQuality) },
|
||||
{ "Spell Check" , Bool(UserConfig.EnableSpellCheck) },
|
||||
{ "Zoom" , Exact(UserConfig.ZoomLevel) },
|
||||
{ "Animated Images" , Bool(UserConfig.EnableAnimatedImages) },
|
||||
0,
|
||||
{ "Smooth Scrolling" , Bool(UserConfig.EnableSmoothScrolling) },
|
||||
{ "Custom Browser" , CustomBrowser },
|
||||
{ "Zoom" , Exact(UserConfig.ZoomLevel) },
|
||||
0,
|
||||
{ "Spell Check" , Bool(UserConfig.EnableSpellCheck) },
|
||||
{ "Spell Check Language" , UserConfig.SpellCheckLanguage.ToLower() },
|
||||
{ "Translation Target Language" , UserConfig.TranslationTarget },
|
||||
0,
|
||||
{ "Updates" , Bool(UserConfig.EnableUpdateCheck) },
|
||||
{ "Update Dismissed" , Bool(!string.IsNullOrEmpty(UserConfig.DismissedUpdate)) },
|
||||
@ -70,8 +80,8 @@ public static AnalyticsReport Create(AnalyticsFile file, ExternalInfo info, Plug
|
||||
{ "Custom Browser CSS" , RoundUp((UserConfig.CustomBrowserCSS ?? string.Empty).Length, 50) },
|
||||
{ "Custom Notification CSS" , RoundUp((UserConfig.CustomNotificationCSS ?? string.Empty).Length, 50) },
|
||||
0,
|
||||
{ "Plugins All" , List(plugins.Plugins.Select(plugin => plugin.Identifier)) },
|
||||
{ "Plugins Enabled" , List(plugins.Plugins.Where(plugin => plugins.Config.IsEnabled(plugin)).Select(plugin => plugin.Identifier)) },
|
||||
{ "Plugins All" , List(plugins.Plugins.Select(Plugin)) },
|
||||
{ "Plugins Enabled" , List(plugins.Plugins.Where(plugin => plugins.Config.IsEnabled(plugin)).Select(Plugin)) },
|
||||
0,
|
||||
{ "Theme" , Dict(editLayoutDesign, "_theme", "light/def") },
|
||||
{ "Column Width" , Dict(editLayoutDesign, "columnWidth", "310px/def") },
|
||||
@ -99,6 +109,12 @@ public static AnalyticsReport Create(AnalyticsFile file, ExternalInfo info, Plug
|
||||
{ "Notification Context Menus" , LogRound(file.CountNotificationContextMenus, 2) },
|
||||
{ "Notification Extra Mouse Buttons" , LogRound(file.CountNotificationExtraMouseButtons, 2) },
|
||||
{ "Notification Keyboard Shortcuts" , LogRound(file.CountNotificationKeyboardShortcuts, 2) },
|
||||
{ "Browser Reloads" , LogRound(file.CountBrowserReloads, 2) },
|
||||
{ "Copied Usernames" , LogRound(file.CountCopiedUsernames, 2) },
|
||||
{ "Viewed Images" , LogRound(file.CountViewedImages, 2) },
|
||||
{ "Downloaded Images" , LogRound(file.CountDownloadedImages, 2) },
|
||||
{ "Downloaded Videos" , LogRound(file.CountDownloadedVideos, 2) },
|
||||
{ "Used ROT13" , LogRound(file.CountUsedROT13, 2) },
|
||||
{ "Tweet Screenshots" , LogRound(file.CountTweetScreenshots, 2) },
|
||||
{ "Tweet Details" , LogRound(file.CountTweetDetails, 2) },
|
||||
{ "Video Plays" , LogRound(file.CountVideoPlays, 4) }
|
||||
@ -112,6 +128,7 @@ public static AnalyticsReport Create(AnalyticsFile file, ExternalInfo info, Plug
|
||||
private static string Exact(int value) => value.ToString();
|
||||
private static string RoundUp(int value, int multiple) => (multiple*(int)Math.Ceiling((double)value/multiple)).ToString();
|
||||
private static string LogRound(int value, int logBase) => (value <= 0 ? 0 : (int)Math.Pow(logBase, Math.Floor(Math.Log(value, logBase)))).ToString();
|
||||
private static string Plugin(Plugin plugin) => plugin.Group.GetIdentifierPrefixShort()+plugin.Identifier.Substring(plugin.Group.GetIdentifierPrefix().Length);
|
||||
private static string Dict(Dictionary<string, string> dict, string key, string def = "(unknown)") => dict.TryGetValue(key, out string value) ? value : def;
|
||||
private static string List(IEnumerable<string> list) => string.Join("|", list.DefaultIfEmpty("(none)"));
|
||||
|
||||
@ -182,6 +199,12 @@ static AnalyticsReportGenerator(){
|
||||
ProgramArguments = args.Keys.Select(key => key.TrimStart('-')).ToArray();
|
||||
}
|
||||
|
||||
private static string CustomBrowser{
|
||||
get{
|
||||
return Path.GetFileName(UserConfig.BrowserPath) ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private static string TrayMode{
|
||||
get{
|
||||
switch(UserConfig.TrayBehavior){
|
||||
|
@ -54,7 +54,7 @@ public static void Show(string hash = null){
|
||||
|
||||
private readonly ChromiumWebBrowser browser;
|
||||
|
||||
private FormGuide(string url, Form owner){
|
||||
private FormGuide(string url, FormBrowser owner){
|
||||
InitializeComponent();
|
||||
|
||||
Text = Program.BrandName+" Guide";
|
||||
@ -65,7 +65,7 @@ private FormGuide(string url, Form owner){
|
||||
}
|
||||
|
||||
this.browser = new ChromiumWebBrowser(url){
|
||||
MenuHandler = new ContextMenuGuide(),
|
||||
MenuHandler = new ContextMenuGuide(owner),
|
||||
JsDialogHandler = new JavaScriptDialogHandler(),
|
||||
LifeSpanHandler = new LifeSpanHandler(),
|
||||
RequestHandler = new RequestHandlerBrowser()
|
||||
|
@ -11,5 +11,13 @@ public static string GetIdentifierPrefix(this PluginGroup group){
|
||||
default: return "unknown/";
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetIdentifierPrefixShort(this PluginGroup group){
|
||||
switch(group){
|
||||
case PluginGroup.Official: return "o/";
|
||||
case PluginGroup.Custom: return "c/";
|
||||
default: return "?/";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user