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

Compare commits

...

16 Commits

Author SHA1 Message Date
e50480aa35 Fix edit-design plugin modal labels changing margins with different themes 2018-01-16 22:55:21 +01:00
6943c7813f Fix hovering scrollbars not changing their color with edit-design plugin enabled 2018-01-16 22:54:53 +01:00
7c9b4382ca Fix Follow dialog closing when clicking any but the first Follow button 2018-01-16 19:20:14 +01:00
3187f97592 Rewrite 'Keep Like/Follow dialogs open' code after TD removed the old way 2018-01-15 21:25:43 +01:00
b71a367052 Merge pull request #196 from chylex/delet_audio_lib
Remove audio library
2018-01-14 11:13:31 +01:00
2d4bbf2a6f Fix sound notification extension detection and add warning to mp3 files 2018-01-14 00:08:43 +01:00
6e59dfddcc Remove audio library 2018-01-13 23:38:30 +01:00
bd92fc6ee0 Use <audio> for custom sound notifications & allow volume control for default one
Closes #195
2018-01-13 22:59:34 +01:00
2f61de7025 Add GetHandlerFactory extension method to BrowserUtils 2018-01-13 22:37:24 +01:00
8fcec7ec7c Merge remote-tracking branch 'refs/remotes/origin/master' into delet_audio_lib 2018-01-13 19:50:13 +01:00
33d9ba3871 Refactor UserConfig event invocations into a generic method 2018-01-13 19:49:16 +01:00
4f8c778ba0 Ignore errors in automatic cache clearing
Closes #194
2018-01-13 15:35:20 +01:00
804c739038 Fix broken element dragging (timeline tweets and maybe more) 2018-01-13 15:27:07 +01:00
a0445fbb12 Release 1.12.1.1 2018-01-12 12:48:14 +01:00
7ab5d7b796 Release 1.12.1 2018-01-12 12:40:09 +01:00
7f83a7773b Fix 'Show this thread' not working >_> 2018-01-12 12:39:46 +01:00
27 changed files with 244 additions and 455 deletions

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using TweetDuck.Core.Controls; using TweetDuck.Core.Controls;
@@ -82,8 +83,8 @@ namespace TweetDuck.Configuration{
public Size CustomNotificationSize { get; set; } = Size.Empty; public Size CustomNotificationSize { get; set; } = Size.Empty;
public int NotificationScrollSpeed { get; set; } = 100; public int NotificationScrollSpeed { get; set; } = 100;
public int NotificationSoundVolume { get; set; } = 100;
private string _notificationSoundPath; private string _notificationSoundPath;
private int _notificationSoundVolume = 100;
public string CustomCefArgs { get; set; } = null; public string CustomCefArgs { get; set; } = null;
public string CustomBrowserCSS { get; set; } = null; public string CustomBrowserCSS { get; set; } = null;
@@ -93,45 +94,33 @@ namespace TweetDuck.Configuration{
public bool IsCustomNotificationPositionSet => CustomNotificationPosition != ControlExtensions.InvisibleLocation; public bool IsCustomNotificationPositionSet => CustomNotificationPosition != ControlExtensions.InvisibleLocation;
public bool IsCustomNotificationSizeSet => CustomNotificationSize != Size.Empty; public bool IsCustomNotificationSizeSet => CustomNotificationSize != Size.Empty;
public bool IsCustomSoundNotificationSet => NotificationSoundPath != string.Empty;
public TwitterUtils.ImageQuality TwitterImageQuality => BestImageQuality ? TwitterUtils.ImageQuality.Orig : TwitterUtils.ImageQuality.Default; public TwitterUtils.ImageQuality TwitterImageQuality => BestImageQuality ? TwitterUtils.ImageQuality.Orig : TwitterUtils.ImageQuality.Default;
public string NotificationSoundPath{ public string NotificationSoundPath{
get => string.IsNullOrEmpty(_notificationSoundPath) ? string.Empty : _notificationSoundPath; get => _notificationSoundPath ?? string.Empty;
set => _notificationSoundPath = value; set => UpdatePropertyWithEvent(ref _notificationSoundPath, value, SoundNotificationChanged);
}
public int NotificationSoundVolume{
get => _notificationSoundVolume;
set => UpdatePropertyWithEvent(ref _notificationSoundVolume, value, SoundNotificationChanged);
} }
public bool MuteNotifications{ public bool MuteNotifications{
get => _muteNotifications; get => _muteNotifications;
set => UpdatePropertyWithEvent(ref _muteNotifications, value, MuteToggled);
set{
if (_muteNotifications != value){
_muteNotifications = value;
MuteToggled?.Invoke(this, EventArgs.Empty);
}
}
} }
public int ZoomLevel{ public int ZoomLevel{
get => _zoomLevel; get => _zoomLevel;
set => UpdatePropertyWithEvent(ref _zoomLevel, value, ZoomLevelChanged);
set{
if (_zoomLevel != value){
_zoomLevel = value;
ZoomLevelChanged?.Invoke(this, EventArgs.Empty);
}
}
} }
public TrayIcon.Behavior TrayBehavior{ public TrayIcon.Behavior TrayBehavior{
get => _trayBehavior; get => _trayBehavior;
set => UpdatePropertyWithEvent(ref _trayBehavior, value, TrayBehaviorChanged);
set{
if (_trayBehavior != value){
_trayBehavior = value;
TrayBehaviorChanged?.Invoke(this, EventArgs.Empty);
}
}
} }
// EVENTS // EVENTS
@@ -139,6 +128,7 @@ namespace TweetDuck.Configuration{
public event EventHandler MuteToggled; public event EventHandler MuteToggled;
public event EventHandler ZoomLevelChanged; public event EventHandler ZoomLevelChanged;
public event EventHandler TrayBehaviorChanged; public event EventHandler TrayBehaviorChanged;
public event EventHandler SoundNotificationChanged;
// END OF CONFIG // END OF CONFIG
@@ -148,6 +138,13 @@ namespace TweetDuck.Configuration{
this.file = file; this.file = file;
} }
private void UpdatePropertyWithEvent<T>(ref T field, T value, EventHandler eventHandler){
if (!EqualityComparer<T>.Default.Equals(field, value)){
field = value;
eventHandler?.Invoke(this, EventArgs.Empty);
}
}
public void Save(){ public void Save(){
try{ try{
if (File.Exists(file)){ if (File.Exists(file)){

View File

@@ -19,7 +19,6 @@ namespace TweetDuck.Core.Bridge{
build.Append("x.openSearchInFirstColumn=").Append(Bool(Program.UserConfig.OpenSearchInFirstColumn)); build.Append("x.openSearchInFirstColumn=").Append(Bool(Program.UserConfig.OpenSearchInFirstColumn));
build.Append("x.keepLikeFollowDialogsOpen=").Append(Bool(Program.UserConfig.KeepLikeFollowDialogsOpen)); build.Append("x.keepLikeFollowDialogsOpen=").Append(Bool(Program.UserConfig.KeepLikeFollowDialogsOpen));
build.Append("x.muteNotifications=").Append(Bool(Program.UserConfig.MuteNotifications)); build.Append("x.muteNotifications=").Append(Bool(Program.UserConfig.MuteNotifications));
build.Append("x.hasCustomNotificationSound=").Append(Bool(Program.UserConfig.NotificationSoundPath.Length > 0));
build.Append("x.notificationMediaPreviews=").Append(Bool(Program.UserConfig.NotificationMediaPreviews)); build.Append("x.notificationMediaPreviews=").Append(Bool(Program.UserConfig.NotificationMediaPreviews));
build.Append("x.translationTarget=").Append(Str(Program.UserConfig.TranslationTarget)); build.Append("x.translationTarget=").Append(Str(Program.UserConfig.TranslationTarget));
} }

View File

@@ -126,7 +126,7 @@ namespace TweetDuck.Core.Bridge{
public void OnTweetSound(){ public void OnTweetSound(){
form.InvokeAsyncSafe(() => { form.InvokeAsyncSafe(() => {
form.OnTweetNotification(); form.OnTweetNotification();
form.PlayNotificationSound(); form.OnTweetSound();
}); });
} }

View File

@@ -15,7 +15,6 @@ using TweetDuck.Core.Utils;
using TweetDuck.Plugins; using TweetDuck.Plugins;
using TweetDuck.Plugins.Events; using TweetDuck.Plugins.Events;
using TweetDuck.Updates; using TweetDuck.Updates;
using TweetLib.Audio;
namespace TweetDuck.Core{ namespace TweetDuck.Core{
sealed partial class FormBrowser : Form{ sealed partial class FormBrowser : Form{
@@ -50,7 +49,6 @@ namespace TweetDuck.Core{
private FormWindowState prevState; private FormWindowState prevState;
private TweetScreenshotManager notificationScreenshotManager; private TweetScreenshotManager notificationScreenshotManager;
private SoundNotification soundNotification;
private VideoPlayer videoPlayer; private VideoPlayer videoPlayer;
private AnalyticsManager analytics; private AnalyticsManager analytics;
@@ -82,7 +80,6 @@ namespace TweetDuck.Core{
contextMenu.Dispose(); contextMenu.Dispose();
notificationScreenshotManager?.Dispose(); notificationScreenshotManager?.Dispose();
soundNotification?.Dispose();
videoPlayer?.Dispose(); videoPlayer?.Dispose();
analytics?.Dispose(); analytics?.Dispose();
}; };
@@ -291,22 +288,6 @@ namespace TweetDuck.Core{
}); });
} }
private void soundNotification_PlaybackError(object sender, PlaybackErrorEventArgs e){
e.Ignore = true;
using(FormMessage form = new FormMessage("Notification Sound Error", "Could not play custom notification sound.\n"+e.Message, MessageBoxIcon.Error)){
form.AddButton(FormMessage.Ignore, ControlType.Cancel | ControlType.Focused);
Button btnOpenSettings = form.AddButton("View Options");
btnOpenSettings.Width += 16;
btnOpenSettings.Location = new Point(btnOpenSettings.Location.X-16, btnOpenSettings.Location.Y);
if (form.ShowDialog() == DialogResult.OK && form.ClickedButton == btnOpenSettings){
OpenSettings(typeof(TabSettingsSounds));
}
}
}
protected override void WndProc(ref Message m){ protected override void WndProc(ref Message m){
if (isLoaded && m.Msg == Program.WindowRestoreMessage){ if (isLoaded && m.Msg == Program.WindowRestoreMessage){
if (WindowsUtils.CurrentProcessID == m.WParam.ToInt32()){ if (WindowsUtils.CurrentProcessID == m.WParam.ToInt32()){
@@ -357,6 +338,10 @@ namespace TweetDuck.Core{
browser.ReloadColumns(); browser.ReloadColumns();
} }
public void PlaySoundNotification(){
browser.PlaySoundNotification();
}
public void ApplyROT13(){ public void ApplyROT13(){
browser.ApplyROT13(); browser.ApplyROT13();
} }
@@ -459,19 +444,7 @@ namespace TweetDuck.Core{
} }
} }
public void PlayNotificationSound(){ public void OnTweetSound(){
if (Config.NotificationSoundPath.Length == 0){
return;
}
if (soundNotification == null){
soundNotification = new SoundNotification();
soundNotification.PlaybackError += soundNotification_PlaybackError;
}
soundNotification.SetVolume(Config.NotificationSoundVolume);
soundNotification.Play(Config.NotificationSoundPath);
TriggerAnalyticsEvent(AnalyticsFile.Event.SoundNotification); TriggerAnalyticsEvent(AnalyticsFile.Event.SoundNotification);
} }

View File

@@ -139,8 +139,7 @@ namespace TweetDuck.Core.Notification{
DpiScale = this.GetDPIScale(); DpiScale = this.GetDPIScale();
DefaultResourceHandlerFactory handlerFactory = (DefaultResourceHandlerFactory)browser.ResourceHandlerFactory; browser.GetHandlerFactory().RegisterHandler(TwitterUtils.TweetDeckURL, this.resourceHandler);
handlerFactory.RegisterHandler(TwitterUtils.TweetDeckURL, this.resourceHandler);
Controls.Add(browser); Controls.Add(browser);

View File

@@ -1,32 +1,53 @@
using System; using System.Drawing;
using TweetLib.Audio; using System.IO;
using System.Windows.Forms;
using CefSharp;
using TweetDuck.Core.Controls;
using TweetDuck.Core.Other;
using TweetDuck.Core.Other.Settings;
namespace TweetDuck.Core.Notification{ namespace TweetDuck.Core.Notification{
sealed class SoundNotification : IDisposable{ static class SoundNotification{
public string SupportedFormats => player.SupportedFormats; public const string SupportedFormats = "*.wav;*.ogg;*.flac;*.opus;*.weba;*.webm"; // TODO add mp3 when supported
public event EventHandler<PlaybackErrorEventArgs> PlaybackError;
public static IResourceHandler CreateFileHandler(string path){
string mimeType;
private readonly AudioPlayer player; switch(Path.GetExtension(path)){
case ".weba":
case ".webm": mimeType = "audio/webm"; break;
case ".wav": mimeType = "audio/wav"; break;
case ".ogg": mimeType = "audio/ogg"; break;
case ".flac": mimeType = "audio/flac"; break;
case ".opus": mimeType = "audio/ogg; codecs=opus"; break;
case ".mp3": TryShowError("MP3 sound notifications are temporarily unsupported, please convert the file to another format, such as .ogg, .wav, or .flac."); return null;
default: mimeType = null; break;
}
public SoundNotification(){ try{
this.player = AudioPlayer.New(); return ResourceHandler.FromFilePath(path, mimeType);
this.player.PlaybackError += Player_PlaybackError; }catch{
TryShowError("Could not find custom notification sound file:\n"+path);
return null;
}
} }
public void Play(string file){ private static void TryShowError(string message){
player.Play(file); FormBrowser browser = FormManager.TryFind<FormBrowser>();
}
public bool SetVolume(int volume){ browser?.InvokeAsyncSafe(() => {
return player.SetVolume(volume); using(FormMessage form = new FormMessage("Sound Notification Error", message, MessageBoxIcon.Error)){
} form.AddButton(FormMessage.Ignore, ControlType.Cancel | ControlType.Focused);
Button btnViewOptions = form.AddButton("View Options");
btnViewOptions.Width += 16;
btnViewOptions.Location = new Point(btnViewOptions.Location.X-16, btnViewOptions.Location.Y);
private void Player_PlaybackError(object sender, PlaybackErrorEventArgs e){ if (form.ShowDialog() == DialogResult.OK && form.ClickedButton == btnViewOptions){
PlaybackError?.Invoke(this, e); browser.OpenSettings(typeof(TabSettingsSounds));
} }
}
public void Dispose(){ });
player.Dispose();
} }
} }
} }

View File

@@ -40,7 +40,7 @@ namespace TweetDuck.Core.Other{
AddButton("Locales", () => new TabSettingsLocales()); AddButton("Locales", () => new TabSettingsLocales());
AddButton("System Tray", () => new TabSettingsTray()); AddButton("System Tray", () => new TabSettingsTray());
AddButton("Notifications", () => new TabSettingsNotifications(new FormNotificationExample(this.browser, this.plugins))); AddButton("Notifications", () => new TabSettingsNotifications(new FormNotificationExample(this.browser, this.plugins)));
AddButton("Sounds", () => new TabSettingsSounds()); AddButton("Sounds", () => new TabSettingsSounds(this.browser.PlaySoundNotification));
AddButton("Feedback", () => new TabSettingsFeedback(analytics, AnalyticsReportGenerator.ExternalInfo.From(this.browser), this.plugins)); AddButton("Feedback", () => new TabSettingsFeedback(analytics, AnalyticsReportGenerator.ExternalInfo.From(this.browser), this.plugins));
AddButton("Advanced", () => new TabSettingsAdvanced(this.browser.ReinjectCustomCSS)); AddButton("Advanced", () => new TabSettingsAdvanced(this.browser.ReinjectCustomCSS));

View File

@@ -36,6 +36,7 @@
this.trackBarVolume = new System.Windows.Forms.TrackBar(); this.trackBarVolume = new System.Windows.Forms.TrackBar();
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel(); this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
this.panelVolume = new System.Windows.Forms.Panel(); this.panelVolume = new System.Windows.Forms.Panel();
this.volumeUpdateTimer = new System.Windows.Forms.Timer(this.components);
this.panelSoundNotification.SuspendLayout(); this.panelSoundNotification.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).BeginInit();
this.flowPanel.SuspendLayout(); this.flowPanel.SuspendLayout();
@@ -170,6 +171,11 @@
this.panelVolume.Size = new System.Drawing.Size(322, 36); this.panelVolume.Size = new System.Drawing.Size(322, 36);
this.panelVolume.TabIndex = 2; this.panelVolume.TabIndex = 2;
// //
// volumeUpdateTimer
//
this.volumeUpdateTimer.Interval = 250;
this.volumeUpdateTimer.Tick += new System.EventHandler(this.volumeUpdateTimer_Tick);
//
// TabSettingsSounds // TabSettingsSounds
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -201,5 +207,6 @@
private System.Windows.Forms.TrackBar trackBarVolume; private System.Windows.Forms.TrackBar trackBarVolume;
private System.Windows.Forms.FlowLayoutPanel flowPanel; private System.Windows.Forms.FlowLayoutPanel flowPanel;
private System.Windows.Forms.Panel panelVolume; private System.Windows.Forms.Panel panelVolume;
private System.Windows.Forms.Timer volumeUpdateTimer;
} }
} }

View File

@@ -4,25 +4,18 @@ using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using TweetDuck.Core.Controls; using TweetDuck.Core.Controls;
using TweetDuck.Core.Notification; using TweetDuck.Core.Notification;
using TweetLib.Audio;
namespace TweetDuck.Core.Other.Settings{ namespace TweetDuck.Core.Other.Settings{
sealed partial class TabSettingsSounds : BaseTabSettings{ sealed partial class TabSettingsSounds : BaseTabSettings{
private readonly SoundNotification soundNotification; private readonly Action playSoundNotification;
private readonly bool supportsChangingVolume;
public TabSettingsSounds(){ public TabSettingsSounds(Action playSoundNotification){
InitializeComponent(); InitializeComponent();
soundNotification = new SoundNotification(); this.playSoundNotification = playSoundNotification;
soundNotification.PlaybackError += sound_PlaybackError;
Disposed += (sender, args) => soundNotification.Dispose();
supportsChangingVolume = soundNotification.SetVolume(Config.NotificationSoundVolume);
toolTip.SetToolTip(tbCustomSound, "When empty, the default TweetDeck sound notification is used."); toolTip.SetToolTip(tbCustomSound, "When empty, the default TweetDeck sound notification is used.");
trackBarVolume.Enabled = supportsChangingVolume && !string.IsNullOrEmpty(Config.NotificationSoundPath);
trackBarVolume.SetValueSafe(Config.NotificationSoundVolume); trackBarVolume.SetValueSafe(Config.NotificationSoundVolume);
labelVolumeValue.Text = trackBarVolume.Value+"%"; labelVolumeValue.Text = trackBarVolume.Value+"%";
@@ -39,22 +32,29 @@ namespace TweetDuck.Core.Other.Settings{
public override void OnClosing(){ public override void OnClosing(){
Config.NotificationSoundPath = tbCustomSound.Text; Config.NotificationSoundPath = tbCustomSound.Text;
Config.NotificationSoundVolume = trackBarVolume.Value;
}
private bool RefreshCanPlay(){
bool isEmpty = string.IsNullOrEmpty(tbCustomSound.Text);
bool canPlay = isEmpty || File.Exists(tbCustomSound.Text);
tbCustomSound.ForeColor = canPlay ? SystemColors.WindowText : Color.Red;
btnPlaySound.Enabled = canPlay;
btnResetSound.Enabled = !isEmpty;
return canPlay;
} }
private void tbCustomSound_TextChanged(object sender, EventArgs e){ private void tbCustomSound_TextChanged(object sender, EventArgs e){
bool isEmpty = string.IsNullOrEmpty(tbCustomSound.Text); RefreshCanPlay();
tbCustomSound.ForeColor = isEmpty || File.Exists(tbCustomSound.Text) ? SystemColors.WindowText : Color.Red;
btnPlaySound.Enabled = !isEmpty;
btnResetSound.Enabled = !isEmpty;
trackBarVolume.Enabled = supportsChangingVolume && !isEmpty;
} }
private void btnPlaySound_Click(object sender, EventArgs e){ private void btnPlaySound_Click(object sender, EventArgs e){
soundNotification.Play(tbCustomSound.Text); if (RefreshCanPlay()){
} Config.NotificationSoundPath = tbCustomSound.Text;
Config.NotificationSoundVolume = trackBarVolume.Value;
private void sound_PlaybackError(object sender, PlaybackErrorEventArgs e){ playSoundNotification();
FormMessage.Error("Notification Sound Error", "Could not play custom notification sound.\n"+e.Message, FormMessage.OK); }
} }
private void btnBrowseSound_Click(object sender, EventArgs e){ private void btnBrowseSound_Click(object sender, EventArgs e){
@@ -62,7 +62,7 @@ namespace TweetDuck.Core.Other.Settings{
AutoUpgradeEnabled = true, AutoUpgradeEnabled = true,
DereferenceLinks = true, DereferenceLinks = true,
Title = "Custom Notification Sound", Title = "Custom Notification Sound",
Filter = "Sound file ("+soundNotification.SupportedFormats+")|"+soundNotification.SupportedFormats+"|All files (*.*)|*.*" Filter = $"Sound file ({SoundNotification.SupportedFormats})|{SoundNotification.SupportedFormats}|All files (*.*)|*.*"
}){ }){
if (dialog.ShowDialog() == DialogResult.OK){ if (dialog.ShowDialog() == DialogResult.OK){
tbCustomSound.Text = dialog.FileName; tbCustomSound.Text = dialog.FileName;
@@ -75,9 +75,14 @@ namespace TweetDuck.Core.Other.Settings{
} }
private void trackBarVolume_ValueChanged(object sender, EventArgs e){ private void trackBarVolume_ValueChanged(object sender, EventArgs e){
volumeUpdateTimer.Stop();
volumeUpdateTimer.Start();
labelVolumeValue.Text = trackBarVolume.Value+"%";
}
private void volumeUpdateTimer_Tick(object sender, EventArgs e){
Config.NotificationSoundVolume = trackBarVolume.Value; Config.NotificationSoundVolume = trackBarVolume.Value;
soundNotification.SetVolume(Config.NotificationSoundVolume); volumeUpdateTimer.Stop();
labelVolumeValue.Text = Config.NotificationSoundVolume+"%";
} }
} }
} }

View File

@@ -7,6 +7,7 @@ using TweetDuck.Core.Bridge;
using TweetDuck.Core.Controls; using TweetDuck.Core.Controls;
using TweetDuck.Core.Handling; using TweetDuck.Core.Handling;
using TweetDuck.Core.Handling.General; using TweetDuck.Core.Handling.General;
using TweetDuck.Core.Notification;
using TweetDuck.Core.Utils; using TweetDuck.Core.Utils;
using TweetDuck.Plugins; using TweetDuck.Plugins;
using TweetDuck.Plugins.Enums; using TweetDuck.Plugins.Enums;
@@ -36,6 +37,8 @@ namespace TweetDuck.Core{
private readonly ChromiumWebBrowser browser; private readonly ChromiumWebBrowser browser;
private readonly PluginManager plugins; private readonly PluginManager plugins;
private string prevSoundNotificationPath = null;
public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridge bridge){ public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridge bridge){
this.browser = new ChromiumWebBrowser(TwitterUtils.TweetDeckURL){ this.browser = new ChromiumWebBrowser(TwitterUtils.TweetDeckURL){
DialogHandler = new FileDialogHandler(), DialogHandler = new FileDialogHandler(),
@@ -70,6 +73,7 @@ namespace TweetDuck.Core{
Program.UserConfig.MuteToggled += UserConfig_MuteToggled; Program.UserConfig.MuteToggled += UserConfig_MuteToggled;
Program.UserConfig.ZoomLevelChanged += UserConfig_ZoomLevelChanged; Program.UserConfig.ZoomLevelChanged += UserConfig_ZoomLevelChanged;
Program.UserConfig.SoundNotificationChanged += UserConfig_SoundNotificationInfoChanged;
} }
// setup and management // setup and management
@@ -91,6 +95,7 @@ namespace TweetDuck.Core{
Program.UserConfig.MuteToggled -= UserConfig_MuteToggled; Program.UserConfig.MuteToggled -= UserConfig_MuteToggled;
Program.UserConfig.ZoomLevelChanged -= UserConfig_ZoomLevelChanged; Program.UserConfig.ZoomLevelChanged -= UserConfig_ZoomLevelChanged;
Program.UserConfig.SoundNotificationChanged -= UserConfig_SoundNotificationInfoChanged;
browser.Dispose(); browser.Dispose();
} }
@@ -129,6 +134,7 @@ namespace TweetDuck.Core{
ScriptLoader.ExecuteFile(e.Frame, "code.js"); ScriptLoader.ExecuteFile(e.Frame, "code.js");
InjectBrowserCSS(); InjectBrowserCSS();
ReinjectCustomCSS(Program.UserConfig.CustomBrowserCSS); ReinjectCustomCSS(Program.UserConfig.CustomBrowserCSS);
UserConfig_SoundNotificationInfoChanged(null, EventArgs.Empty);
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Browser); plugins.ExecutePlugins(e.Frame, PluginEnvironment.Browser);
TweetDeckBridge.ResetStaticProperties(); TweetDeckBridge.ResetStaticProperties();
@@ -167,6 +173,27 @@ namespace TweetDuck.Core{
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Program.UserConfig.ZoomLevel); BrowserUtils.SetZoomLevel(browser.GetBrowser(), Program.UserConfig.ZoomLevel);
} }
private void UserConfig_SoundNotificationInfoChanged(object sender, EventArgs e){
const string soundUrl = "https://ton.twimg.com/tduck/updatesnd";
bool hasCustomSound = Program.UserConfig.IsCustomSoundNotificationSet;
if (prevSoundNotificationPath != Program.UserConfig.NotificationSoundPath){
DefaultResourceHandlerFactory handlerFactory = browser.GetHandlerFactory();
IResourceHandler resourceHandler = hasCustomSound ? SoundNotification.CreateFileHandler(Program.UserConfig.NotificationSoundPath) : null;
if (resourceHandler != null){
handlerFactory.RegisterHandler(soundUrl, resourceHandler);
}
else{
handlerFactory.UnregisterHandler(soundUrl);
}
prevSoundNotificationPath = Program.UserConfig.NotificationSoundPath;
}
browser.ExecuteScriptAsync("TDGF_setSoundNotificationData", hasCustomSound, Program.UserConfig.NotificationSoundVolume);
}
// external handling // external handling
public UpdateHandler CreateUpdateHandler(UpdaterSettings settings){ public UpdateHandler CreateUpdateHandler(UpdaterSettings settings){
@@ -215,6 +242,10 @@ namespace TweetDuck.Core{
browser.ExecuteScriptAsync("TDGF_reloadColumns()"); browser.ExecuteScriptAsync("TDGF_reloadColumns()");
} }
public void PlaySoundNotification(){
browser.ExecuteScriptAsync("TDGF_playSoundNotification()");
}
public void ApplyROT13(){ public void ApplyROT13(){
browser.ExecuteScriptAsync("TDGF_applyROT13()"); browser.ExecuteScriptAsync("TDGF_applyROT13()");
} }

View File

@@ -36,8 +36,14 @@ namespace TweetDuck.Core.Utils{
} }
else if (shouldRun && AutoClearTimer == null){ else if (shouldRun && AutoClearTimer == null){
AutoClearTimer = new Timer(state => { AutoClearTimer = new Timer(state => {
if (AutoClearTimer != null && CalculateCacheSize() >= Program.SystemConfig.ClearCacheThreshold*1024L*1024L){ if (AutoClearTimer != null){
SetClearOnExit(); try{
if (CalculateCacheSize() >= Program.SystemConfig.ClearCacheThreshold*1024L*1024L){
SetClearOnExit();
}
}catch(Exception){
// TODO should probably log errors and report them at some point
}
} }
}, null, TimeSpan.FromSeconds(30), TimeSpan.FromHours(4)); }, null, TimeSpan.FromSeconds(30), TimeSpan.FromHours(4));
} }

View File

@@ -35,6 +35,10 @@ namespace TweetDuck.Core.Utils{
return (ChromiumWebBrowser)browserControl; return (ChromiumWebBrowser)browserControl;
} }
public static DefaultResourceHandlerFactory GetHandlerFactory(this ChromiumWebBrowser browser){
return (DefaultResourceHandlerFactory)browser.ResourceHandlerFactory;
}
private const string TwitterTrackingUrl = "t.co"; private const string TwitterTrackingUrl = "t.co";
public enum UrlCheckResult{ public enum UrlCheckResult{

View File

@@ -20,7 +20,7 @@ namespace TweetDuck{
public const string BrandName = "TweetDuck"; public const string BrandName = "TweetDuck";
public const string Website = "https://tweetduck.chylex.com"; public const string Website = "https://tweetduck.chylex.com";
public const string VersionTag = "1.12"; public const string VersionTag = "1.12.1.1";
public static readonly bool IsPortable = File.Exists("makeportable"); public static readonly bool IsPortable = File.Exists("makeportable");

View File

@@ -8,7 +8,7 @@ Edit layout & design
chylex chylex
[version] [version]
1.1.8 1.1.9
[website] [website]
https://tweetduck.chylex.com https://tweetduck.chylex.com

View File

@@ -367,12 +367,12 @@ enabled(){
this.css.insert(".app-content, .app-columns-container { background-color: #444448 !important }"); this.css.insert(".app-content, .app-columns-container { background-color: #444448 !important }");
this.css.insert(".column-drag-handle { opacity: 0.5 !important }"); this.css.insert(".column-drag-handle { opacity: 0.5 !important }");
this.css.insert(".column-drag-handle:hover { opacity: 1 !important }"); this.css.insert(".column-drag-handle:hover { opacity: 1 !important }");
this.css.insert(".scroll-styled-v:not(.scroll-alt)::-webkit-scrollbar-thumb, .scroll-styled-h:not(.scroll-alt)::-webkit-scrollbar-thumb { background-color: #666 !important }"); this.css.insert(".scroll-styled-v:not(.scroll-alt)::-webkit-scrollbar-thumb:not(:hover), .scroll-styled-h:not(.scroll-alt)::-webkit-scrollbar-thumb:not(:hover) { background-color: #666 !important }");
notificationScrollbarColor = "666"; notificationScrollbarColor = "666";
break; break;
case "light": case "light":
this.css.insert(".scroll-styled-v:not(.scroll-alt)::-webkit-scrollbar-thumb, .scroll-styled-h:not(.scroll-alt)::-webkit-scrollbar-thumb { background-color: #d2d6da !important }"); this.css.insert(".scroll-styled-v:not(.scroll-alt)::-webkit-scrollbar-thumb:not(:hover), .scroll-styled-h:not(.scroll-alt)::-webkit-scrollbar-thumb:not(:hover) { background-color: #d2d6da !important }");
this.css.insert(".app-columns-container.scroll-styled-h::-webkit-scrollbar-thumb:not(:hover) { background-color: #a5aeb5 !important }"); this.css.insert(".app-columns-container.scroll-styled-h::-webkit-scrollbar-thumb:not(:hover) { background-color: #a5aeb5 !important }");
notificationScrollbarColor = "a5aeb5"; notificationScrollbarColor = "a5aeb5";
break; break;
@@ -562,7 +562,7 @@ ${this.config.revertIcons ? `
` : ``} ` : ``}
${notificationScrollbarColor ? ` ${notificationScrollbarColor ? `
.scroll-styled-v::-webkit-scrollbar-thumb, .scroll-styled-h::-webkit-scrollbar-thumb { background-color: #${notificationScrollbarColor} !important } .scroll-styled-v::-webkit-scrollbar-thumb:not(:hover), .scroll-styled-h::-webkit-scrollbar-thumb:not(:hover) { background-color: #${notificationScrollbarColor} !important }
` : ``} ` : ``}
</style>`); </style>`);
}; };

View File

@@ -233,7 +233,7 @@
} }
.td-avatar-shape-item-outer label { .td-avatar-shape-item-outer label {
margin: 10px 0 0; margin: 10px 0 0 !important;
} }
.td-avatar-shape { .td-avatar-shape {

View File

@@ -507,10 +507,35 @@
// //
// Block: Hook into the notification sound effect. // Block: Hook into the notification sound effect.
// //
HTMLAudioElement.prototype.play = prependToFunction(HTMLAudioElement.prototype.play, function(){ HTMLAudioElement.prototype.play = prependToFunction(HTMLAudioElement.prototype.play, function(){
return $TDX.muteNotifications || $TDX.hasCustomNotificationSound; return $TDX.muteNotifications;
}); });
window.TDGF_setSoundNotificationData = function(custom, volume){
let audio = document.getElementById("update-sound");
audio.volume = volume/100;
const sourceId = "tduck-custom-sound-source";
let source = document.getElementById(sourceId);
if (custom && !source){
source = document.createElement("source");
source.id = sourceId;
source.src = "https://ton.twimg.com/tduck/updatesnd";
audio.prepend(source);
}
else if (!custom && source){
audio.removeChild(source);
}
audio.load();
};
window.TDGF_playSoundNotification = function(){
document.getElementById("update-sound").play();
};
// //
// Block: Update highlighted column and tweet for context menu and other functionality. // Block: Update highlighted column and tweet for context menu and other functionality.
// //
@@ -734,14 +759,12 @@
// Block: Allow drag & drop behavior for dropping links on columns to open their detail view. // Block: Allow drag & drop behavior for dropping links on columns to open their detail view.
// //
(function(){ (function(){
let tweetRegex = /^https?:\/\/twitter\.com\/[A-Za-z0-9_]+\/status\/(\d+)\/?$/; const tweetRegex = /^https?:\/\/twitter\.com\/[A-Za-z0-9_]+\/status\/(\d+)\/?$/;
const selector = "section.js-column";
let isDraggingValid = false; let isDraggingValid = false;
window.TDGF_onGlobalDragStart = function(type, data){ const events = {
isDraggingValid = (type === "link" || type === "text") && tweetRegex.test(data);
};
app.delegate("section.js-column", {
dragover: function(e){ dragover: function(e){
e.originalEvent.dataTransfer.dropEffect = isDraggingValid ? "move" : "none"; e.originalEvent.dataTransfer.dropEffect = isDraggingValid ? "move" : "none";
e.preventDefault(); e.preventDefault();
@@ -767,7 +790,17 @@
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
} }
}); };
window.TDGF_onGlobalDragStart = function(type, data){
if (type === "link"){
isDraggingValid = tweetRegex.test(data);
app.delegate(selector, events);
}
else{
app.undelegate(selector, events);
}
};
})(); })();
// //
@@ -1174,13 +1207,52 @@
// //
// Block: Revert Like/Follow dialogs being closed after clicking an action. // Block: Revert Like/Follow dialogs being closed after clicking an action.
// //
if (ensurePropertyExists(TD, "decider", "get")){ (function(){
const prevFunc = TD.decider.get; const prevSetTimeout = window.setTimeout;
TD.decider.get = function(key){ const overrideState = function(){
return $TDX.keepLikeFollowDialogsOpen && key.startsWith("tweetdeck_subsequent_") ? false : prevFunc.apply(this, arguments); return if !$TDX.keepLikeFollowDialogsOpen;
window.setTimeout = function(func, timeout){
return timeout !== 500 && prevSetTimeout.apply(this, arguments);
};
}; };
}
const restoreState = function(context, key){
window.setTimeout = prevSetTimeout;
if ($TDX.keepLikeFollowDialogsOpen && key in context.state){
context.state[key] = false;
}
};
$(document).on("uiShowFavoriteFromOptions", function(){
$(".js-btn-fav", ".js-modal-inner").each(function(){
let event = $._data(this, "events").click[0];
let handler = event.handler;
event.handler = function(){
overrideState();
handler.apply(this, arguments);
restoreState($._data(document, "events").dataFavoriteState[0].handler.context, "stopSubsequentLikes");
};
});
});
$(document).on("uiShowFollowFromOptions", function(){
$(".js-component", ".js-modal-inner").each(function(){
let event = $._data(this, "events").click[0];
let handler = event.handler;
let context = handler.context;
event.handler = function(){
overrideState();
handler.apply(this, arguments);
restoreState(context, "stopSubsequentFollows");
};
});
});
})();
// //
// Block: Fix DM reply input box not getting focused after opening a conversation. // Block: Fix DM reply input box not getting focused after opening a conversation.

View File

@@ -114,7 +114,7 @@
return if !btn; return if !btn;
btn.addEventListener("click", function(){ btn.addEventListener("click", function(){
$TD.showNotificationTweetDetail(); $TD.showTweetDetail();
}); });
})(); })();

View File

@@ -378,10 +378,6 @@
<Content Include="Resources\Scripts\update.js" /> <Content Include="Resources\Scripts\update.js" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="lib\TweetLib.Audio\TweetLib.Audio.csproj">
<Project>{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}</Project>
<Name>TweetLib.Audio</Name>
</ProjectReference>
<ProjectReference Include="subprocess\TweetDuck.Browser.csproj"> <ProjectReference Include="subprocess\TweetDuck.Browser.csproj">
<Project>{b10b0017-819e-4f71-870f-8256b36a26aa}</Project> <Project>{b10b0017-819e-4f71-870f-8256b36a26aa}</Project>
<Name>TweetDuck.Browser</Name> <Name>TweetDuck.Browser</Name>

View File

@@ -8,8 +8,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetDuck.Browser", "subpro
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "tests\UnitTests.csproj", "{A958FA7A-4A2C-42A7-BFA0-159343483F4E}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "tests\UnitTests.csproj", "{A958FA7A-4A2C-42A7-BFA0-159343483F4E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.Audio", "lib\TweetLib.Audio\TweetLib.Audio.csproj", "{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetDuck.Video", "video\TweetDuck.Video.csproj", "{278B2D11-402D-44B6-B6A1-8FA67DB65565}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetDuck.Video", "video\TweetDuck.Video.csproj", "{278B2D11-402D-44B6-B6A1-8FA67DB65565}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.Communication", "lib\TweetLib.Communication\TweetLib.Communication.csproj", "{72473763-4B9D-4FB6-A923-9364B2680F06}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TweetLib.Communication", "lib\TweetLib.Communication\TweetLib.Communication.csproj", "{72473763-4B9D-4FB6-A923-9364B2680F06}"
@@ -32,10 +30,6 @@ Global
{A958FA7A-4A2C-42A7-BFA0-159343483F4E}.Debug|x86.ActiveCfg = Debug|x86 {A958FA7A-4A2C-42A7-BFA0-159343483F4E}.Debug|x86.ActiveCfg = Debug|x86
{A958FA7A-4A2C-42A7-BFA0-159343483F4E}.Debug|x86.Build.0 = Debug|x86 {A958FA7A-4A2C-42A7-BFA0-159343483F4E}.Debug|x86.Build.0 = Debug|x86
{A958FA7A-4A2C-42A7-BFA0-159343483F4E}.Release|x86.ActiveCfg = Release|x86 {A958FA7A-4A2C-42A7-BFA0-159343483F4E}.Release|x86.ActiveCfg = Release|x86
{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}.Debug|x86.ActiveCfg = Debug|x86
{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}.Debug|x86.Build.0 = Debug|x86
{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}.Release|x86.ActiveCfg = Release|x86
{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}.Release|x86.Build.0 = Release|x86
{278B2D11-402D-44B6-B6A1-8FA67DB65565}.Debug|x86.ActiveCfg = Debug|x86 {278B2D11-402D-44B6-B6A1-8FA67DB65565}.Debug|x86.ActiveCfg = Debug|x86
{278B2D11-402D-44B6-B6A1-8FA67DB65565}.Debug|x86.Build.0 = Debug|x86 {278B2D11-402D-44B6-B6A1-8FA67DB65565}.Debug|x86.Build.0 = Debug|x86
{278B2D11-402D-44B6-B6A1-8FA67DB65565}.Release|x86.ActiveCfg = Release|x86 {278B2D11-402D-44B6-B6A1-8FA67DB65565}.Release|x86.ActiveCfg = Release|x86

View File

@@ -59,6 +59,7 @@ Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\Cache"
Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\GPUCache" Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\GPUCache"
[InstallDelete] [InstallDelete]
Type: files; Name: "{app}\TweetLib.Audio.dll"
Type: filesandordirs; Name: "{app}\plugins\official" Type: filesandordirs; Name: "{app}\plugins\official"
Type: files; Name: "{app}\locales\am.pak" Type: files; Name: "{app}\locales\am.pak"
Type: files; Name: "{app}\locales\ar.pak" Type: files; Name: "{app}\locales\ar.pak"

View File

@@ -1,41 +0,0 @@
using System;
using System.Runtime.InteropServices;
using TweetLib.Audio.Impl;
namespace TweetLib.Audio{
public abstract class AudioPlayer : IDisposable{
private static bool? IsWMPAvailable;
public static AudioPlayer New(){
if (IsWMPAvailable.HasValue){
if (IsWMPAvailable.Value){
return new SoundPlayerImplWMP();
}
else{
return new SoundPlayerImplFallback();
}
}
try{
SoundPlayerImplWMP implWMP = new SoundPlayerImplWMP();
IsWMPAvailable = true;
return implWMP;
}catch(COMException){
IsWMPAvailable = false;
return new SoundPlayerImplFallback();
}
}
public abstract string SupportedFormats { get; }
public abstract event EventHandler<PlaybackErrorEventArgs> PlaybackError;
public abstract void Play(string file);
public abstract bool SetVolume(int volume);
protected abstract void Dispose(bool disposing);
public void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -1,53 +0,0 @@
using System;
using System.IO;
using System.Media;
namespace TweetLib.Audio.Impl{
sealed class SoundPlayerImplFallback : AudioPlayer{
public override string SupportedFormats => "*.wav";
public override event EventHandler<PlaybackErrorEventArgs> PlaybackError;
private readonly SoundPlayer player;
private bool ignorePlaybackError;
public SoundPlayerImplFallback(){
player = new SoundPlayer{
LoadTimeout = 5000
};
}
public override void Play(string file){
if (player.SoundLocation != file){
player.SoundLocation = file;
ignorePlaybackError = false;
}
try{
player.Play();
}catch(FileNotFoundException e){
OnNotificationSoundError("File not found: "+e.FileName);
}catch(InvalidOperationException){
OnNotificationSoundError("File format was not recognized.");
}catch(TimeoutException){
OnNotificationSoundError("File took too long to load.");
}
}
public override bool SetVolume(int volume){
return false;
}
protected override void Dispose(bool disposing){
player.Dispose();
}
private void OnNotificationSoundError(string message){
if (!ignorePlaybackError){
PlaybackErrorEventArgs args = new PlaybackErrorEventArgs(message);
PlaybackError?.Invoke(this, args);
ignorePlaybackError = args.Ignore;
}
}
}
}

View File

@@ -1,124 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using WMPLib;
namespace TweetLib.Audio.Impl{
sealed class SoundPlayerImplWMP : AudioPlayer{
public override string SupportedFormats => "*.wav;*.mp3;*.mp2;*.m4a;*.mid;*.midi;*.rmi;*.wma;*.aif;*.aifc;*.aiff;*.snd;*.au";
public override event EventHandler<PlaybackErrorEventArgs> PlaybackError;
private readonly Form owner;
private readonly ControlWMP wmp;
private bool wasTryingToPlay;
private bool ignorePlaybackError;
private WindowsMediaPlayer Player => wmp.Ocx;
public SoundPlayerImplWMP(){
owner = new Form();
wmp = new ControlWMP();
wmp.BeginInit();
owner.Controls.Add(wmp);
wmp.EndInit();
Player.uiMode = "none";
Player.settings.autoStart = false;
Player.settings.enableErrorDialogs = false;
Player.settings.invokeURLs = false;
Player.settings.volume = 0;
Player.MediaChange += player_MediaChange;
Player.MediaError += player_MediaError;
}
public override void Play(string file){
wasTryingToPlay = true;
try{
if (Player.URL != file){
Player.close();
Player.URL = file;
ignorePlaybackError = false;
}
else{
Player.controls.stop();
}
Player.controls.play();
}catch(Exception e){
OnNotificationSoundError("An error occurred in Windows Media Player: "+e.Message);
}
}
public override bool SetVolume(int volume){
Player.settings.volume = volume;
return true;
}
protected override void Dispose(bool disposing){
wmp.Dispose();
owner.Dispose();
}
private void player_MediaChange(object item){
IWMPMedia2 media = item as IWMPMedia2;
if (media == null){
OnNotificationSoundError("Unknown error.");
return;
}
// ReSharper disable once CompareOfFloatsByEqualityOperator
else if (media.Error == null && media.duration == 0.0){
OnNotificationSoundError("File does not contain an audio track.");
}
else if (media.Error != null){
OnNotificationSoundError(media.Error);
}
Marshal.ReleaseComObject(media);
}
private void player_MediaError(object pMediaObject){
IWMPMedia2 media = pMediaObject as IWMPMedia2;
if (media == null){
OnNotificationSoundError("Unknown error.");
return;
}
else if (media.Error != null){
OnNotificationSoundError(media.Error);
}
Marshal.ReleaseComObject(media);
}
private void OnNotificationSoundError(IWMPErrorItem error){
OnNotificationSoundError(error.errorCode == -1072885353 ? "Invalid media file." : error.errorDescription);
Marshal.ReleaseComObject(error);
}
private void OnNotificationSoundError(string message){
if (wasTryingToPlay){
wasTryingToPlay = false;
if (!ignorePlaybackError){
PlaybackErrorEventArgs args = new PlaybackErrorEventArgs(message);
PlaybackError?.Invoke(this, args);
ignorePlaybackError = args.Ignore;
}
}
}
[Clsid("{6bf52a52-394a-11d3-b153-00c04f79faa6}")]
private sealed class ControlWMP : AxHost{
public WindowsMediaPlayer Ocx { get; private set; }
public ControlWMP() : base("6bf52a52-394a-11d3-b153-00c04f79faa6"){}
protected override void AttachInterfaces(){
Ocx = (WindowsMediaPlayer)GetOcx();
}
}
}
}

View File

@@ -1,13 +0,0 @@
using System;
namespace TweetLib.Audio{
public sealed class PlaybackErrorEventArgs : EventArgs{
public string Message { get; }
public bool Ignore { get; set; }
public PlaybackErrorEventArgs(string message){
this.Message = message;
this.Ignore = false;
}
}
}

View File

@@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TweetDuck Audio Library")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TweetDuck Audio Library")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e9e1fd1b-f480-45b7-9970-be2ecfd309ac")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.1.0")]
[assembly: AssemblyFileVersion("1.1.1.0")]

View File

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{E9E1FD1B-F480-45B7-9970-BE2ECFD309AC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TweetLib.Audio</RootNamespace>
<AssemblyName>TweetLib.Audio</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ResolveComReferenceSilent>True</ResolveComReferenceSilent>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Release\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="AudioPlayer.cs" />
<Compile Include="PlaybackErrorEventArgs.cs" />
<Compile Include="Impl\SoundPlayerImplFallback.cs" />
<Compile Include="Impl\SoundPlayerImplWMP.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<COMReference Include="WMPLib">
<Guid>{6BF52A50-394A-11D3-B153-00C04F79FAA6}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>