├── Toastify ├── version ├── src │ ├── App.xaml.cs │ ├── Core │ │ ├── HotkeyType.cs │ │ ├── SpotifyWebAPIInitializationFailedReason.cs │ │ ├── Broadcaster │ │ │ ├── MessageReceivedEventArgs.cs │ │ │ ├── JsonGreetingsObject.cs │ │ │ └── JsonTrack.cs │ │ ├── SpotifyWeb.cs │ │ ├── ToastTitlesOrder.cs │ │ ├── UpdateDeliveryMode.cs │ │ ├── ToastifyVolumeControlMode.cs │ │ ├── ApplicationStartupException.cs │ │ ├── SecureProxyConfigJsonConverter.cs │ │ ├── VersionCheckFrequency.cs │ │ └── ToastifyActionEnum.cs │ ├── Model │ │ ├── GetVolumeControlModeDelegate.cs │ │ ├── MediaActionType.cs │ │ ├── IToastifyActionRegistry.cs │ │ ├── ToastifyExit.cs │ │ ├── ToastifyShowDebugView.cs │ │ ├── ToastifySimpleMediaAction.cs │ │ ├── ToastifyNoAction.cs │ │ ├── ToastifyShowSpotify.cs │ │ ├── JsonConverterContractResolver.cs │ │ ├── SpotifyUserProfile.cs │ │ ├── ToastifyShowToast.cs │ │ ├── ToastifyVolumeAction.cs │ │ ├── ToastifyVolumeUp.cs │ │ ├── ToastifyVolumeMute.cs │ │ ├── ToastifyVolumeDown.cs │ │ └── ToastifyActionAsEnumJsonConverter.cs │ ├── DI │ │ └── PropertyDependencyAttribute.cs │ ├── ViewModel │ │ ├── ISettingsViewModel.cs │ │ ├── ChangelogViewModel.cs │ │ ├── AboutViewModel.cs │ │ └── ConfigProxyDialogViewModel.cs │ ├── Common │ │ ├── ConstraintFailedException.cs │ │ ├── EnumReadableNameAttribute.cs │ │ ├── EnumComboBoxItem.cs │ │ ├── ComboBoxItemAttribute.cs │ │ ├── StringStream.cs │ │ ├── Range.cs │ │ └── WindowPosition.cs │ ├── Events │ │ ├── UpdateReadyEventArgs.cs │ │ ├── SpotifyPlayStateChangedEventArgs.cs │ │ ├── SpotifyTrackTimeChangedEventArgs.cs │ │ ├── CheckVersionCompleteEventArgs.cs │ │ ├── SpotifyWebAPIInitializationFailedEventArgs.cs │ │ ├── SpotifyVolumeChangedEventArgs.cs │ │ ├── HotkeyActionCallbackFailedEventArgs.cs │ │ ├── SpotifyTrackChangedEventArgs.cs │ │ ├── CurrentSettingsChangedEventArgs.cs │ │ ├── SettingsViewLaunchedEventArgs.cs │ │ ├── SettingsSavedEventArgs.cs │ │ └── SpotifyStateEventArgs.cs │ ├── Logging │ │ └── DebugLogAppender.cs │ ├── Threading │ │ ├── WindowThreadOptions.cs │ │ └── IWindowThread.cs │ ├── Helpers │ │ ├── AutomationHelper.cs │ │ ├── Validators │ │ │ ├── IPPortRule.cs │ │ │ └── IPAddressRule.cs │ │ ├── Converters │ │ │ ├── HexColorToAlphaValueConverter.cs │ │ │ ├── BoolToVisibleConverter.cs │ │ │ ├── OppositeBoolConverter.cs │ │ │ ├── OppositeBoolToVisibleConverter.cs │ │ │ ├── SettingValueToOppositeBoolValueConverter.cs │ │ │ └── SettingValueToValueConverter.cs │ │ ├── WindsorContainerExtensions.cs │ │ ├── Markdown │ │ │ └── TextToFlowDocumentConverter.cs │ │ └── ColorHelper.cs │ ├── View │ │ └── DebugView.xaml │ ├── Services │ │ └── Analytics.g.tt │ └── App.xaml ├── ManagedWinapi.dll ├── Resources │ ├── InfoLarge.png │ ├── thumbs_up.png │ ├── SpotifyLogo.png │ ├── ToastifyIcon.ico │ ├── WarningLarge.png │ ├── WarningSmall.png │ ├── thumbs_down.png │ ├── SpotifyAdPlaying.png │ ├── SpotifyToastifyLogo.png │ ├── ToastifyAccessDenied.png │ ├── ManagedWinapiNativeHelper.dll │ ├── SpotifyToastifyUpdateLogo.png │ └── SystemTrayAnimation │ │ ├── toastify_loading_spotify_0.ico │ │ ├── toastify_loading_spotify_1.ico │ │ ├── toastify_loading_spotify_10.ico │ │ ├── toastify_loading_spotify_11.ico │ │ ├── toastify_loading_spotify_12.ico │ │ ├── toastify_loading_spotify_13.ico │ │ ├── toastify_loading_spotify_14.ico │ │ ├── toastify_loading_spotify_15.ico │ │ ├── toastify_loading_spotify_16.ico │ │ ├── toastify_loading_spotify_17.ico │ │ ├── toastify_loading_spotify_18.ico │ │ ├── toastify_loading_spotify_19.ico │ │ ├── toastify_loading_spotify_2.ico │ │ ├── toastify_loading_spotify_20.ico │ │ ├── toastify_loading_spotify_21.ico │ │ ├── toastify_loading_spotify_22.ico │ │ ├── toastify_loading_spotify_23.ico │ │ ├── toastify_loading_spotify_3.ico │ │ ├── toastify_loading_spotify_4.ico │ │ ├── toastify_loading_spotify_5.ico │ │ ├── toastify_loading_spotify_6.ico │ │ ├── toastify_loading_spotify_7.ico │ │ ├── toastify_loading_spotify_8.ico │ │ └── toastify_loading_spotify_9.ico ├── Properties │ ├── launchSettings.json │ ├── Settings.settings │ ├── AssemblyInfo.cs │ └── Settings.Designer.cs ├── Toastify.csproj.vspscc ├── app.config ├── log4net.config └── pre-build.cmd ├── InstallationScript ├── README.txt └── Plugins │ ├── x64-ansi │ └── NSISpcre.dll │ ├── x86-ansi │ ├── NSISpcre.dll │ ├── ShellLink.dll │ ├── DotNetChecker.dll │ ├── KillProcWMI.dll │ └── ShellExecAsUser.dll │ ├── x64-unicode │ └── NSISpcre.dll │ └── x86-unicode │ ├── NSISpcre.dll │ ├── ShellLink.dll │ ├── KillProcWMI.dll │ ├── DotNetChecker.dll │ └── ShellExecAsUser.dll ├── update-version.cmd ├── .gitmodules ├── .vscode └── settings.json ├── packages ├── Windows │ └── 10.0.14393 │ │ └── Windows.winmd └── repositories.config ├── Toastify.Test ├── WindsorTestsData │ ├── IDependency.cs │ ├── Dependency.cs │ ├── IDependecyWithDependecy.cs │ ├── DependecyWithDependencies.cs │ ├── DependencyBase.cs │ └── WindsorContainerData.cs ├── app.config ├── Helpers │ └── WindsorContainerExtensionsTest.cs ├── packages.config ├── Model │ └── ToastifyActions │ │ └── ToastifyNoActionTest.cs └── Properties │ └── AssemblyInfo.cs ├── ToastifyAPI ├── Native │ ├── Delegates │ │ ├── EnumWindowsProc.cs │ │ ├── HookProc.cs │ │ ├── EnumThreadDelegate.cs │ │ ├── SendMessageDelegate.cs │ │ ├── EnumResNameProcDelegate.cs │ │ └── LowLevelMouseHookProc.cs │ ├── MMDeviceAPI │ │ ├── Enums │ │ │ ├── EDataFlow.cs │ │ │ ├── ERole.cs │ │ │ └── EDeviceState.cs │ │ ├── MMDeviceEnumerator.cs │ │ ├── IMMDeviceCollection.cs │ │ ├── IAudioSessionManager2.cs │ │ ├── IAudioSessionEnumerator.cs │ │ ├── IMMDevice.cs │ │ ├── IMMDeviceEnumerator.cs │ │ ├── ISimpleAudioVolume.cs │ │ └── IAudioSessionControl2.cs │ ├── Enums │ │ ├── MapVirtualKeyType.cs │ │ ├── GWL.cs │ │ ├── MenuFlags.cs │ │ ├── CryptProtectPromptFlags.cs │ │ ├── ExecutionStateFlags.cs │ │ ├── VirtualKeyCode.cs │ │ ├── ShGSI.cs │ │ ├── HookType.cs │ │ ├── ResourceType.cs │ │ ├── SysCommands.cs │ │ ├── CryptProtectFlags.cs │ │ ├── WindowStylesFlags.cs │ │ ├── ExtendedWindowStylesFlags.cs │ │ └── WindowsMessagesFlags.cs │ ├── RawInputAPI │ │ ├── Structs │ │ │ ├── RawInput.cs │ │ │ ├── RawHID.cs │ │ │ ├── RawInputData.cs │ │ │ ├── RawInputHeader.cs │ │ │ ├── RawInputDevice.cs │ │ │ ├── RawKeyboard.cs │ │ │ └── RawMouse.cs │ │ ├── Enums │ │ │ ├── RawInputCommand.cs │ │ │ ├── RawKeyboardFlags.cs │ │ │ ├── RawInputType.cs │ │ │ ├── RawMouseFlags.cs │ │ │ └── RawMouseButtons.cs │ │ └── RawInput.cs │ ├── Shell32.cs │ ├── Structs │ │ ├── CryptProtectPromptStruct.cs │ │ ├── WindowPlacement.cs │ │ ├── Rect.cs │ │ ├── DataBlob.cs │ │ └── ShStockIconInfo.cs │ ├── Crypt32.cs │ └── Processes.cs ├── Interop │ ├── Interfaces │ │ ├── IInputDevice.cs │ │ ├── IKeyboard.cs │ │ ├── IMouse.cs │ │ └── IInputDevices.cs │ ├── Keyboard.cs │ └── InputDevices.cs ├── Model │ ├── Interfaces │ │ ├── ISpotifyUserProfile.cs │ │ ├── ICurrentlyPlayingObject.cs │ │ ├── ISongAlbumArt.cs │ │ ├── IKeyboardHotkey.cs │ │ ├── IMouseHookHotkey.cs │ │ ├── IActionable.cs │ │ ├── IKeyOrButton.cs │ │ ├── ISpotifyTrack.cs │ │ ├── ISong.cs │ │ ├── ILockedGlobalHotkey.cs │ │ ├── IAction.cs │ │ ├── IGlobalHotkey.cs │ │ └── IHotkey.cs │ ├── GlobalHotkey.cs │ └── LockedGlobalHotkey.cs ├── Logic │ ├── Interfaces │ │ ├── IKeyboardHotkeyVisitor.cs │ │ ├── IHotkeyVisitor.cs │ │ └── IMouseHookHotkeyVisitor.cs │ └── KeyboardHotkeyVisitor.cs ├── Core │ ├── Auth │ │ ├── ISpotifyWebAuth.cs │ │ ├── IToken.cs │ │ ├── NoAuth.cs │ │ ├── IAuthHttpServer.cs │ │ ├── ToastifyWebAuthAPI │ │ │ ├── ClientCredentialsFlow.cs │ │ │ ├── Structs │ │ │ │ ├── HttpResponse.cs │ │ │ │ └── SpotifyTokenResponse.cs │ │ │ ├── Utils.cs │ │ │ └── AuthorizationCodeFlow.cs │ │ ├── AuthEventArgs.cs │ │ └── ITokenManager.cs │ ├── ISpotifyWeb.cs │ ├── SpotifyTrackType.cs │ ├── SpotifySubscriptionLevel.cs │ ├── ISpotifyWebAPI.cs │ ├── MouseAction.cs │ ├── IToastifyBroadcaster.cs │ └── IProxyConfig.cs ├── GitHub │ ├── Model │ │ ├── CollectionData.cs │ │ ├── BaseModel.cs │ │ ├── Emoji.cs │ │ ├── Asset.cs │ │ └── Release.cs │ └── RepoInfo.cs ├── packages.config ├── Events │ ├── ActionFailedEventArgs.cs │ ├── WindowTitleChangedEventArgs.cs │ └── SpotifyTokenChangedEventArgs.cs ├── Spotify.win32.cs ├── Helpers │ ├── StringHelpers.cs │ ├── ITokenExtensions.cs │ └── Net.cs ├── Spotify.uwp.cs ├── Win32API.uwp.cs ├── Common │ └── AnonymousEqualityComparer.cs ├── multiple.proj └── Properties │ └── AssemblyInfo.cs ├── ExamplePlugin ├── ExamplePlugin.csproj.vspscc ├── Properties │ └── AssemblyInfo.cs └── ExamplePlugin.cs ├── tasks.json ├── ISSUE_TEMPLATE.md ├── ToastifyAPI.Tests ├── packages.config ├── Logic │ └── KeyboardHotkeyVisitorTest.cs └── Properties │ └── AssemblyInfo.cs └── update-version.ps1 /Toastify/version: -------------------------------------------------------------------------------- 1 | 1.12.2 -------------------------------------------------------------------------------- /InstallationScript/README.txt: -------------------------------------------------------------------------------- 1 | Copy the Plugins folder to: 2 | [NSIS install directory]\ -------------------------------------------------------------------------------- /update-version.cmd: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | CD /D %~dp0 4 | powershell -File "update-version.ps1" -------------------------------------------------------------------------------- /Toastify/src/App.xaml.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/src/App.xaml.cs -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Aleab.Common"] 2 | path = Aleab.Common 3 | url = https://github.com/aleab/Aleab.Common.git 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dotnet.preferCSharpExtension": true, 3 | "dotnet.defaultSolution": "Toastify.sln" 4 | } -------------------------------------------------------------------------------- /Toastify/ManagedWinapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/ManagedWinapi.dll -------------------------------------------------------------------------------- /Toastify/Resources/InfoLarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/InfoLarge.png -------------------------------------------------------------------------------- /Toastify/Resources/thumbs_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/thumbs_up.png -------------------------------------------------------------------------------- /Toastify/Resources/SpotifyLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SpotifyLogo.png -------------------------------------------------------------------------------- /Toastify/Resources/ToastifyIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/ToastifyIcon.ico -------------------------------------------------------------------------------- /Toastify/Resources/WarningLarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/WarningLarge.png -------------------------------------------------------------------------------- /Toastify/Resources/WarningSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/WarningSmall.png -------------------------------------------------------------------------------- /Toastify/Resources/thumbs_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/thumbs_down.png -------------------------------------------------------------------------------- /Toastify/Resources/SpotifyAdPlaying.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SpotifyAdPlaying.png -------------------------------------------------------------------------------- /Toastify/Resources/SpotifyToastifyLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SpotifyToastifyLogo.png -------------------------------------------------------------------------------- /Toastify/Resources/ToastifyAccessDenied.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/ToastifyAccessDenied.png -------------------------------------------------------------------------------- /packages/Windows/10.0.14393/Windows.winmd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/packages/Windows/10.0.14393/Windows.winmd -------------------------------------------------------------------------------- /Toastify.Test/WindsorTestsData/IDependency.cs: -------------------------------------------------------------------------------- 1 | namespace Toastify.Tests.WindsorTestsData 2 | { 3 | internal interface IDependency 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /InstallationScript/Plugins/x64-ansi/NSISpcre.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x64-ansi/NSISpcre.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-ansi/NSISpcre.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-ansi/NSISpcre.dll -------------------------------------------------------------------------------- /Toastify/Resources/ManagedWinapiNativeHelper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/ManagedWinapiNativeHelper.dll -------------------------------------------------------------------------------- /Toastify/Resources/SpotifyToastifyUpdateLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SpotifyToastifyUpdateLogo.png -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-ansi/ShellLink.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-ansi/ShellLink.dll -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /InstallationScript/Plugins/x64-unicode/NSISpcre.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x64-unicode/NSISpcre.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-ansi/DotNetChecker.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-ansi/DotNetChecker.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-ansi/KillProcWMI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-ansi/KillProcWMI.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-unicode/NSISpcre.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-unicode/NSISpcre.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-unicode/ShellLink.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-unicode/ShellLink.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-ansi/ShellExecAsUser.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-ansi/ShellExecAsUser.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-unicode/KillProcWMI.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-unicode/KillProcWMI.dll -------------------------------------------------------------------------------- /Toastify/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Toastify": { 4 | "commandName": "Project", 5 | "nativeDebugging" : false 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-unicode/DotNetChecker.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-unicode/DotNetChecker.dll -------------------------------------------------------------------------------- /InstallationScript/Plugins/x86-unicode/ShellExecAsUser.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/InstallationScript/Plugins/x86-unicode/ShellExecAsUser.dll -------------------------------------------------------------------------------- /Toastify.Test/WindsorTestsData/Dependency.cs: -------------------------------------------------------------------------------- 1 | namespace Toastify.Tests.WindsorTestsData 2 | { 3 | internal class Dependency : DependencyBase, IDependency 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /Toastify/src/Core/HotkeyType.cs: -------------------------------------------------------------------------------- 1 | namespace Toastify.Core 2 | { 3 | public enum HotkeyType 4 | { 5 | Undefined = -1, 6 | Keyboard, 7 | MouseHook 8 | } 9 | } -------------------------------------------------------------------------------- /Toastify/src/Model/GetVolumeControlModeDelegate.cs: -------------------------------------------------------------------------------- 1 | using Toastify.Core; 2 | 3 | namespace Toastify.Model 4 | { 5 | public delegate ToastifyVolumeControlMode GetVolumeControlModeDelegate(); 6 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Delegates/EnumWindowsProc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.Delegates 4 | { 5 | public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); 6 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Delegates/HookProc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.Delegates 4 | { 5 | public delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam); 6 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Delegates/EnumThreadDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.Delegates 4 | { 5 | public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); 6 | } -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_0.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_0.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_1.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_10.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_10.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_11.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_11.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_12.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_12.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_13.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_13.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_14.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_14.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_15.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_15.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_16.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_17.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_17.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_18.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_18.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_19.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_19.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_2.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_20.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_20.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_21.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_21.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_22.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_22.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_23.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_23.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_3.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_3.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_4.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_4.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_5.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_5.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_6.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_6.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_7.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_7.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_8.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_8.ico -------------------------------------------------------------------------------- /Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_9.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igzmanuelmartinvivaldi/toastify/HEAD/Toastify/Resources/SystemTrayAnimation/toastify_loading_spotify_9.ico -------------------------------------------------------------------------------- /ToastifyAPI/Interop/Interfaces/IInputDevice.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Interop.Interfaces 2 | { 3 | public interface IInputDevice 4 | { 5 | bool IsKeyboard(); 6 | 7 | bool IsMouse(); 8 | } 9 | } -------------------------------------------------------------------------------- /Toastify.Test/WindsorTestsData/IDependecyWithDependecy.cs: -------------------------------------------------------------------------------- 1 | namespace Toastify.Tests.WindsorTestsData 2 | { 3 | internal interface IDependecyWithDependecy 4 | { 5 | IDependency Dependency { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Delegates/SendMessageDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.Delegates 4 | { 5 | public delegate void SendMessageDelegate(IntPtr hWnd, uint uMsg, UIntPtr dwData, IntPtr lResult); 6 | } -------------------------------------------------------------------------------- /Toastify/src/DI/PropertyDependencyAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.DI 4 | { 5 | [AttributeUsage(AttributeTargets.Property)] 6 | public class PropertyDependencyAttribute : Attribute 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Delegates/EnumResNameProcDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.Delegates 4 | { 5 | public delegate bool EnumResNameProcDelegate(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam); 6 | } -------------------------------------------------------------------------------- /Toastify/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/ISpotifyUserProfile.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Core; 2 | 3 | namespace ToastifyAPI.Model.Interfaces 4 | { 5 | public interface ISpotifyUserProfile 6 | { 7 | SpotifySubscriptionLevel SubscriptionLevel { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/Enums/EDataFlow.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Native.MMDeviceAPI.Enums 2 | { 3 | public enum EDataFlow 4 | { 5 | ERender, 6 | ECapture, 7 | EAll, 8 | EDataFlowEnumCount 9 | } 10 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/Enums/ERole.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Native.MMDeviceAPI.Enums 2 | { 3 | public enum ERole 4 | { 5 | EConsole, 6 | EMultimedia, 7 | ECommunications, 8 | ERoleEnumCount 9 | } 10 | } -------------------------------------------------------------------------------- /Toastify/src/Core/SpotifyWebAPIInitializationFailedReason.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Core 4 | { 5 | public enum SpotifyWebAPIInitializationFailedReason 6 | { 7 | NoToken, 8 | ToastifyWebAuthAPINotFound 9 | } 10 | } -------------------------------------------------------------------------------- /ToastifyAPI/Logic/Interfaces/IKeyboardHotkeyVisitor.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Model.Interfaces; 2 | 3 | namespace ToastifyAPI.Logic.Interfaces 4 | { 5 | public interface IKeyboardHotkeyVisitor : IHotkeyVisitor 6 | { 7 | void Visit(IKeyboardHotkey hotkey); 8 | } 9 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/GlobalHotkey.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using ManagedWinapi; 3 | using ToastifyAPI.Model.Interfaces; 4 | 5 | namespace ToastifyAPI.Model 6 | { 7 | public class GlobalHotkey : Hotkey, IGlobalHotkey, ILockedGlobalHotkey 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/MMDeviceEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ToastifyAPI.Native.MMDeviceAPI 4 | { 5 | [ComImport] 6 | [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] 7 | public class MMDeviceEnumerator 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /ToastifyAPI/Logic/Interfaces/IHotkeyVisitor.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Logic.Interfaces 2 | { 3 | /// 4 | /// Degenerate interface used in the (kind-of) Visitor pattern to handle hotkey presses. 5 | /// 6 | public interface IHotkeyVisitor 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /Toastify/src/Model/MediaActionType.cs: -------------------------------------------------------------------------------- 1 | namespace Toastify.Model 2 | { 3 | /// 4 | /// The type of action of a . 5 | /// 6 | public enum MediaActionType 7 | { 8 | AppCommandMessage, 9 | MediaKey 10 | } 11 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/ISpotifyWebAuth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace ToastifyAPI.Core.Auth 5 | { 6 | public interface ISpotifyWebAuth : IDisposable 7 | { 8 | Task GetToken(); 9 | Task RefreshToken(IToken token); 10 | } 11 | } -------------------------------------------------------------------------------- /Toastify/Toastify.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /ToastifyAPI/Core/ISpotifyWeb.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Core.Auth; 2 | 3 | namespace ToastifyAPI.Core 4 | { 5 | public interface ISpotifyWeb 6 | { 7 | #region Public Properties 8 | 9 | ISpotifyWebAuth Auth { get; } 10 | 11 | ISpotifyWebAPI API { get; } 12 | 13 | #endregion 14 | } 15 | } -------------------------------------------------------------------------------- /ExamplePlugin/ExamplePlugin.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /Toastify.Test/WindsorTestsData/DependecyWithDependencies.cs: -------------------------------------------------------------------------------- 1 | using Toastify.DI; 2 | 3 | namespace Toastify.Tests.WindsorTestsData 4 | { 5 | internal class DependecyWithDependencies : DependencyBase, IDependecyWithDependecy 6 | { 7 | [PropertyDependency] 8 | public IDependency Dependency { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /Toastify/src/ViewModel/ISettingsViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Toastify.Model; 3 | 4 | namespace Toastify.ViewModel 5 | { 6 | public interface ISettingsViewModel 7 | { 8 | #region Public Properties 9 | 10 | IReadOnlyList Hotkeys { get; } 11 | 12 | #endregion 13 | } 14 | } -------------------------------------------------------------------------------- /ToastifyAPI/GitHub/Model/CollectionData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ToastifyAPI.GitHub.Model 4 | { 5 | public class CollectionData : BaseModel where T : BaseModel 6 | { 7 | #region Public Properties 8 | 9 | public ICollection Collection { get; set; } 10 | 11 | #endregion 12 | } 13 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Delegates/LowLevelMouseHookProc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using ToastifyAPI.Native.Enums; 4 | using ToastifyAPI.Native.Structs; 5 | 6 | namespace ToastifyAPI.Native.Delegates 7 | { 8 | public delegate IntPtr LowLevelMouseHookProc(int code, WindowsMessagesFlags wParam, [In] LowLevelMouseHookStruct lParam); 9 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/ICurrentlyPlayingObject.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Core; 2 | 3 | namespace ToastifyAPI.Model.Interfaces 4 | { 5 | public interface ICurrentlyPlayingObject 6 | { 7 | int ProgressMs { get; } 8 | bool IsPlaying { get; } 9 | ISpotifyTrack Track { get; } 10 | SpotifyTrackType Type { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/ISongAlbumArt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Model.Interfaces 4 | { 5 | public interface ISongAlbumArt : IEquatable 6 | { 7 | #region Public Properties 8 | 9 | int Height { get; } 10 | int Width { get; } 11 | string Url { get; } 12 | 13 | #endregion 14 | } 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/SpotifyTrackType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace ToastifyAPI.Core 6 | { 7 | [Serializable] 8 | [JsonConverter(typeof(StringEnumConverter))] 9 | public enum SpotifyTrackType 10 | { 11 | Unknown = -1, 12 | Song, 13 | Episode, 14 | Ad 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/MapVirtualKeyType.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable InconsistentNaming 2 | namespace ToastifyAPI.Native.Enums 3 | { 4 | public enum MapVirtualKeyType : uint 5 | { 6 | MAPVK_VK_TO_VSC = 0, 7 | MAPVK_VSC_TO_VK = 1, 8 | MAPVK_VK_TO_CHAR = 2, 9 | MAPVK_VSC_TO_VK_EX = 3, 10 | MAPVK_VK_TO_VSC_EX = 4 11 | } 12 | } -------------------------------------------------------------------------------- /ToastifyAPI/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "command": "dotnet", 7 | "type": "process", 8 | "args": [ 9 | "build", 10 | "${workspaceFolder}/toastify.csproj" 11 | ], 12 | "problemMatcher": "$msCompile" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Interop/Interfaces/IKeyboard.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | 3 | namespace ToastifyAPI.Interop.Interfaces 4 | { 5 | /// 6 | /// A wrapper around the class. 7 | /// 8 | public interface IKeyboard : IInputDevice 9 | { 10 | bool IsKeyDown(Key key); 11 | 12 | bool IsKeyUp(Key key); 13 | } 14 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/GWL.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable InconsistentNaming 2 | namespace ToastifyAPI.Native.Enums 3 | { 4 | public enum GWL 5 | { 6 | GWL_EXSTYLE = -20, 7 | GWL_HINSTANCE = -6, 8 | GWL_HWNDPARENT = -8, 9 | GWL_ID = -12, 10 | GWL_STYLE = -16, 11 | GWL_USERDATA = -21, 12 | GWL_WNDPROC = -4 13 | } 14 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/SpotifySubscriptionLevel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Newtonsoft.Json.Converters; 4 | 5 | namespace ToastifyAPI.Core 6 | { 7 | [Serializable] 8 | [JsonConverter(typeof(StringEnumConverter))] 9 | public enum SpotifySubscriptionLevel 10 | { 11 | Unknown = -1, 12 | Free, 13 | Open = Free, 14 | Premium 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/MenuFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | // ReSharper disable InconsistentNaming 4 | namespace ToastifyAPI.Native.Enums 5 | { 6 | [Flags] 7 | public enum MenuFlags : long 8 | { 9 | MF_BYCOMMAND = 0x0000L, 10 | MF_ENABLED = 0x0000L, 11 | MF_GRAYED = 0x0001L, 12 | MF_DISABLED = 0x0002L, 13 | MF_BYPOSITION = 0x0400L 14 | } 15 | } -------------------------------------------------------------------------------- /Toastify/src/Common/ConstraintFailedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | 4 | namespace Toastify.Common 5 | { 6 | public class ConstraintFailedException : ApplicationException 7 | { 8 | public ConstraintFailedException(Expression constraint) : base($"Constraint failed:{Environment.NewLine} {constraint}{Environment.NewLine}") 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ToastifyAPI/GitHub/Model/BaseModel.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.Http.Headers; 3 | 4 | namespace ToastifyAPI.GitHub.Model 5 | { 6 | public abstract class BaseModel 7 | { 8 | #region Public Properties 9 | 10 | public HttpResponseHeaders HttpResponseHeaders { get; set; } 11 | 12 | public HttpStatusCode HttpStatusCode { get; set; } 13 | 14 | #endregion 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/IKeyboardHotkey.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | 3 | namespace ToastifyAPI.Model.Interfaces 4 | { 5 | /// 6 | /// Defines a hotkey that uses keyboard keys. 7 | /// 8 | public interface IKeyboardHotkey : IHotkey 9 | { 10 | #region Public Properties 11 | 12 | Key? Key { get; set; } 13 | 14 | #endregion 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/CryptProtectPromptFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | // ReSharper disable InconsistentNaming 4 | namespace ToastifyAPI.Native.Enums 5 | { 6 | [Flags] 7 | public enum CryptProtectPromptFlags 8 | { 9 | // prompt on unprotect 10 | CRYPTPROTECT_PROMPT_ON_UNPROTECT = 0x1, 11 | 12 | // prompt on protect 13 | CRYPTPROTECT_PROMPT_ON_PROTECT = 0x2 14 | } 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/Enums/EDeviceState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.MMDeviceAPI.Enums 4 | { 5 | [Flags] 6 | public enum EDeviceState 7 | { 8 | Active = 0x00000001, 9 | Disabled = 0x00000002, 10 | NotPresent = 0x00000004, 11 | UnPlugged = 0x00000008, 12 | All = UnPlugged | NotPresent | Disabled | Active // 0x0000000F 13 | } 14 | } -------------------------------------------------------------------------------- /Toastify/src/Events/UpdateReadyEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Events 4 | { 5 | public class UpdateReadyEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public string Version { get; set; } 10 | 11 | public string InstallerPath { get; set; } 12 | 13 | public string GitHubReleaseUrl { get; set; } 14 | 15 | #endregion 16 | } 17 | } -------------------------------------------------------------------------------- /ToastifyAPI/Interop/Interfaces/IMouse.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | 3 | namespace ToastifyAPI.Interop.Interfaces 4 | { 5 | /// 6 | /// A wrapper around the class. 7 | /// 8 | public interface IMouse : IInputDevice 9 | { 10 | bool IsPressed(MouseButton mouseButton); 11 | 12 | bool IsReleased(MouseButton mouseButton); 13 | } 14 | } -------------------------------------------------------------------------------- /ToastifyAPI/Events/ActionFailedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Events 4 | { 5 | public class ActionFailedEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public string Message { get; } 10 | 11 | #endregion 12 | 13 | public ActionFailedEventArgs(string message) 14 | { 15 | this.Message = message; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/IMouseHookHotkey.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Core; 2 | 3 | namespace ToastifyAPI.Model.Interfaces 4 | { 5 | /// 6 | /// Defines a hotkey that uses mouse buttons. 7 | /// 8 | public interface IMouseHookHotkey : IHotkey 9 | { 10 | #region Public Properties 11 | 12 | MouseAction? MouseButton { get; set; } 13 | 14 | #endregion 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Structs/RawInput.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ToastifyAPI.Native.RawInputAPI.Structs 4 | { 5 | /// 6 | /// Contains the raw input from a device. 7 | /// 8 | [StructLayout(LayoutKind.Sequential)] 9 | public struct RawInput 10 | { 11 | public RawInputHeader Header; 12 | public RawInputData Data; 13 | } 14 | } -------------------------------------------------------------------------------- /Toastify/src/Core/Broadcaster/MessageReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Core.Broadcaster 4 | { 5 | public class MessageReceivedEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public string Message { get; } 10 | 11 | #endregion 12 | 13 | public MessageReceivedEventArgs(string message) 14 | { 15 | this.Message = message; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Toastify/src/Events/SpotifyPlayStateChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Events 4 | { 5 | public class SpotifyPlayStateChangedEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public bool Playing { get; } 10 | 11 | #endregion 12 | 13 | public SpotifyPlayStateChangedEventArgs(bool playing) 14 | { 15 | this.Playing = playing; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Toastify/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using System.Runtime.InteropServices; 3 | using System.Windows; 4 | using log4net.Config; 5 | 6 | [assembly: ComVisible(false)] 7 | [assembly: InternalsVisibleTo("Toastify.Tests")] 8 | 9 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] 10 | [assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)] 11 | 12 | -------------------------------------------------------------------------------- /Toastify/src/Logging/DebugLogAppender.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using log4net.Appender; 3 | using log4net.Core; 4 | 5 | namespace Toastify.Logging 6 | { 7 | // ReSharper disable once UnusedMember.Global 8 | public class DebugLogAppender : ConsoleAppender 9 | { 10 | protected override void Append(LoggingEvent loggingEvent) 11 | { 12 | Debug.Write(this.RenderLoggingEvent(loggingEvent)); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/IActionable.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Model.Interfaces 2 | { 3 | /// 4 | /// Defines an object that can perform an action. 5 | /// 6 | public interface IActionable 7 | { 8 | #region Public Properties 9 | 10 | IAction Action { get; set; } 11 | 12 | float MaxFrequency { get; set; } 13 | 14 | #endregion 15 | 16 | void PerformAction(); 17 | } 18 | } -------------------------------------------------------------------------------- /Toastify/src/Events/SpotifyTrackTimeChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Events 4 | { 5 | public class SpotifyTrackTimeChangedEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public double TrackTime { get; } 10 | 11 | #endregion 12 | 13 | public SpotifyTrackTimeChangedEventArgs(double trackTime) 14 | { 15 | this.TrackTime = trackTime; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/IKeyOrButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | using MouseAction = ToastifyAPI.Core.MouseAction; 4 | 5 | namespace ToastifyAPI.Model.Interfaces 6 | { 7 | public interface IKeyOrButton : ICloneable 8 | { 9 | #region Public Properties 10 | 11 | bool IsKey { get; } 12 | 13 | Key? Key { get; } 14 | 15 | MouseAction? MouseButton { get; } 16 | 17 | #endregion 18 | } 19 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Structs/RawHID.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace ToastifyAPI.Native.RawInputAPI.Structs 5 | { 6 | /// 7 | /// Contains information about the state of the HID. 8 | /// 9 | [StructLayout(LayoutKind.Sequential)] 10 | public struct RawHID 11 | { 12 | public int Size; 13 | public int Count; 14 | public IntPtr Data; 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/IToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Core.Auth 4 | { 5 | public interface IToken : IEquatable 6 | { 7 | #region Public Properties 8 | 9 | string AccessToken { get; } 10 | string TokenType { get; } 11 | double ExpiresIn { get; } 12 | string RefreshToken { get; } 13 | DateTime CreateDate { get; } 14 | 15 | #endregion 16 | 17 | bool IsExpired(); 18 | } 19 | } -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | If this is a crash, bug or unexpected behaviour report, please use the following template. 2 | 3 | ## EXPECTED BEHAVIOUR 4 | *(Write the expected behaviour here)* 5 | 6 | ## ACTUAL BEHAVIOUR 7 | *(Write the actual behaviour here)* 8 | 9 | ## STEPS TO REPRODUCE THE BEHAVIOUR 10 | *(Write the steps to reproduce the actual behaviour here)* 11 | 12 | ## LOG FILE 13 | *(Drag and drop your `Toastify.log` file here; it can be found in `%LocalAppData%\Toastify`)* 14 | -------------------------------------------------------------------------------- /Toastify/src/Model/IToastifyActionRegistry.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | using Toastify.Core; 3 | 4 | namespace Toastify.Model 5 | { 6 | /// 7 | /// Supports the retrieval of instances from a registry of values. 8 | /// 9 | public interface IToastifyActionRegistry 10 | { 11 | [CanBeNull] 12 | ToastifyAction GetAction(ToastifyActionEnum actionEnum); 13 | } 14 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Shell32.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using ToastifyAPI.Native.Enums; 4 | using ToastifyAPI.Native.Structs; 5 | 6 | // ReSharper disable BuiltInTypeReferenceStyle 7 | namespace ToastifyAPI.Native 8 | { 9 | public static class Shell32 10 | { 11 | [DllImport("shell32.dll", SetLastError = false)] 12 | internal static extern Int32 SHGetStockIconInfo(ShStockIconId siid, ShGSI uFlags, ref ShStockIconInfo psii); 13 | } 14 | } -------------------------------------------------------------------------------- /ToastifyAPI/Spotify.win32.cs: -------------------------------------------------------------------------------- 1 | #if !WIN_10 2 | 3 | using JetBrains.Annotations; 4 | 5 | namespace ToastifyAPI 6 | { 7 | public static partial class Spotify 8 | { 9 | #region Static Members 10 | 11 | [CanBeNull] 12 | private static string GetSpotifyPath_platform() 13 | { 14 | // noop, this is taken care of in the GetSpotifyPath_common() 15 | return null; 16 | } 17 | 18 | #endregion 19 | } 20 | } 21 | 22 | #endif -------------------------------------------------------------------------------- /ToastifyAPI/Native/Structs/CryptProtectPromptStruct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using ToastifyAPI.Native.Enums; 4 | 5 | namespace ToastifyAPI.Native.Structs 6 | { 7 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 8 | public struct CryptProtectPromptStruct 9 | { 10 | public int cbSize; 11 | public CryptProtectPromptFlags dwPromptFlags; 12 | public IntPtr hwndApp; 13 | public string szPrompt; 14 | } 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/ISpotifyWebAPI.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using ToastifyAPI.Core.Auth; 3 | using ToastifyAPI.Model.Interfaces; 4 | 5 | namespace ToastifyAPI.Core 6 | { 7 | public interface ISpotifyWebAPI 8 | { 9 | #region Public Properties 10 | 11 | IToken Token { get; set; } 12 | 13 | #endregion 14 | 15 | Task GetCurrentlyPlayingTrackAsync(); 16 | Task GetUserPrivateProfileAsync(); 17 | } 18 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/MouseAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Converters; 5 | 6 | namespace ToastifyAPI.Core 7 | { 8 | [Serializable] 9 | [JsonConverter(typeof(StringEnumConverter))] 10 | public enum MouseAction 11 | { 12 | MWheelUp = MouseButton.Middle + 120, 13 | MWheelDown = MouseButton.Middle - 120, 14 | XButton1 = MouseButton.XButton1, 15 | XButton2 = MouseButton.XButton2 16 | } 17 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/ISpotifyTrack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ToastifyAPI.Core; 3 | 4 | namespace ToastifyAPI.Model.Interfaces 5 | { 6 | public interface ISpotifyTrack : IEquatable 7 | { 8 | #region Public Properties 9 | 10 | SpotifyTrackType Type { get; } 11 | string Title { get; } 12 | int Length { get; } 13 | 14 | #endregion 15 | 16 | bool IsValid(); 17 | string GetClipboardText(string template); 18 | } 19 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/IMMDeviceCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ToastifyAPI.Native.MMDeviceAPI 4 | { 5 | [Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E")] 6 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 7 | public interface IMMDeviceCollection 8 | { 9 | [PreserveSig] 10 | int GetCount(out int deviceCount); 11 | 12 | [PreserveSig] 13 | int Item(int deviceIndex, [Out] out IMMDevice device); 14 | } 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/ExecutionStateFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | // ReSharper disable InconsistentNaming 4 | namespace ToastifyAPI.Native.Enums 5 | { 6 | [Flags] 7 | public enum ExecutionStateFlags : uint 8 | { 9 | ES_AWAYMODE_REQUIRED = 0x00000040, 10 | ES_CONTINUOUS = 0x80000000, 11 | ES_DISPLAY_REQUIRED = 0x00000002, 12 | ES_SYSTEM_REQUIRED = 0x00000001, 13 | ES_USER_PRESENT = 0x00000004 // Legacy flag, should not be used. 14 | } 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/IAudioSessionManager2.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ToastifyAPI.Native.MMDeviceAPI 4 | { 5 | [Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F")] 6 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 7 | public interface IAudioSessionManager2 8 | { 9 | int NotImpl1(); 10 | 11 | int NotImpl2(); 12 | 13 | [PreserveSig] 14 | int GetSessionEnumerator(out IAudioSessionEnumerator sessionEnum); 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/VirtualKeyCode.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable InconsistentNaming 2 | namespace ToastifyAPI.Native.Enums 3 | { 4 | public enum VirtualKeyCode : byte 5 | { 6 | None = 0x00, 7 | VK_VOLUME_MUTE = 0xAD, 8 | VK_VOLUME_DOWN = 0xAE, 9 | VK_VOLUME_UP = 0xAF, 10 | VK_MEDIA_NEXT_TRACK = 0xB0, 11 | VK_MEDIA_PREV_TRACK = 0xB1, 12 | VK_MEDIA_STOP = 0xB2, 13 | VK_MEDIA_PLAY_PAUSE = 0xB3, 14 | } 15 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/NoAuth.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace ToastifyAPI.Core.Auth 4 | { 5 | public class NoAuth : ISpotifyWebAuth 6 | { 7 | public Task GetToken() 8 | { 9 | return Task.FromResult(null); 10 | } 11 | 12 | public Task RefreshToken(IToken token) 13 | { 14 | return Task.FromResult(null); 15 | } 16 | 17 | public void Dispose() 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ToastifyAPI/Interop/Interfaces/IInputDevices.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | 3 | namespace ToastifyAPI.Interop.Interfaces 4 | { 5 | public interface IInputDevices 6 | { 7 | #region Public Properties 8 | 9 | IKeyboard Keyboard { get; set; } 10 | 11 | IMouse Mouse { get; set; } 12 | 13 | #endregion 14 | 15 | bool IsPressed(Key key); 16 | 17 | bool ArePressed(ModifierKeys modifiers); 18 | 19 | bool IsPressed(MouseButton mouseButton); 20 | } 21 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/IToastifyBroadcaster.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using ToastifyAPI.Model.Interfaces; 3 | 4 | namespace ToastifyAPI.Core 5 | { 6 | public interface IToastifyBroadcaster 7 | { 8 | #region Public Properties 9 | 10 | uint Port { get; } 11 | 12 | #endregion 13 | 14 | Task StartAsync(); 15 | Task StopAsync(); 16 | 17 | Task BroadcastCurrentTrack(T track) where T : ISpotifyTrack; 18 | Task BroadcastPlayState(bool playing); 19 | } 20 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/IAudioSessionEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ToastifyAPI.Native.MMDeviceAPI 4 | { 5 | [Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8")] 6 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 7 | public interface IAudioSessionEnumerator 8 | { 9 | [PreserveSig] 10 | int GetCount(out int sessionCount); 11 | 12 | [PreserveSig] 13 | int GetSession(int sessionCount, out IAudioSessionControl2 session); 14 | } 15 | } -------------------------------------------------------------------------------- /Toastify/src/Core/Broadcaster/JsonGreetingsObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Toastify.Core.Broadcaster 5 | { 6 | [Serializable] 7 | [JsonObject(MemberSerialization.OptIn)] 8 | public class JsonGreetingsObject 9 | { 10 | #region Public Properties 11 | 12 | [JsonProperty("track")] 13 | public JsonTrack Track { get; set; } 14 | 15 | [JsonProperty("playing")] 16 | public bool Playing { get; set; } 17 | 18 | #endregion 19 | } 20 | } -------------------------------------------------------------------------------- /ToastifyAPI/Helpers/StringHelpers.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Helpers 2 | { 3 | public static class StringHelpers 4 | { 5 | #region Static Members 6 | 7 | public static string ToLowerCamelCase(this string str) 8 | { 9 | if (string.IsNullOrWhiteSpace(str)) 10 | return str; 11 | if (str.Length == 1) 12 | return str.ToLower(); 13 | return char.ToLower(str[0]) + str.Substring(1); 14 | } 15 | 16 | #endregion 17 | } 18 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/ISong.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using JetBrains.Annotations; 4 | 5 | namespace ToastifyAPI.Model.Interfaces 6 | { 7 | public interface ISong : ISpotifyTrack, IEquatable 8 | { 9 | #region Public Properties 10 | 11 | [NotNull] 12 | string Album { get; } 13 | 14 | [NotNull] 15 | IReadOnlyList Artists { get; } 16 | 17 | ISongAlbumArt AlbumArt { get; set; } 18 | 19 | #endregion 20 | } 21 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Enums/RawInputCommand.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Native.RawInputAPI.Enums 2 | { 3 | /// 4 | /// Enumeration contanining the command types to issue. 5 | /// 6 | public enum RawInputCommand 7 | { 8 | /// 9 | /// Get input data. 10 | /// 11 | Input = 0x10000003, 12 | 13 | /// 14 | /// Get header data. 15 | /// 16 | Header = 0x10000005 17 | } 18 | } -------------------------------------------------------------------------------- /Toastify/src/Core/SpotifyWeb.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Core; 2 | using ToastifyAPI.Core.Auth; 3 | 4 | namespace Toastify.Core 5 | { 6 | public class SpotifyWeb : ISpotifyWeb 7 | { 8 | #region Public Properties 9 | 10 | public ISpotifyWebAuth Auth { get; } 11 | public ISpotifyWebAPI API { get; } 12 | 13 | #endregion 14 | 15 | public SpotifyWeb(ISpotifyWebAuth auth, ISpotifyWebAPI webApi) 16 | { 17 | this.Auth = auth; 18 | this.API = webApi; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ToastifyAPI/Logic/KeyboardHotkeyVisitor.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Logic.Interfaces; 2 | using ToastifyAPI.Model.Interfaces; 3 | 4 | namespace ToastifyAPI.Logic 5 | { 6 | /// 7 | /// Implements the Visitor pattern for the class. 8 | /// 9 | public class KeyboardHotkeyVisitor : IKeyboardHotkeyVisitor 10 | { 11 | /// 12 | public void Visit(IKeyboardHotkey hotkey) 13 | { 14 | hotkey?.PerformAction(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Toastify/src/Core/ToastTitlesOrder.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using Toastify.Common; 4 | 5 | namespace Toastify.Core 6 | { 7 | [JsonConverter(typeof(StringEnumConverter))] 8 | public enum ToastTitlesOrder 9 | { 10 | [ComboBoxItem("Track by Artist", "Show the Artist name below the Track name.")] 11 | TrackByArtist, 12 | 13 | [ComboBoxItem("Artist: \x201CTrack\x201D", "Show The Track name below the Artist name, inside double quotes.")] 14 | ArtistOfTrack 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Events/WindowTitleChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Events 4 | { 5 | public class WindowTitleChangedEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public string OldTitle { get; } 10 | public string NewTitle { get; } 11 | 12 | #endregion 13 | 14 | public WindowTitleChangedEventArgs(string oldTitle, string newTitle) 15 | { 16 | this.OldTitle = oldTitle; 17 | this.NewTitle = newTitle; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /ToastifyAPI/Logic/Interfaces/IMouseHookHotkeyVisitor.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | using ToastifyAPI.Model.Interfaces; 3 | 4 | namespace ToastifyAPI.Logic.Interfaces 5 | { 6 | public interface IMouseHookHotkeyVisitor : IHotkeyVisitor 7 | { 8 | void Visit(IMouseHookHotkey hotkey); 9 | 10 | bool IsRegistered([NotNull] IMouseHookHotkey hotkey); 11 | void RegisterHook([NotNull] IMouseHookHotkey hotkey); 12 | void UnregisterHook([NotNull] IMouseHookHotkey hotkey); 13 | void UnregisterAll(); 14 | } 15 | } -------------------------------------------------------------------------------- /Toastify/src/Events/CheckVersionCompleteEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Events 4 | { 5 | public class CheckVersionCompleteEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public string Version { get; set; } 10 | 11 | public bool IsNew { get; set; } 12 | 13 | public int GitHubReleaseId { get; set; } = -1; 14 | 15 | public string GitHubReleaseUrl { get; set; } 16 | 17 | public string GitHubReleaseDownloadUrl { get; set; } 18 | 19 | #endregion 20 | } 21 | } -------------------------------------------------------------------------------- /Toastify.Test/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Toastify/src/Threading/WindowThreadOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | 4 | namespace Toastify.Threading 5 | { 6 | public class WindowThreadOptions where T : Window, new() 7 | { 8 | #region Public Properties 9 | 10 | public Action WindowInitialization { get; set; } 11 | public Action BeforeWindowShownAction { get; set; } 12 | public Action AfterWindowShownAction { get; set; } 13 | public Action> OnWindowClosingAction { get; set; } 14 | 15 | #endregion 16 | } 17 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Enums/RawKeyboardFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.RawInputAPI.Enums 4 | { 5 | /// 6 | /// Enumeration containing flags for raw keyboard input. 7 | /// 8 | [Flags] 9 | public enum RawKeyboardFlags : ushort 10 | { 11 | KeyMake = 0x00, 12 | KeyBreak = 0x01, 13 | KeyE0 = 0x02, 14 | KeyE1 = 0x04, 15 | TerminalServerSetLED = 0x08, 16 | TerminalServerShadow = 0x10, 17 | TerminalServerVkPacket = 0x20 18 | } 19 | } -------------------------------------------------------------------------------- /Toastify/src/Events/SpotifyWebAPIInitializationFailedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Toastify.Core; 3 | 4 | namespace Toastify.Events 5 | { 6 | public class SpotifyWebAPIInitializationFailedEventArgs : EventArgs 7 | { 8 | #region Public Properties 9 | 10 | public SpotifyWebAPIInitializationFailedReason Reason { get; } 11 | 12 | #endregion 13 | 14 | public SpotifyWebAPIInitializationFailedEventArgs(SpotifyWebAPIInitializationFailedReason reason) 15 | { 16 | this.Reason = reason; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/ILockedGlobalHotkey.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace ToastifyAPI.Model.Interfaces 4 | { 5 | /// 6 | /// A global hotkey that can't be modified. 7 | /// 8 | public interface ILockedGlobalHotkey 9 | { 10 | #region Public Properties 11 | 12 | bool Enabled { get; } 13 | Keys KeyCode { get; } 14 | bool Ctrl { get; } 15 | bool Alt { get; } 16 | bool Shift { get; } 17 | bool WindowsKey { get; } 18 | 19 | #endregion 20 | } 21 | } -------------------------------------------------------------------------------- /Toastify/src/Events/SpotifyVolumeChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Events 4 | { 5 | public class SpotifyVolumeChangedEventArgs : EventArgs 6 | { 7 | #region Public Properties 8 | 9 | public double PreviousVolume { get; } 10 | public double NewVolume { get; } 11 | 12 | #endregion 13 | 14 | public SpotifyVolumeChangedEventArgs(double previousVolume, double newVolume) 15 | { 16 | this.PreviousVolume = previousVolume; 17 | this.NewVolume = newVolume; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /ToastifyAPI/Events/SpotifyTokenChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ToastifyAPI.Core.Auth; 3 | 4 | namespace ToastifyAPI.Events 5 | { 6 | public class SpotifyTokenChangedEventArgs : EventArgs 7 | { 8 | #region Public Properties 9 | 10 | public IToken OldToken { get; } 11 | public IToken NewToken { get; } 12 | 13 | #endregion 14 | 15 | public SpotifyTokenChangedEventArgs(IToken oldToken, IToken newToken) 16 | { 17 | this.OldToken = oldToken; 18 | this.NewToken = newToken; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/ShGSI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | // ReSharper disable InconsistentNaming 4 | namespace ToastifyAPI.Native.Enums 5 | { 6 | [Flags] 7 | public enum ShGSI : uint 8 | { 9 | SHGSI_ICONLOCATION = 0, 10 | SHGSI_ICON = 0x000000100, 11 | SHGSI_SYSICONINDEX = 0x000004000, 12 | SHGSI_LINKOVERLAY = 0x000008000, 13 | SHGSI_SELECTED = 0x000010000, 14 | SHGSI_LARGEICON = 0x000000000, 15 | SHGSI_SMALLICON = 0x000000001, 16 | SHGSI_SHELLICONSIZE = 0x000000004 17 | } 18 | } -------------------------------------------------------------------------------- /Toastify/src/Events/HotkeyActionCallbackFailedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Toastify.Model; 3 | 4 | namespace Toastify.Events 5 | { 6 | public class HotkeyActionCallbackFailedEventArgs : EventArgs 7 | { 8 | #region Public Properties 9 | 10 | public Hotkey Hotkey { get; } 11 | 12 | public Exception Exception { get; } 13 | 14 | #endregion 15 | 16 | public HotkeyActionCallbackFailedEventArgs(Hotkey hotkey, Exception exception) 17 | { 18 | this.Hotkey = hotkey; 19 | this.Exception = exception; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Toastify/src/Helpers/AutomationHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Windows.Automation; 3 | 4 | namespace Toastify.Helpers 5 | { 6 | public static class AutomationHelper 7 | { 8 | #region Static Members 9 | 10 | public static AutomationPattern GetSpecifiedPattern(AutomationElement element, string patternName) 11 | { 12 | AutomationPattern[] supportedPattern = element.GetSupportedPatterns(); 13 | return supportedPattern.FirstOrDefault(pattern => pattern.ProgrammaticName == patternName); 14 | } 15 | 16 | #endregion 17 | } 18 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/IAuthHttpServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace ToastifyAPI.Core.Auth 5 | { 6 | /// 7 | /// Interface for an HTTP server that should listen for the response of the /authorize endpoint of Spotify's Account service 8 | /// 9 | public interface IAuthHttpServer 10 | { 11 | #region Events 12 | 13 | event EventHandler AuthorizationFinished; 14 | 15 | #endregion 16 | 17 | int Port { get; } 18 | 19 | Task Start(); 20 | Task Stop(); 21 | } 22 | } -------------------------------------------------------------------------------- /Toastify/src/Threading/IWindowThread.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Threading; 3 | 4 | namespace Toastify.Threading 5 | { 6 | public interface IWindowThread : IDisposable 7 | { 8 | #region Public Properties 9 | 10 | bool IsBackground { get; } 11 | string ThreadName { get; } 12 | Dispatcher Dispatcher { get; } 13 | 14 | #endregion 15 | 16 | void Start(); 17 | void Abort(); 18 | void Join(); 19 | void Join(TimeSpan timeout); 20 | void Join(int millisecondsTimeout); 21 | 22 | void CloseWindow(); 23 | } 24 | } -------------------------------------------------------------------------------- /ToastifyAPI/Helpers/ITokenExtensions.cs: -------------------------------------------------------------------------------- 1 | using ToastifyAPI.Core.Auth; 2 | 3 | namespace ToastifyAPI.Helpers 4 | { 5 | // ReSharper disable once InconsistentNaming 6 | public static class ITokenExtensions 7 | { 8 | #region Static Members 9 | 10 | public static string GetExpirationInfo(this IToken token) 11 | { 12 | return token != null 13 | ? $"{{ {nameof(IToken.CreateDate)}: \"{token.CreateDate:yyyy/MM/dd HH:mm:ss.fffK}\", {nameof(IToken.ExpiresIn)}: {token.ExpiresIn} }}" 14 | : null; 15 | } 16 | 17 | #endregion 18 | } 19 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/IAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | using ToastifyAPI.Events; 4 | 5 | namespace ToastifyAPI.Model.Interfaces 6 | { 7 | public interface IAction : IEquatable, ICloneable 8 | { 9 | #region Public Properties 10 | 11 | [NotNull] 12 | string Name { get; } 13 | 14 | #endregion 15 | 16 | #region Events 17 | 18 | event EventHandler ActionPerformed; 19 | 20 | event EventHandler ActionFailed; 21 | 22 | #endregion 23 | 24 | void PerformAction(); 25 | } 26 | } -------------------------------------------------------------------------------- /ToastifyAPI/Spotify.uwp.cs: -------------------------------------------------------------------------------- 1 | #if WIN_10 2 | 3 | using Windows.ApplicationModel; 4 | using JetBrains.Annotations; 5 | 6 | namespace ToastifyAPI 7 | { 8 | public static partial class Spotify 9 | { 10 | #region Static Members 11 | 12 | [CanBeNull] 13 | private static string GetSpotifyPath_platform() 14 | { 15 | Package spotifyPackage = Win32API.FindPackage("SpotifyAB.SpotifyMusic"); 16 | return spotifyPackage != null ? $@"shell:AppsFolder\{spotifyPackage.Id.FamilyName}!Spotify" : null; 17 | } 18 | 19 | #endregion 20 | } 21 | } 22 | 23 | #endif -------------------------------------------------------------------------------- /Toastify/src/Core/UpdateDeliveryMode.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using Toastify.Common; 4 | 5 | namespace Toastify.Core 6 | { 7 | [JsonConverter(typeof(StringEnumConverter))] 8 | public enum UpdateDeliveryMode 9 | { 10 | [ComboBoxItem("Notify only", "A toast will be displayed when a new version is available, but it won't be downloaded")] 11 | NotifyUpdate, 12 | 13 | [ComboBoxItem("Download automatically", "The new version will be downloaded automatically; the user is notified when the update is ready to be installed")] 14 | AutoDownload 15 | } 16 | } -------------------------------------------------------------------------------- /Toastify/src/Events/SpotifyTrackChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ToastifyAPI.Model.Interfaces; 3 | 4 | namespace Toastify.Events 5 | { 6 | public class SpotifyTrackChangedEventArgs : EventArgs 7 | { 8 | #region Public Properties 9 | 10 | public ISpotifyTrack PreviousTrack { get; } 11 | public ISpotifyTrack NewTrack { get; } 12 | 13 | #endregion 14 | 15 | public SpotifyTrackChangedEventArgs(ISpotifyTrack previousTrack, ISpotifyTrack newTrack) 16 | { 17 | this.PreviousTrack = previousTrack; 18 | this.NewTrack = newTrack; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/IProxyConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace ToastifyAPI.Core 5 | { 6 | public interface IProxyConfig : ICloneable 7 | { 8 | #region Public Properties 9 | 10 | string Host { get; } 11 | 12 | int Port { get; } 13 | 14 | bool UseDefaultCredentials { get; } 15 | 16 | /// 17 | /// Whether to bypass the proxy server for local addresses. 18 | /// 19 | bool BypassProxyOnLocal { get; } 20 | 21 | #endregion 22 | 23 | bool IsValid(); 24 | 25 | IWebProxy CreateWebProxy(); 26 | } 27 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/ToastifyWebAuthAPI/ClientCredentialsFlow.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using ToastifyAPI.Core.Auth.ToastifyWebAuthAPI.Structs; 3 | 4 | namespace ToastifyAPI.Core.Auth.ToastifyWebAuthAPI 5 | { 6 | public static class ClientCredentialsFlow 7 | { 8 | #region Static Members 9 | 10 | [DllImport("ToastifyWebAuthAPI.dll", CallingConvention = CallingConvention.Cdecl)] 11 | public static extern void GetClientCredentialsToken( 12 | [In, Out] ref HttpResponse response, 13 | [In, Out] ref SpotifyTokenResponse tokenResponse); 14 | 15 | #endregion 16 | } 17 | } -------------------------------------------------------------------------------- /Toastify/src/Events/CurrentSettingsChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Toastify.Model; 3 | 4 | namespace Toastify.Events 5 | { 6 | public class CurrentSettingsChangedEventArgs : EventArgs 7 | { 8 | #region Public Properties 9 | 10 | public Settings PreviousSettings { get; } 11 | public Settings CurrentSettings { get; } 12 | 13 | #endregion 14 | 15 | public CurrentSettingsChangedEventArgs(Settings previousSettings, Settings currentSettings) 16 | { 17 | this.PreviousSettings = previousSettings; 18 | this.CurrentSettings = currentSettings; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/IMMDevice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace ToastifyAPI.Native.MMDeviceAPI 5 | { 6 | [Guid("D666063F-1587-4E43-81F1-B948E807363F")] 7 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 8 | public interface IMMDevice 9 | { 10 | [PreserveSig] 11 | int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); 12 | 13 | int OpenPropertyStore_NotImpl(); 14 | 15 | [PreserveSig] 16 | int GetId([MarshalAs(UnmanagedType.LPWStr)] out string ppstrId); 17 | } 18 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/IMMDeviceEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using ToastifyAPI.Native.MMDeviceAPI.Enums; 3 | 4 | namespace ToastifyAPI.Native.MMDeviceAPI 5 | { 6 | [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")] 7 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 8 | public interface IMMDeviceEnumerator 9 | { 10 | [PreserveSig] 11 | int EnumAudioEndpoints(EDataFlow dataFlow, EDeviceState stateMask, [Out] out IMMDeviceCollection deviceCollection); 12 | 13 | [PreserveSig] 14 | int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice); 15 | } 16 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Structs/WindowPlacement.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using ToastifyAPI.Native.Enums; 3 | 4 | namespace ToastifyAPI.Native.Structs 5 | { 6 | public struct WindowPlacement 7 | { 8 | public int length; 9 | public int flags; 10 | public ShowWindowCmd showCmd; 11 | public Point ptMinPosition; 12 | public Point ptMaxPosition; 13 | public Rectangle rcNormalPosition; 14 | 15 | public override string ToString() 16 | { 17 | return $"{this.length},{this.flags},{this.showCmd},{this.ptMinPosition},{this.ptMaxPosition},{this.rcNormalPosition}"; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /ToastifyAPI.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ToastifyAPI/Native/Structs/Rect.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ToastifyAPI.Native.Structs 4 | { 5 | [StructLayout(LayoutKind.Sequential)] 6 | public struct Rect 7 | { 8 | public int left; 9 | public int top; 10 | public int right; 11 | public int bottom; 12 | 13 | public int Width { get { return this.right - this.left; } } 14 | 15 | public int Height { get { return this.bottom - this.top; } } 16 | 17 | public override string ToString() 18 | { 19 | return $"{{X={this.left},Y={this.top},Width={this.Width},Height={this.Height}}}"; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Toastify/src/Events/SettingsViewLaunchedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Toastify.Model; 3 | using Toastify.ViewModel; 4 | 5 | namespace Toastify.Events 6 | { 7 | public class SettingsViewLaunchedEventArgs : EventArgs 8 | { 9 | #region Public Properties 10 | 11 | public Settings Settings { get; set; } 12 | public ISettingsViewModel SettingsViewModel { get; set; } 13 | 14 | #endregion 15 | 16 | public SettingsViewLaunchedEventArgs(Settings settings, ISettingsViewModel settingsViewModel) 17 | { 18 | this.Settings = settings; 19 | this.SettingsViewModel = settingsViewModel; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Toastify.Test/Helpers/WindsorContainerExtensionsTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Toastify.Helpers; 3 | using Toastify.Tests.WindsorTestsData; 4 | 5 | namespace Toastify.Tests.Helpers 6 | { 7 | [TestFixture, TestOf(typeof(WindsorContainerExtensions))] 8 | public class WindsorContainerExtensionsTest 9 | { 10 | [Test(Author = "aleab")] 11 | public static void BuildUpTest() 12 | { 13 | DependencyBase objWithDependencies = new DependecyWithDependencies(); 14 | WindsorContainerData.Container.BuildUp(objWithDependencies); 15 | 16 | Assert.That(objWithDependencies.DependenciesInjected()); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Toastify.Test/WindsorTestsData/DependencyBase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | using Toastify.DI; 5 | 6 | namespace Toastify.Tests.WindsorTestsData 7 | { 8 | internal abstract class DependencyBase 9 | { 10 | public bool DependenciesInjected() 11 | { 12 | IEnumerable properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) 13 | .Where(p => p.GetCustomAttribute() != null); 14 | return properties.All(p => p.GetValue(this) != null); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Toastify/src/Events/SettingsSavedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Toastify.Model; 4 | 5 | namespace Toastify.Events 6 | { 7 | public class SettingsSavedEventArgs : EventArgs 8 | { 9 | #region Public Properties 10 | 11 | public Settings Settings { get; set; } 12 | public IReadOnlyList PreviewHotkeys { get; set; } 13 | 14 | #endregion 15 | 16 | public SettingsSavedEventArgs(Settings settings, IReadOnlyList previewHotkeys) 17 | { 18 | this.Settings = settings; 19 | this.PreviewHotkeys = previewHotkeys; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/MMDeviceAPI/ISimpleAudioVolume.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace ToastifyAPI.Native.MMDeviceAPI 5 | { 6 | [Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8")] 7 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 8 | public interface ISimpleAudioVolume 9 | { 10 | [PreserveSig] 11 | int SetMasterVolume(float fLevel, ref Guid eventContext); 12 | 13 | [PreserveSig] 14 | int GetMasterVolume(out float pfLevel); 15 | 16 | [PreserveSig] 17 | int SetMute(bool bMute, ref Guid eventContext); 18 | 19 | [PreserveSig] 20 | int GetMute(out bool pbMute); 21 | } 22 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/IGlobalHotkey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ToastifyAPI.Model.Interfaces 5 | { 6 | /// 7 | /// A global hotkey. 8 | /// 9 | public interface IGlobalHotkey 10 | { 11 | #region Public Properties 12 | 13 | bool Enabled { get; set; } 14 | Keys KeyCode { get; set; } 15 | bool Ctrl { get; set; } 16 | bool Alt { get; set; } 17 | bool Shift { get; set; } 18 | bool WindowsKey { get; set; } 19 | 20 | #endregion 21 | 22 | #region Events 23 | 24 | event EventHandler HotkeyPressed; 25 | 26 | #endregion 27 | } 28 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/AuthEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Core.Auth 4 | { 5 | /// 6 | /// Response of the /authorize endpoint of Spotify's Accounts service 7 | /// 8 | public class AuthEventArgs : EventArgs 9 | { 10 | #region Public Properties 11 | 12 | public string Code { get; } 13 | public string State { get; } 14 | public string Error { get; } 15 | 16 | #endregion 17 | 18 | public AuthEventArgs(string code, string state, string error) 19 | { 20 | this.Code = code; 21 | this.State = state; 22 | this.Error = error; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Toastify.Test/WindsorTestsData/WindsorContainerData.cs: -------------------------------------------------------------------------------- 1 | using Castle.MicroKernel.Registration; 2 | using Castle.Windsor; 3 | 4 | namespace Toastify.Tests.WindsorTestsData 5 | { 6 | internal static class WindsorContainerData 7 | { 8 | public static WindsorContainer Container 9 | { 10 | get 11 | { 12 | var container = new WindsorContainer(); 13 | container.Register( 14 | Component.For().ImplementedBy(), 15 | Component.For().ImplementedBy()); 16 | return container; 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/HookType.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable InconsistentNaming 2 | namespace ToastifyAPI.Native.Enums 3 | { 4 | public enum HookType 5 | { 6 | WH_JOURNALRECORD = 0, 7 | WH_JOURNALPLAYBACK = 1, 8 | WH_KEYBOARD = 2, 9 | WH_GETMESSAGE = 3, 10 | WH_CALLWNDPROC = 4, 11 | WH_CBT = 5, 12 | WH_SYSMSGFILTER = 6, 13 | WH_MOUSE = 7, 14 | WH_HARDWARE = 8, 15 | WH_DEBUG = 9, 16 | WH_SHELL = 10, 17 | WH_FOREGROUNDIDLE = 11, 18 | WH_CALLWNDPROCRET = 12, 19 | WH_KEYBOARD_LL = 13, 20 | WH_MOUSE_LL = 14 21 | } 22 | } -------------------------------------------------------------------------------- /Toastify/src/Helpers/Validators/IPPortRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Controls; 4 | 5 | // ReSharper disable BuiltInTypeReferenceStyle 6 | namespace Toastify.Helpers.Validators 7 | { 8 | public class IPPortRule : ValidationRule 9 | { 10 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 11 | { 12 | if (value == null) 13 | return ValidationResult.ValidResult; 14 | 15 | if (UInt16.TryParse((string)value, out UInt16 port) && port > 0) 16 | return ValidationResult.ValidResult; 17 | 18 | return new ValidationResult(false, "Insert a valid IPv4 port number."); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Toastify/src/Common/EnumReadableNameAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Common 4 | { 5 | [AttributeUsage(AttributeTargets.Field)] 6 | public class EnumReadableNameAttribute : Attribute 7 | { 8 | #region Static Fields and Properties 9 | 10 | public static readonly EnumReadableNameAttribute Default = new EnumReadableNameAttribute(); 11 | 12 | #endregion 13 | 14 | #region Public Properties 15 | 16 | public string Name { get; } 17 | 18 | #endregion 19 | 20 | public EnumReadableNameAttribute() : this(null) 21 | { 22 | } 23 | 24 | public EnumReadableNameAttribute(string name) 25 | { 26 | this.Name = name; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ToastifyAPI/Win32API.uwp.cs: -------------------------------------------------------------------------------- 1 | #if WIN_10 2 | 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Windows.ApplicationModel; 6 | using Windows.Management.Deployment; 7 | 8 | namespace ToastifyAPI 9 | { 10 | // ReSharper disable once PartialTypeWithSinglePart 11 | public static partial class Win32API 12 | { 13 | #region Static Members 14 | 15 | internal static Package FindPackage(string name) 16 | { 17 | var packageManager = new PackageManager(); 18 | IEnumerable packages = packageManager.FindPackagesForUser(string.Empty); 19 | return packages.FirstOrDefault(package => package.Id.Name == name); 20 | } 21 | 22 | #endregion 23 | } 24 | } 25 | 26 | #endif -------------------------------------------------------------------------------- /Toastify/src/Helpers/Converters/HexColorToAlphaValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Toastify.Helpers.Converters 6 | { 7 | public class HexColorToAlphaValueConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | string hexColor = (string)value ?? string.Empty; 12 | return byte.Parse(hexColor.Substring(1, 2), NumberStyles.AllowHexSpecifier); 13 | } 14 | 15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Toastify/src/Common/EnumComboBoxItem.cs: -------------------------------------------------------------------------------- 1 | namespace Toastify.Common 2 | { 3 | public class EnumComboBoxItem 4 | { 5 | #region Public Properties 6 | 7 | public object Value { get; set; } 8 | public string Description { get; set; } 9 | public string Tooltip { get; set; } 10 | 11 | #endregion 12 | 13 | public EnumComboBoxItem(object value, string description) : this(value, description, null) 14 | { 15 | } 16 | 17 | public EnumComboBoxItem(object value, string description, string tooltip) 18 | { 19 | this.Value = value; 20 | this.Description = string.IsNullOrWhiteSpace(description) ? value.ToString() : description; 21 | this.Tooltip = tooltip; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Toastify/src/Helpers/Converters/BoolToVisibleConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Toastify.Helpers.Converters 7 | { 8 | public class BoolToVisibleConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | // Note: will throw a cast exception if you throw the wrong type at it. Good :) 13 | return (bool)value ? Visibility.Visible : Visibility.Collapsed; 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Toastify/src/Model/ToastifyExit.cs: -------------------------------------------------------------------------------- 1 | using Toastify.Core; 2 | 3 | namespace Toastify.Model 4 | { 5 | /// 6 | /// Terminates Toastify. 7 | /// 8 | public sealed class ToastifyExit : ToastifyAction 9 | { 10 | #region Public Properties 11 | 12 | /// 13 | public override string Name 14 | { 15 | get { return "Exit"; } 16 | } 17 | 18 | /// 19 | public override ToastifyActionEnum ToastifyActionEnum 20 | { 21 | get { return ToastifyActionEnum.Exit; } 22 | } 23 | 24 | #endregion 25 | 26 | /// 27 | public override void PerformAction() 28 | { 29 | App.Terminate(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ToastifyAPI/Common/AnonymousEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace ToastifyAPI.Common 5 | { 6 | public class AnonymousEqualityComparer : IEqualityComparer 7 | { 8 | private readonly Func equals; 9 | private readonly Func getHashCode; 10 | 11 | public AnonymousEqualityComparer(Func equals, Func getHashCode) 12 | { 13 | this.equals = equals; 14 | this.getHashCode = getHashCode; 15 | } 16 | 17 | public bool Equals(T x, T y) 18 | { 19 | return this.equals(x, y); 20 | } 21 | 22 | public int GetHashCode(T obj) 23 | { 24 | return this.getHashCode(obj); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Enums/RawInputType.cs: -------------------------------------------------------------------------------- 1 | namespace ToastifyAPI.Native.RawInputAPI.Enums 2 | { 3 | /// 4 | /// Enumeration containing the type device the raw input is coming from. 5 | /// 6 | public enum RawInputType 7 | { 8 | /// 9 | /// Mouse input. 10 | /// 11 | Mouse = 0, 12 | 13 | /// 14 | /// Keyboard input. 15 | /// 16 | Keyboard = 1, 17 | 18 | /// 19 | /// Human interface device input. 20 | /// 21 | HID = 2, 22 | 23 | /// 24 | /// Another device that is not the keyboard or the mouse. 25 | /// 26 | Other = 3 27 | } 28 | } -------------------------------------------------------------------------------- /Toastify/src/Helpers/Converters/OppositeBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Toastify.Helpers.Converters 6 | { 7 | public class OppositeBoolConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | // Note: don't check validity etc, since we'll need to throw an exception anyway, may as well let 12 | // that exception be here and not waste time :) 13 | return !(bool)value; 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Toastify/src/Helpers/Converters/OppositeBoolToVisibleConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Toastify.Helpers.Converters 7 | { 8 | public class OppositeBoolToVisibleConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | // Note: will throw a cast exception if you throw the wrong type at it. Good :) 13 | return !(bool)value ? Visibility.Visible : Visibility.Collapsed; 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Toastify/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Toastify/src/Events/SpotifyStateEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Toastify.Model; 3 | using ToastifyAPI.Model.Interfaces; 4 | 5 | namespace Toastify.Events 6 | { 7 | public class SpotifyStateEventArgs : EventArgs 8 | { 9 | #region Public Properties 10 | 11 | public ISpotifyTrack CurrentTrack { get; } 12 | public bool Playing { get; } 13 | public double TrackTime { get; } 14 | public double Volume { get; } 15 | 16 | #endregion 17 | 18 | public SpotifyStateEventArgs(ISpotifyTrack currentTrack, bool playing, double trackTime, double volume) 19 | { 20 | this.CurrentTrack = currentTrack; 21 | this.Playing = playing; 22 | this.TrackTime = trackTime; 23 | this.Volume = volume; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Toastify.Test/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Structs/RawInputData.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace ToastifyAPI.Native.RawInputAPI.Structs 4 | { 5 | /// 6 | /// Value type for a raw input data. 7 | /// 8 | [StructLayout(LayoutKind.Explicit)] 9 | public struct RawInputData 10 | { 11 | /// 12 | /// Mouse raw input data. 13 | /// 14 | [FieldOffset(0)] 15 | public RawMouse Mouse; 16 | 17 | /// 18 | /// Keyboard raw input data. 19 | /// 20 | [FieldOffset(0)] 21 | public RawKeyboard Keyboard; 22 | 23 | /// 24 | /// HID raw input data. 25 | /// 26 | [FieldOffset(0)] 27 | public RawHID HID; 28 | } 29 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/ITokenManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using ToastifyAPI.Events; 4 | 5 | namespace ToastifyAPI.Core.Auth 6 | { 7 | public interface ITokenManager : IDisposable 8 | { 9 | #region Public Properties 10 | 11 | IToken Token { get; } 12 | ManualResetEvent RefreshingTokenEvent { get; } 13 | 14 | #endregion 15 | 16 | #region Events 17 | 18 | event EventHandler TokenChanged; 19 | 20 | event EventHandler TokenReleased; 21 | 22 | event EventHandler TokenNull; 23 | 24 | #endregion 25 | 26 | bool BeginGetToken(CancellationToken cancellationToken); 27 | bool BeginGetToken(CancellationToken cancellationToken, Action callback); 28 | 29 | void ReleaseToken(); 30 | } 31 | } -------------------------------------------------------------------------------- /Toastify/src/Model/ToastifyShowDebugView.cs: -------------------------------------------------------------------------------- 1 | #if DEBUG 2 | 3 | using Toastify.Core; 4 | using Toastify.View; 5 | 6 | namespace Toastify.Model 7 | { 8 | public sealed class ToastifyShowDebugView : ToastifyAction 9 | { 10 | #region Public Properties 11 | 12 | /// 13 | public override string Name 14 | { 15 | get { return "Show DebugView"; } 16 | } 17 | 18 | /// 19 | public override ToastifyActionEnum ToastifyActionEnum 20 | { 21 | get { return ToastifyActionEnum.ShowDebugView; } 22 | } 23 | 24 | #endregion 25 | 26 | /// 27 | public override void PerformAction() 28 | { 29 | if (DebugView.Current == null) 30 | DebugView.Launch(); 31 | } 32 | } 33 | } 34 | 35 | #endif -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/ResourceType.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable InconsistentNaming 2 | namespace ToastifyAPI.Native.Enums 3 | { 4 | public enum ResourceType 5 | { 6 | RT_CURSOR = 1, 7 | RT_BITMAP = 2, 8 | RT_ICON = 3, 9 | RT_MENU = 4, 10 | RT_DIALOG = 5, 11 | RT_STRING = 6, 12 | RT_FONTDIR = 7, 13 | RT_FONT = 8, 14 | RT_ACCELERATOR = 9, 15 | RT_RCDATA = 10, 16 | RT_MESSAGETABLE = 11, 17 | RT_GROUP_CURSOR = 12, 18 | RT_GROUP_ICON = 14, 19 | RT_VERSION = 16, 20 | RT_DLGINCLUDE = 17, 21 | RT_PLUGPLAY = 19, 22 | RT_VXD = 20, 23 | RT_ANICURSOR = 21, 24 | RT_ANIICON = 22, 25 | RT_HTML = 23, 26 | RT_MANIFEST = 24 27 | } 28 | } -------------------------------------------------------------------------------- /ToastifyAPI/GitHub/Model/Emoji.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using System.Text.RegularExpressions; 3 | using JetBrains.Annotations; 4 | 5 | namespace ToastifyAPI.GitHub.Model 6 | { 7 | public class Emoji 8 | { 9 | #region Public Properties 10 | 11 | public string Name { get; set; } 12 | 13 | public string Url { get; set; } 14 | 15 | #endregion 16 | 17 | [NotNull] 18 | public string GetAsUnicodeString() 19 | { 20 | if (string.IsNullOrWhiteSpace(this.Url)) 21 | return string.Empty; 22 | 23 | string codepoint = Regex.Replace(this.Url, @"^.*emoji/unicode/([a-fA-F0-9]+)\.png.*$", "$1", RegexOptions.Compiled); 24 | return int.TryParse(codepoint, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int code) ? char.ConvertFromUtf32(code) : string.Empty; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Enums/RawMouseFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ToastifyAPI.Native.RawInputAPI.Enums 4 | { 5 | /// 6 | /// Enumeration containing the flags for raw mouse data. 7 | /// 8 | [Flags] 9 | public enum RawMouseFlags : ushort 10 | { 11 | /// 12 | /// Relative to the last position. 13 | /// 14 | MoveRelative = 0, 15 | 16 | /// 17 | /// Absolute positioning. 18 | /// 19 | MoveAbsolute = 1, 20 | 21 | /// 22 | /// Coordinate data is mapped to a virtual desktop. 23 | /// 24 | VirtualDesktop = 2, 25 | 26 | /// 27 | /// Attributes for the mouse have changed. 28 | /// 29 | AttributesChanged = 4 30 | } 31 | } -------------------------------------------------------------------------------- /ToastifyAPI.Tests/Logic/KeyboardHotkeyVisitorTest.cs: -------------------------------------------------------------------------------- 1 | using FakeItEasy; 2 | using NUnit.Framework; 3 | using ToastifyAPI.Logic; 4 | using ToastifyAPI.Model.Interfaces; 5 | 6 | namespace ToastifyAPI.Tests.Logic 7 | { 8 | [TestFixture, TestOf(typeof(KeyboardHotkeyVisitor))] 9 | public class KeyboardHotkeyVisitorTest 10 | { 11 | private KeyboardHotkeyVisitor visitor; 12 | private IKeyboardHotkey fakeHotkey; 13 | 14 | [SetUp] 15 | public void SetUp() 16 | { 17 | this.visitor = new KeyboardHotkeyVisitor(); 18 | this.fakeHotkey = A.Fake(); 19 | } 20 | 21 | [Test(Author = "aleab")] 22 | public void TestVisit() 23 | { 24 | this.visitor.Visit(this.fakeHotkey); 25 | A.CallTo(() => this.fakeHotkey.PerformAction()).MustHaveHappenedOnceExactly(); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Toastify/src/Model/ToastifySimpleMediaAction.cs: -------------------------------------------------------------------------------- 1 | using Toastify.Core; 2 | using ToastifyAPI.Native.Enums; 3 | 4 | namespace Toastify.Model 5 | { 6 | /// 7 | /// Simple concrete implementation of . 8 | /// 9 | public class ToastifySimpleMediaAction : ToastifyMediaAction 10 | { 11 | public ToastifySimpleMediaAction(string name, ToastifyActionEnum actionEnum, long appCommandCode) : base(name, actionEnum, appCommandCode) 12 | { 13 | } 14 | 15 | public ToastifySimpleMediaAction(string name, ToastifyActionEnum actionEnum, long appCommandCode, VirtualKeyCode virtualKeyCode) : base(name, actionEnum, appCommandCode, virtualKeyCode) 16 | { 17 | } 18 | 19 | /// 20 | public override void PerformAction() 21 | { 22 | this.PerformMediaAction(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Toastify/src/Helpers/Converters/SettingValueToOppositeBoolValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using Toastify.Model; 5 | 6 | namespace Toastify.Helpers.Converters 7 | { 8 | public class SettingValueToOppositeBoolValueConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | try 13 | { 14 | return !((SettingValue)value)?.Value; 15 | } 16 | catch 17 | { 18 | dynamic dynamicValue = value; 19 | return !dynamicValue?.Value; 20 | } 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | return new SettingValue(!(bool)(value ?? false)); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Toastify/src/Model/ToastifyNoAction.cs: -------------------------------------------------------------------------------- 1 | using Toastify.Core; 2 | 3 | namespace Toastify.Model 4 | { 5 | /// 6 | /// Void action 7 | /// 8 | public sealed class ToastifyNoAction : ToastifyAction 9 | { 10 | #region Static Fields and Properties 11 | 12 | public static readonly string ActionName = "No Action"; 13 | 14 | #endregion 15 | 16 | #region Public Properties 17 | 18 | /// 19 | public override string Name 20 | { 21 | get { return ActionName; } 22 | } 23 | 24 | /// 25 | public override ToastifyActionEnum ToastifyActionEnum 26 | { 27 | get { return ToastifyActionEnum.None; } 28 | } 29 | 30 | #endregion 31 | 32 | /// 33 | public override void PerformAction() 34 | { 35 | // No action 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Toastify/src/Common/ComboBoxItemAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Toastify.Common 4 | { 5 | [AttributeUsage(AttributeTargets.Field)] 6 | public class ComboBoxItemAttribute : Attribute 7 | { 8 | #region Static Fields and Properties 9 | 10 | public static readonly ComboBoxItemAttribute Default = new ComboBoxItemAttribute(); 11 | 12 | #endregion 13 | 14 | #region Public Properties 15 | 16 | public string Content { get; } 17 | 18 | public string Tooltip { get; } 19 | 20 | #endregion 21 | 22 | public ComboBoxItemAttribute() : this(null) 23 | { 24 | } 25 | 26 | public ComboBoxItemAttribute(string content) : this(content, null) 27 | { 28 | } 29 | 30 | public ComboBoxItemAttribute(string content, string tooltip) 31 | { 32 | this.Content = content; 33 | this.Tooltip = tooltip; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Toastify.Test/Model/ToastifyActions/ToastifyNoActionTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Toastify.Core; 3 | using Toastify.Model; 4 | 5 | namespace Toastify.Tests.Model.ToastifyActions 6 | { 7 | [TestFixture, TestOf(typeof(ToastifyNoAction))] 8 | public class ToastifyNoActionTest 9 | { 10 | [Test(Author = "aleab")] 11 | public static void TestState() 12 | { 13 | var action = new ToastifyNoAction(); 14 | Assert.Multiple(() => 15 | { 16 | Assert.That(action.Name, Is.EqualTo(ToastifyNoAction.ActionName)); 17 | Assert.That(action.ToastifyActionEnum, Is.EqualTo(ToastifyActionEnum.None)); 18 | }); 19 | } 20 | 21 | [Test(Author = "aleab")] 22 | public static void TestPerformAction() 23 | { 24 | var action = new ToastifyNoAction(); 25 | Assert.DoesNotThrow(() => action.PerformAction()); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Structs/RawInputHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using ToastifyAPI.Native.RawInputAPI.Enums; 4 | 5 | namespace ToastifyAPI.Native.RawInputAPI.Structs 6 | { 7 | /// 8 | /// Value type for a raw input header. 9 | /// 10 | [StructLayout(LayoutKind.Sequential)] 11 | public struct RawInputHeader 12 | { 13 | /// 14 | /// Type of device the input is coming from. 15 | /// 16 | public RawInputType Type; 17 | 18 | /// 19 | /// Size of the packet of data. 20 | /// 21 | public int Size; 22 | 23 | /// 24 | /// Handle to the device sending the data. 25 | /// 26 | public IntPtr Device; 27 | 28 | /// 29 | /// wParam from the window message. 30 | /// 31 | public IntPtr wParam; 32 | } 33 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/ToastifyWebAuthAPI/Structs/HttpResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Text; 3 | 4 | namespace ToastifyAPI.Core.Auth.ToastifyWebAuthAPI.Structs 5 | { 6 | [StructLayout(LayoutKind.Sequential)] 7 | public struct HttpResponse 8 | { 9 | public int status; 10 | 11 | [MarshalAs(UnmanagedType.LPStr)] 12 | public string error; 13 | 14 | [MarshalAs(UnmanagedType.LPStr)] 15 | public string body; 16 | 17 | public int maxErrorLength; 18 | public int maxBodyLength; 19 | 20 | public HttpResponse(int maxErrorLength, int maxBodyLength) 21 | { 22 | this.status = 0; 23 | this.error = new StringBuilder(maxErrorLength).Append((char)0, maxErrorLength).ToString(); 24 | this.body = new StringBuilder(maxBodyLength).Append((char)0, maxBodyLength).ToString(); 25 | this.maxErrorLength = maxErrorLength; 26 | this.maxBodyLength = maxBodyLength; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/Interfaces/IHotkey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | using ToastifyAPI.Interop.Interfaces; 4 | using ToastifyAPI.Logic.Interfaces; 5 | 6 | namespace ToastifyAPI.Model.Interfaces 7 | { 8 | /// 9 | /// Defines a hotkey that can perform an action and provides methods to check its internal validity, to check if the required keyboard modifiers are 10 | /// pressed and to activate or deactivate the hotkey itself. 11 | /// 12 | public interface IHotkey : IActionable, ICloneable, IDisposable 13 | { 14 | #region Public Properties 15 | 16 | IInputDevices InputDevices { get; set; } 17 | 18 | bool Enabled { get; set; } 19 | bool Active { get; } 20 | ModifierKeys Modifiers { get; set; } 21 | 22 | #endregion 23 | 24 | bool IsValid(); 25 | 26 | bool AreModifiersPressed(); 27 | 28 | void Activate(); 29 | 30 | void Deactivate(); 31 | 32 | void Dispatch(IHotkeyVisitor visitor); 33 | } 34 | } -------------------------------------------------------------------------------- /Toastify/src/Model/ToastifyShowSpotify.cs: -------------------------------------------------------------------------------- 1 | using Toastify.Core; 2 | 3 | namespace Toastify.Model 4 | { 5 | /// 6 | /// This action shows or minimizes Spotify's main window. 7 | /// 8 | public sealed class ToastifyShowSpotify : ToastifyAction 9 | { 10 | #region Public Properties 11 | 12 | /// 13 | public override string Name 14 | { 15 | get { return "Show Spotify"; } 16 | } 17 | 18 | /// 19 | public override ToastifyActionEnum ToastifyActionEnum 20 | { 21 | get { return ToastifyActionEnum.ShowSpotify; } 22 | } 23 | 24 | #endregion 25 | 26 | /// 27 | public override void PerformAction() 28 | { 29 | if (Spotify.Instance.IsMinimized) 30 | Spotify.Instance.ShowSpotify(); 31 | else 32 | Spotify.Instance.Minimize(); 33 | 34 | this.RaiseActionPerformed(this); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Toastify/src/Model/JsonConverterContractResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json.Serialization; 3 | 4 | namespace Toastify.Model 5 | { 6 | /// 7 | /// Default JSON contract resolver used by the application. 8 | /// Converters for special classes should be set here. 9 | /// 10 | public class JsonConverterContractResolver : DefaultContractResolver 11 | { 12 | #region Static Fields and Properties 13 | 14 | internal static readonly IContractResolver Instance = new JsonConverterContractResolver(); 15 | 16 | #endregion 17 | 18 | protected override JsonContract CreateContract(Type objectType) 19 | { 20 | JsonContract contract = base.CreateContract(objectType); 21 | 22 | if (typeof(ToastifyAction).IsAssignableFrom(objectType)) // Serialize ToastifyAction objects only as a ToastifyActionEnum value 23 | contract.Converter = new ToastifyActionAsEnumJsonConverter(); 24 | 25 | return contract; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Structs/DataBlob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace ToastifyAPI.Native.Structs 5 | { 6 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 7 | public struct DataBlob : IEquatable 8 | { 9 | public int cbData; 10 | public IntPtr pbData; 11 | 12 | /// 13 | public bool Equals(DataBlob other) 14 | { 15 | return this.cbData == other.cbData && 16 | this.pbData.Equals(other.pbData); 17 | } 18 | 19 | /// 20 | public override bool Equals(object obj) 21 | { 22 | if (obj is null) 23 | return false; 24 | 25 | return obj is DataBlob blob && this.Equals(blob); 26 | } 27 | 28 | /// 29 | public override int GetHashCode() 30 | { 31 | unchecked 32 | { 33 | return (this.cbData * 397) ^ this.pbData.GetHashCode(); 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/Enums/SysCommands.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable InconsistentNaming 2 | namespace ToastifyAPI.Native.Enums 3 | { 4 | public enum SysCommands : uint 5 | { 6 | SC_SIZE = 0xF000, 7 | SC_MOVE = 0xF010, 8 | SC_MINIMIZE = 0xF020, 9 | SC_MAXIMIZE = 0xF030, 10 | SC_NEXTWINDOW = 0xF040, 11 | SC_PREVWINDOW = 0xF050, 12 | SC_CLOSE = 0xF060, 13 | SC_VSCROLL = 0xF070, 14 | SC_HSCROLL = 0xF080, 15 | SC_MOUSEMENU = 0xF090, 16 | SC_KEYMENU = 0xF100, 17 | SC_ARRANGE = 0xF110, 18 | SC_RESTORE = 0xF120, 19 | SC_TASKLIST = 0xF130, 20 | SC_SCREENSAVE = 0xF140, 21 | SC_HOTKEY = 0xF150, 22 | SC_DEFAULT = 0xF160, 23 | SC_MONITORPOWER = 0xF170, 24 | SC_CONTEXTHELP = 0xF180, 25 | SC_SEPARATOR = 0xF00F, 26 | 27 | SCF_ISSECURE = 0x00000001, 28 | 29 | // Obsolete names 30 | SC_ICON = SC_MINIMIZE, 31 | SC_ZOOM = SC_MAXIMIZE, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Toastify/src/Helpers/Converters/SettingValueToValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using Toastify.Model; 5 | 6 | namespace Toastify.Helpers.Converters 7 | { 8 | public class SettingValueToValueConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | try 13 | { 14 | return ((ISettingValue)value)?.GetValue(); 15 | } 16 | catch 17 | { 18 | dynamic dynamicValue = value; 19 | return dynamicValue?.Value; 20 | } 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | Type genericType = typeof(SettingValue<>).MakeGenericType(targetType.GenericTypeArguments[0]); 26 | var converted = (ISettingValue)Activator.CreateInstance(genericType); 27 | converted.SetValue(value); 28 | return converted; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /ToastifyAPI/Model/LockedGlobalHotkey.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using ToastifyAPI.Model.Interfaces; 3 | 4 | namespace ToastifyAPI.Model 5 | { 6 | /// 7 | /// A read-only global hotkey. 8 | /// 9 | public class LockedGlobalHotkey : ILockedGlobalHotkey 10 | { 11 | #region Public Properties 12 | 13 | public bool Enabled { get; } 14 | 15 | public Keys KeyCode { get; } 16 | 17 | public bool Ctrl { get; } 18 | 19 | public bool Alt { get; } 20 | 21 | public bool Shift { get; } 22 | 23 | public bool WindowsKey { get; } 24 | 25 | #endregion 26 | 27 | public LockedGlobalHotkey(IGlobalHotkey globalHotkey) 28 | { 29 | this.Enabled = globalHotkey?.Enabled ?? false; 30 | this.KeyCode = globalHotkey?.KeyCode ?? Keys.None; 31 | this.Ctrl = globalHotkey?.Ctrl ?? false; 32 | this.Alt = globalHotkey?.Alt ?? false; 33 | this.Shift = globalHotkey?.Shift ?? false; 34 | this.WindowsKey = globalHotkey?.WindowsKey ?? false; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Toastify/src/ViewModel/ChangelogViewModel.cs: -------------------------------------------------------------------------------- 1 | using Toastify.Common; 2 | 3 | namespace Toastify.ViewModel 4 | { 5 | public class ChangelogViewModel : ObservableObject 6 | { 7 | private const string NO_RELEASE_BODY_MD = "### No relevant changes"; 8 | private const string LOADING_MD = "#### Loading..."; 9 | 10 | private string _releaseBodyMarkdown = LOADING_MD; 11 | private string _publishedAt; 12 | 13 | #region Public Properties 14 | 15 | public string ReleaseBodyMarkdown 16 | { 17 | get { return string.IsNullOrWhiteSpace(this._releaseBodyMarkdown) ? NO_RELEASE_BODY_MD : this._releaseBodyMarkdown; } 18 | set { this.RaiseAndSetIfChanged(ref this._releaseBodyMarkdown, value); } 19 | } 20 | 21 | public string GitHubLink { get; } = App.RepoInfo.Format("https://github.com/:owner/:repo/releases"); 22 | 23 | public string PublishedAt 24 | { 25 | get { return this._publishedAt; } 26 | set { this.RaiseAndSetIfChanged(ref this._publishedAt, value); } 27 | } 28 | 29 | #endregion 30 | } 31 | } -------------------------------------------------------------------------------- /ToastifyAPI/Interop/Keyboard.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | using JetBrains.Annotations; 3 | using ToastifyAPI.Interop.Interfaces; 4 | 5 | namespace ToastifyAPI.Interop 6 | { 7 | /// 8 | /// Represents a keyboard. 9 | /// 10 | public class Keyboard : IKeyboard 11 | { 12 | private readonly KeyboardDevice keyboardDevice; 13 | 14 | public Keyboard([NotNull] KeyboardDevice keyboardDevice) 15 | { 16 | this.keyboardDevice = keyboardDevice; 17 | } 18 | 19 | /// 20 | public bool IsKeyboard() 21 | { 22 | return true; 23 | } 24 | 25 | /// 26 | public bool IsMouse() 27 | { 28 | return false; 29 | } 30 | 31 | /// 32 | public bool IsKeyDown(Key key) 33 | { 34 | return this.keyboardDevice.IsKeyDown(key); 35 | } 36 | 37 | /// 38 | public bool IsKeyUp(Key key) 39 | { 40 | return this.keyboardDevice.IsKeyUp(key); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /ToastifyAPI/Native/RawInputAPI/Structs/RawInputDevice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using ToastifyAPI.Native.RawInputAPI.Enums; 4 | 5 | namespace ToastifyAPI.Native.RawInputAPI.Structs 6 | { 7 | /// 8 | /// Value type for raw input devices. 9 | /// 10 | [StructLayout(LayoutKind.Sequential)] 11 | public struct RawInputDevice 12 | { 13 | /// 14 | /// Top level collection Usage page for the raw input device. 15 | /// 16 | public HIDUsagePage UsagePage; 17 | 18 | /// 19 | /// Top level collection Usage for the raw input device. 20 | /// 21 | public HIDUsage Usage; 22 | 23 | /// 24 | /// Mode flag that specifies how to interpret the information provided by UsagePage and Usage. 25 | /// 26 | public RawInputDeviceFlags Flags; 27 | 28 | /// 29 | /// Handle to the target device. If NULL, it follows the keyboard focus. 30 | /// 31 | public IntPtr WindowHandle; 32 | } 33 | } -------------------------------------------------------------------------------- /Toastify/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Toastify.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Toastify/src/ViewModel/AboutViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Toastify.Common; 3 | using Toastify.Services; 4 | 5 | namespace Toastify.ViewModel 6 | { 7 | public class AboutViewModel : ObservableObject 8 | { 9 | private readonly Uri homepageUri; 10 | 11 | private string _updateUrl; 12 | 13 | #region Public Properties 14 | 15 | public string ToastifyVersion 16 | { 17 | get { return $"v{App.CurrentVersionNoRevision}"; } 18 | } 19 | 20 | public string HomepageUrl { get; } = App.RepoInfo.Format("https://github.com/:owner/:repo"); 21 | 22 | public string HomepageUrlNoScheme 23 | { 24 | get { return $"{this.homepageUri.Host}{this.homepageUri.PathAndQuery}"; } 25 | } 26 | 27 | public string UpdateUrl 28 | { 29 | get { return string.IsNullOrWhiteSpace(this._updateUrl) ? VersionChecker.GitHubReleasesUrl : this._updateUrl; } 30 | set { this.RaiseAndSetIfChanged(ref this._updateUrl, value); } 31 | } 32 | 33 | #endregion 34 | 35 | public AboutViewModel() 36 | { 37 | this.homepageUri = new Uri(this.HomepageUrl); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Toastify/src/Core/ToastifyVolumeControlMode.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using System; 4 | using Toastify.Common; 5 | 6 | namespace Toastify.Core 7 | { 8 | [Flags] 9 | [JsonConverter(typeof(StringEnumConverter))] 10 | public enum ToastifyVolumeControlMode 11 | { 12 | /// 13 | /// The volume will be changed in the WindowsVolumeMixer and will affect system volume. 14 | /// 15 | [ComboBoxItem("Windows Volume Mixer (global volume)", "Use the Windows Volume Mixer.\nThis affects the global system volume.")] 16 | SystemGlobal = 1 << 1, 17 | 18 | /// 19 | /// The volume will be changed in the WindowsVolumeMixer and will affect just Spotify. 20 | /// 21 | [ComboBoxItem("Windows Volume Mixer (Spotify only)", "Use the Windows Volume Mixer.\nThis only affects Spotify's volume.")] 22 | SystemSpotifyOnly = SystemGlobal | 1, 23 | 24 | // The Spotify volume control mode has been dropped since Spotify version 1.0.75.483.g7ff4a0dc due to issue #31 25 | //[ComboBoxItem("Spotify", "Use Spotify's volume control.")] 26 | //Spotify = SystemGlobal | 1, 27 | } 28 | } -------------------------------------------------------------------------------- /ToastifyAPI/Core/Auth/ToastifyWebAuthAPI/Utils.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Text; 3 | 4 | namespace ToastifyAPI.Core.Auth.ToastifyWebAuthAPI 5 | { 6 | public static class Utils 7 | { 8 | #region Static Members 9 | 10 | [DllImport("ToastifyWebAuthAPI.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetRedirectUri")] 11 | private static extern void _GetRedirectUri([Out] [MarshalAs(UnmanagedType.LPStr)] StringBuilder redirectUri, [In] int maxLength); 12 | 13 | [DllImport("ToastifyWebAuthAPI.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Try")] 14 | private static extern void _Try(); 15 | 16 | public static string GetRedirectUri() 17 | { 18 | StringBuilder sb = new StringBuilder(128); 19 | _GetRedirectUri(sb, 128); 20 | return sb.ToString(); 21 | } 22 | 23 | public static bool Try() 24 | { 25 | try 26 | { 27 | _Try(); 28 | return true; 29 | } 30 | catch 31 | { 32 | return false; 33 | } 34 | } 35 | 36 | #endregion 37 | } 38 | } -------------------------------------------------------------------------------- /Toastify/src/Core/ApplicationStartupException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Toastify.Core 5 | { 6 | public class ApplicationStartupException : ApplicationException 7 | { 8 | public ApplicationStartupException(string message) : base(message + Environment.NewLine + CreateMessage()) 9 | { 10 | } 11 | 12 | #region Static Members 13 | 14 | private static string CreateMessage() 15 | { 16 | // Touching Spotify.Instance forces instance creation if none, but it fails if called too early. 17 | // Therefore, a try is needed. 18 | try 19 | { 20 | // unused variable is needed to build the project 21 | var burner = Spotify.Instance; 22 | } 23 | catch (NullReferenceException) 24 | { 25 | return "\tSpotify instance status: not yet created."; 26 | } 27 | 28 | List messages = new List 29 | { 30 | $"\tSpotify instance running status: {Spotify.Instance.IsRunning}" 31 | }; 32 | 33 | return string.Join(Environment.NewLine, messages); 34 | } 35 | 36 | #endregion 37 | } 38 | } -------------------------------------------------------------------------------- /Toastify/src/View/DebugView.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 |