Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial revision. Catches a crash, saves it, then asks the user if he…

… wants to send the log to the server on the next start, and sends it afterwards.
  • Loading branch information...
commit 111a4a32e43f2546a0c26e28df027b4420a25bec 0 parents
@ashtom ashtom authored
46 .gitignore
@@ -0,0 +1,46 @@
+# OS junk files
+[Tt]humbs.db
+*.DS_Store
+
+# Visual Studio files
+*.[Oo]bj
+*.user
+*.aps
+*.pch
+*.vspscc
+*.vssscc
+*_i.c
+*_p.c
+*.ncb
+*.suo
+*.tlb
+*.tlh
+*.bak
+*.[Cc]ache
+*.ilk
+*.log
+*.lib
+*.sbr
+*.sdf
+*.opensdf
+*.unsuccessfulbuild
+ipch/
+obj/
+[Bb]in
+[Dd]ebug*/
+[Rr]elease*/
+Ankh.NoLoad
+
+# Tooling
+_ReSharper*/
+*.resharper
+[Tt]est[Rr]esult*
+
+# Project files
+[Bb]uild/
+
+# Office Temp Files
+~$*
+
+# NuGet
+packages/
20 HockeySDK.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010 Express for Windows Phone
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HockeySDK", "HockeySDK\HockeySDK.csproj", "{621893EB-F854-4777-8CFD-9032E6FF740C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {621893EB-F854-4777-8CFD-9032E6FF740C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {621893EB-F854-4777-8CFD-9032E6FF740C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {621893EB-F854-4777-8CFD-9032E6FF740C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {621893EB-F854-4777-8CFD-9032E6FF740C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
235 HockeySDK/Controls/NotificationBox/NotificationBox.cs
@@ -0,0 +1,235 @@
+/**
+ * Origin:
+ * http://wpassets.codeplex.com/SourceControl/changeset/view/86675
+ *
+ * Microsoft Public License (Ms-PL)
+ * This license governs use of the accompanying software. If you use the
+ * software, you accept this license. If you do not accept the license, do
+ * not use the software.
+ *
+ * 1. Definitions
+ *
+ * The terms "reproduce," "reproduction," "derivative works," and
+ * "distribution" have the same meaning here as under U.S. copyright law.
+ *
+ * A "contribution" is the original software, or any additions or changes
+ * to the software.
+ *
+ * A "contributor" is any person that distributes its contribution under
+ * this license.
+ *
+ * "Licensed patents" are a contributor's patent claims that read directly
+ * on its contribution.
+ *
+ * 2. Grant of Rights
+ *
+ * (A) Copyright Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free copyright license to reproduce
+ * its contribution, prepare derivative works of its contribution, and
+ * distribute its contribution or any derivative works that you create.
+ *
+ * (B) Patent Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free license under its licensed
+ * patents to make, have made, use, sell, offer for sale, import, and/or
+ * otherwise dispose of its contribution in the software or derivative works
+ * of the contribution in the software.
+ *
+ * 3. Conditions and Limitations
+ *
+ * (A) No Trademark License - This license does not grant you rights to use
+ * any contributors' name, logo, or trademarks.
+ *
+ * (B) If you bring a patent claim against any contributor over patents that
+ * you claim are infringed by the software, your patent license from such
+ * contributor to the software ends automatically.
+ *
+ * (C) If you distribute any portion of the software, you must retain all
+ * copyright, patent, trademark, and attribution notices that are present
+ * in the software.
+ *
+ * (D) If you distribute any portion of the software in source code form,
+ * you may do so only under this license by including a complete copy of
+ * this license with your distribution. If you distribute any portion of
+ * the software in compiled or object code form, you may only do so under
+ * a license that complies with this license.
+ *
+ * (E) The software is licensed "as-is." You bear the risk of using it. The
+ * contributors give no express warranties, guarantees or conditions. You
+ * may have additional consumer rights under your local laws which this
+ * license cannot change. To the extent permitted under your local laws,
+ * the contributors exclude the implied warranties of merchantability,
+ * fitness for a particular purpose and non-infringement.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.IO.IsolatedStorage;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Threading;
+using Microsoft.Phone.Controls;
+using HockeyApp.Controls;
+
+namespace HockeyApp.Controls.NotificationBox
+{
+ public class NotificationBox : ItemsControl
+ {
+ #region Properties
+
+ #region Title Property
+
+ /// <summary>
+ /// Gets or sets the title text to display.
+ /// </summary>
+ public string Title
+ {
+ get { return (string)GetValue(TitleProperty); }
+ set { SetValue(TitleProperty, value); }
+ }
+
+ /// <value>Identifies the Title dependency property</value>
+ public static readonly DependencyProperty TitleProperty =
+ DependencyProperty.Register(
+ "Title",
+ typeof(string),
+ typeof(NotificationBox),
+ new PropertyMetadata(default(string)));
+
+ #endregion
+
+ #region Message Property
+
+ /// <summary>
+ /// Gets or sets the message text to display.
+ /// </summary>
+ public string Message
+ {
+ get { return (string)GetValue(MessageProperty); }
+ set { SetValue(MessageProperty, value); }
+ }
+
+ /// <value>Identifies the Message dependency property</value>
+ public static readonly DependencyProperty MessageProperty =
+ DependencyProperty.Register(
+ "Message",
+ typeof(string),
+ typeof(NotificationBox),
+ new PropertyMetadata(default(string)));
+
+ #endregion
+
+ #region ShowAgainOption Property
+
+ /// <summary>
+ /// Gets or sets a value for indicating if this message is to be shown again.
+ /// </summary>
+ public bool ShowAgainOption
+ {
+ get { return (bool)GetValue(ShowAgainOptionProperty); }
+ set { SetValue(ShowAgainOptionProperty, value); }
+ }
+
+ /// <value>Identifies the ShowAgainOption dependency property</value>
+ public static readonly DependencyProperty ShowAgainOptionProperty =
+ DependencyProperty.Register(
+ "ShowAgainOption",
+ typeof(bool),
+ typeof(NotificationBox),
+ new PropertyMetadata(default(bool), ShowAgainOptionChanged));
+
+ /// <summary>
+ /// Invoked on ShowAgainOption change.
+ /// </summary>
+ /// <param name="d">The object that was changed</param>
+ /// <param name="e">Dependency property changed event arguments</param>
+ private static void ShowAgainOptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var message = d as NotificationBox;
+ if (message.UniqueKey != null)
+ {
+ Settings[message.UniqueKey] = e.NewValue;
+ }
+ }
+
+ #endregion
+
+ #region ShowAgainText Property
+
+ /// <summary>
+ /// Gets or sets the text asking if this message should be shown again.
+ /// </summary>
+ public string ShowAgainText
+ {
+ get { return (string)GetValue(ShowAgainTextProperty); }
+ set { SetValue(ShowAgainTextProperty, value); }
+ }
+
+ /// <value>Identifies the ShowAgainText dependency property</value>
+ public static readonly DependencyProperty ShowAgainTextProperty =
+ DependencyProperty.Register(
+ "ShowAgainText",
+ typeof(string),
+ typeof(NotificationBox),
+ new PropertyMetadata(default(string)));
+
+ #endregion
+
+ #region ShowAgainVisibility Property
+
+ /// <summary>
+ /// Gets or sets a value indicating if the show again message is visible or not.
+ /// </summary>
+ public Visibility ShowAgainVisibility
+ {
+ get { return (Visibility)GetValue(ShowAgainVisibilityProperty); }
+ set { SetValue(ShowAgainVisibilityProperty, value); }
+ }
+
+ /// <value>Identifies the ShowAgainVisibility dependency property</value>
+ public static readonly DependencyProperty ShowAgainVisibilityProperty =
+ DependencyProperty.Register(
+ "ShowAgainVisibility",
+ typeof(Visibility),
+ typeof(NotificationBox),
+ new PropertyMetadata(default(Visibility)));
+
+ #endregion
+
+ internal string UniqueKey { get; set; }
+
+ private static IsolatedStorageSettings Settings
+ {
+ get { return IsolatedStorageSettings.ApplicationSettings; }
+ }
+
+ #endregion
+
+ #region Ctor
+
+ public NotificationBox()
+ {
+ DefaultStyleKey = typeof(NotificationBox);
+ }
+
+ #endregion
+
+ #region Overrides
+
+ protected override DependencyObject GetContainerForItemOverride()
+ {
+ return new NotificationBoxItem();
+ }
+
+ protected override bool IsItemItsOwnContainerOverride(object item)
+ {
+ return item is NotificationBoxItem;
+ }
+
+ #endregion
+ }
+}
90 HockeySDK/Controls/NotificationBox/NotificationBoxItem.cs
@@ -0,0 +1,90 @@
+/**
+ * Origin:
+ * http://wpassets.codeplex.com/SourceControl/changeset/view/86675
+ *
+ * Microsoft Public License (Ms-PL)
+ * This license governs use of the accompanying software. If you use the
+ * software, you accept this license. If you do not accept the license, do
+ * not use the software.
+ *
+ * 1. Definitions
+ *
+ * The terms "reproduce," "reproduction," "derivative works," and
+ * "distribution" have the same meaning here as under U.S. copyright law.
+ *
+ * A "contribution" is the original software, or any additions or changes
+ * to the software.
+ *
+ * A "contributor" is any person that distributes its contribution under
+ * this license.
+ *
+ * "Licensed patents" are a contributor's patent claims that read directly
+ * on its contribution.
+ *
+ * 2. Grant of Rights
+ *
+ * (A) Copyright Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free copyright license to reproduce
+ * its contribution, prepare derivative works of its contribution, and
+ * distribute its contribution or any derivative works that you create.
+ *
+ * (B) Patent Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free license under its licensed
+ * patents to make, have made, use, sell, offer for sale, import, and/or
+ * otherwise dispose of its contribution in the software or derivative works
+ * of the contribution in the software.
+ *
+ * 3. Conditions and Limitations
+ *
+ * (A) No Trademark License - This license does not grant you rights to use
+ * any contributors' name, logo, or trademarks.
+ *
+ * (B) If you bring a patent claim against any contributor over patents that
+ * you claim are infringed by the software, your patent license from such
+ * contributor to the software ends automatically.
+ *
+ * (C) If you distribute any portion of the software, you must retain all
+ * copyright, patent, trademark, and attribution notices that are present
+ * in the software.
+ *
+ * (D) If you distribute any portion of the software in source code form,
+ * you may do so only under this license by including a complete copy of
+ * this license with your distribution. If you distribute any portion of
+ * the software in compiled or object code form, you may only do so under
+ * a license that complies with this license.
+ *
+ * (E) The software is licensed "as-is." You bear the risk of using it. The
+ * contributors give no express warranties, guarantees or conditions. You
+ * may have additional consumer rights under your local laws which this
+ * license cannot change. To the extent permitted under your local laws,
+ * the contributors exclude the implied warranties of merchantability,
+ * fitness for a particular purpose and non-infringement.
+ */
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace HockeyApp.Controls.NotificationBox
+{
+ public class NotificationBoxItem : Button
+ {
+ #region Ctor
+
+ internal NotificationBoxItem()
+ {
+ DefaultStyleKey = typeof(NotificationBoxItem);
+ }
+
+ #endregion
+ }
+}
336 HockeySDK/CrashHandler.cs
@@ -0,0 +1,336 @@
+/**
+ * The MIT License
+ * Copyright (c) 2012 Codenauts UG (haftungsbeschränkt). All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading;
+using System.Windows;
+using System.Windows.Threading;
+using Microsoft.Phone.Info;
+using Microsoft.Phone.Reactive;
+using System.Diagnostics;
+using System.IO.IsolatedStorage;
+using System.Net.Browser;
+using HockeyApp.Tools;
+
+namespace HockeyApp
+{
+ public sealed class CrashHandler
+ {
+ private const String CrashDirectoryName = "CrashLogs";
+
+ private static readonly CrashHandler instance = new CrashHandler();
+
+ private Application application = null;
+ private string identifier = null;
+
+ static CrashHandler() { }
+ private CrashHandler() { }
+
+ public static CrashHandler Instance
+ {
+ get
+ {
+ return instance;
+ }
+ }
+
+ public void Configure(Application application, string identifier)
+ {
+ if (this.application == null)
+ {
+ this.application = application;
+ this.identifier = identifier;
+
+ this.application.UnhandledException += OnUnhandledException;
+ }
+ else
+ {
+ throw new InvalidOperationException("CrashHandler was already configured!");
+ }
+ }
+
+ private void OnUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs args)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(CreateHeader());
+ builder.AppendLine();
+ builder.Append(CreateStackTrace(args));
+ SaveLog(builder.ToString());
+ }
+
+ public String CreateHeader()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.AppendFormat("Package: {0}\n", application.GetType().Namespace);
+ builder.AppendFormat("Product-ID: {0}\n", GetProductID());
+ builder.AppendFormat("Version: {0}\n", GetAppVersion());
+ builder.AppendFormat("Windows Phone: {0}\n", Environment.OSVersion.Version.ToString());
+ builder.AppendFormat("Manufacturer: {0}\n", GetDeviceManufacturer());
+ builder.AppendFormat("Model: {0}\n", GetDeviceModel());
+ builder.AppendFormat("Date: {0}\n", DateTime.UtcNow.ToString("o"));
+
+ return builder.ToString();
+ }
+
+ private String CreateStackTrace(ApplicationUnhandledExceptionEventArgs args)
+ {
+ Exception exception = args.ExceptionObject;
+ StringBuilder builder = new StringBuilder();
+ builder.AppendLine(string.IsNullOrEmpty(exception.Message) ? "No reason" : exception.Message);
+ builder.Append(string.IsNullOrEmpty(exception.StackTrace) ? " at unknown location" : exception.StackTrace);
+
+ Exception inner = exception.InnerException;
+ if ((inner != null) && (!string.IsNullOrEmpty(inner.StackTrace)))
+ {
+ builder.AppendLine();
+ builder.AppendLine("Inner Exception");
+ builder.Append(inner.StackTrace);
+ }
+
+ return builder.ToString().Trim();
+ }
+
+ private void SaveLog(String log)
+ {
+ try
+ {
+ IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
+ if (!store.DirectoryExists(CrashDirectoryName))
+ {
+ store.CreateDirectory(CrashDirectoryName);
+ }
+
+ String filename = string.Format("crash{0}.log", Guid.NewGuid());
+ FileStream stream = store.CreateFile(Path.Combine(CrashDirectoryName, filename));
+ using (StreamWriter writer = new StreamWriter(stream))
+ {
+ writer.Write(log);
+ }
+ stream.Close();
+ }
+ catch
+ {
+ // Ignore all exceptions
+ }
+ }
+
+ private static String GetDeviceManufacturer()
+ {
+ object manufacturer;
+ if (DeviceExtendedProperties.TryGetValue("DeviceManufacturer", out manufacturer))
+ {
+ return manufacturer.ToString();
+ }
+ else
+ {
+ return "Unknown";
+ }
+ }
+
+ private static String GetDeviceModel()
+ {
+ object model;
+ if (DeviceExtendedProperties.TryGetValue("DeviceName", out model))
+ {
+ return model.ToString();
+ }
+ else
+ {
+ return "Unknown";
+ }
+ }
+
+ // Idea based on http://bjorn.kuiper.nu/2011/10/01/wp7-notify-user-of-new-application-version/
+ private static String GetAppVersion()
+ {
+ return getValueFromManifest("Version");
+ }
+
+ private static String GetProductID()
+ {
+ return getValueFromManifest("ProductID");
+ }
+
+ private static String getValueFromManifest(String key)
+ {
+ try
+ {
+ StreamReader reader = getManifestReader();
+ while (!reader.EndOfStream)
+ {
+ string line = reader.ReadLine();
+ int begin = line.IndexOf(" " + key + "=\"", StringComparison.InvariantCulture);
+ if (begin >= 0)
+ {
+ int end = line.IndexOf("\"", begin + key.Length + 3, StringComparison.InvariantCulture);
+ if (end >= 0)
+ {
+ return line.Substring(begin + key.Length + 3, end - begin - key.Length - 3);
+ }
+ }
+ }
+ }
+ catch (Exception)
+ {
+ // Ignore all exceptions
+ }
+
+ return "";
+ }
+
+ private static StreamReader getManifestReader()
+ {
+ Uri manifest = new Uri("WMAppManifest.xml", UriKind.Relative);
+ var stream = Application.GetResourceStream(manifest);
+ if (stream != null)
+ {
+ return new StreamReader(stream.Stream);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public void HandleCrashes()
+ {
+ try
+ {
+ IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
+ if (store.DirectoryExists(CrashDirectoryName))
+ {
+ string[] filenames = store.GetFileNames(CrashDirectoryName + "\\crash*.log");
+ Debugger.Log(0, "HockeyApp", filenames.ToString());
+
+ if (filenames.Length > 0)
+ {
+ Scheduler.Dispatcher.Schedule(() =>
+ {
+ NotificationTool.Show(
+ "Crash Data",
+ "The app quit unexpectedly. Would you like to send information about this to the developer?",
+ new NotificationAction("Send", () =>
+ {
+ SendCrashes(store, filenames);
+ }),
+ new NotificationAction("Delete", () =>
+ {
+ DeleteCrashes(store, filenames);
+ })
+ );
+ });
+ }
+ }
+ }
+ catch (Exception)
+ {
+ // Ignore all exceptions
+ }
+ }
+
+ private void SendCrashes(IsolatedStorageFile store, string[] filenames)
+ {
+ foreach (String filename in filenames)
+ {
+ try
+ {
+ Stream fileStream = store.OpenFile(Path.Combine(CrashDirectoryName, filename), FileMode.Open);
+ string log = "";
+ using (StreamReader reader = new StreamReader(fileStream))
+ {
+ log = reader.ReadToEnd();
+ }
+ string body = "raw=" + HttpUtility.UrlEncode(log);
+ fileStream.Close();
+
+ WebRequest request = WebRequestCreator.ClientHttp.Create(new Uri("https://rink.hockeyapp.net/api/2/apps/" + identifier + "/crashes"));
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+ request.Headers[HttpRequestHeader.UserAgent] = "Hockey/WP7";
+
+ request.BeginGetRequestStream(requestResult =>
+ {
+ try
+ {
+ Stream stream = request.EndGetRequestStream(requestResult);
+ byte[] byteArray = Encoding.UTF8.GetBytes(body);
+ stream.Write(byteArray, 0, body.Length);
+ stream.Close();
+
+ request.BeginGetResponse(responseResult =>
+ {
+ Boolean deleteCrashes = true;
+ try
+ {
+ request.EndGetResponse(responseResult);
+ }
+ catch (WebException e)
+ {
+ if ((e.Status == WebExceptionStatus.ConnectFailure) ||
+ (e.Status == WebExceptionStatus.ReceiveFailure) ||
+ (e.Status == WebExceptionStatus.SendFailure) ||
+ (e.Status == WebExceptionStatus.Timeout) ||
+ (e.Status == WebExceptionStatus.UnknownError))
+ {
+ deleteCrashes = false;
+ }
+ }
+ catch (Exception)
+ {
+ }
+ finally
+ {
+ if (deleteCrashes)
+ {
+ DeleteCrashes(store, filenames);
+ }
+ }
+ }, null);
+ }
+ catch (Exception)
+ {
+ }
+ }, null);
+ }
+ catch (Exception)
+ {
+ store.DeleteFile(Path.Combine(CrashDirectoryName, filename));
+ }
+ }
+ }
+
+ private void DeleteCrashes(IsolatedStorageFile store, string[] filenames)
+ {
+ foreach (String filename in filenames)
+ {
+ store.DeleteFile(Path.Combine(CrashDirectoryName, filename));
+ }
+ }
+ }
+}
77 HockeySDK/HockeySDK.csproj
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>10.0.20506</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{621893EB-F854-4777-8CFD-9032E6FF740C}</ProjectGuid>
+ <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>HockeySDK</RootNamespace>
+ <AssemblyName>HockeySDK</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+ <TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>
+ <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+ <SilverlightApplication>false</SilverlightApplication>
+ <ValidateXaml>true</ValidateXaml>
+ <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>Bin\Debug</OutputPath>
+ <DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+ <NoStdLib>true</NoStdLib>
+ <NoConfig>true</NoConfig>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>Bin\Release</OutputPath>
+ <DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+ <NoStdLib>true</NoStdLib>
+ <NoConfig>true</NoConfig>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.Phone" />
+ <Reference Include="Microsoft.Phone.Interop" />
+ <Reference Include="Microsoft.Phone.Reactive" />
+ <Reference Include="System.Windows" />
+ <Reference Include="system" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Net" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Controls\NotificationBox\NotificationBox.cs" />
+ <Compile Include="Controls\NotificationBox\NotificationBoxItem.cs" />
+ <Compile Include="CrashHandler.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Tools\NotificationAction.cs" />
+ <Compile Include="Tools\NotificationTool.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Page Include="Themes\Generic.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ </ItemGroup>
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
+ <ProjectExtensions />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
21 HockeySDK/Properties/AssemblyInfo.cs
@@ -0,0 +1,21 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Resources;
+
+[assembly: AssemblyTitle("HockeySDK")]
+[assembly: AssemblyDescription("Windows Phone Class Library to do crash reporting with hockeyapp.net")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("HockeySDK")]
+[assembly: AssemblyCopyright("Copyright © Codenauts UG 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("555849f2-b863-42c1-b5b2-2c44fdd7b66b")]
+
+[assembly: AssemblyVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
+[assembly: NeutralResourcesLanguageAttribute("de-DE")]
117 HockeySDK/Themes/Generic.xaml
@@ -0,0 +1,117 @@
+<ResourceDictionary
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:HockeyApp.Controls.NotificationBox"
+ mc:Ignorable="d">
+
+ <DataTemplate x:Key="NotificationActionDefaultTemplate">
+ <TextBlock Text="{Binding Content}" />
+ </DataTemplate>
+
+ <Style TargetType="local:NotificationBoxItem">
+ <Setter Property="VerticalAlignment" Value="Stretch" />
+ <Setter Property="VerticalContentAlignment" Value="Center" />
+ <Setter Property="HorizontalContentAlignment" Value="Center" />
+ <Setter Property="Background" Value="Transparent"/>
+ <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
+ <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
+ <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
+ <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
+ <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
+ <Setter Property="Padding" Value="10,3,10,5"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="local:NotificationBoxItem">
+ <Grid Background="Transparent">
+ <VisualStateManager.VisualStateGroups>
+ <VisualStateGroup x:Name="CommonStates">
+ <VisualState x:Name="Normal"/>
+ <VisualState x:Name="MouseOver"/>
+ <VisualState x:Name="Pressed">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ <VisualState x:Name="Disabled">
+ <Storyboard>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
+ </ObjectAnimationUsingKeyFrames>
+ <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
+ <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
+ </ObjectAnimationUsingKeyFrames>
+ </Storyboard>
+ </VisualState>
+ </VisualStateGroup>
+ </VisualStateManager.VisualStateGroups>
+ <Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
+ <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
+ </Border>
+ </Grid>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+ <Style TargetType="local:NotificationBox">
+ <Setter Property="ItemTemplate" Value="{StaticResource NotificationActionDefaultTemplate}" />
+ <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}" />
+ <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}" />
+ <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}" />
+ <Setter Property="Background" Value="#99000000" />
+ <Setter Property="ItemsPanel">
+ <Setter.Value>
+ <ItemsPanelTemplate>
+ <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" />
+ </ItemsPanelTemplate>
+ </Setter.Value>
+ </Setter>
+
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="local:NotificationBox">
+ <Border Background="#99000000" d:DesignWidth="312" d:DesignHeight="464">
+ <Border x:Name="border" Background="#FF1F1F1F" VerticalAlignment="Top">
+ <Grid Margin="24,40,24,0">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="60"/>
+ <RowDefinition Height="Auto" />
+ <RowDefinition/>
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <TextBlock Text="{TemplateBinding Title}" VerticalAlignment="Center" Margin="0,0,0,2" FontSize="32" />
+ <TextBlock Text="{TemplateBinding Message}" TextWrapping="Wrap" Grid.Row="1" Margin="0,2,0,2" FontSize="22" Foreground="#FFDDDDDD" />
+
+ <ItemsPresenter Grid.Row="2" Margin="0,2,0,8" />
+
+ <CheckBox IsChecked="{Binding ShowAgainOption, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
+ Visibility="{TemplateBinding ShowAgainVisibility}"
+ Content="{TemplateBinding ShowAgainText}"
+ Grid.Row="3"
+ VerticalAlignment="Center"
+ HorizontalAlignment="Left" />
+
+ </Grid>
+ </Border>
+ </Border>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+</ResourceDictionary>
154 HockeySDK/Tools/NotificationAction.cs
@@ -0,0 +1,154 @@
+/**
+ * Origin:
+ * http://wpassets.codeplex.com/SourceControl/changeset/view/86675
+ *
+ * Microsoft Public License (Ms-PL)
+ * This license governs use of the accompanying software. If you use the
+ * software, you accept this license. If you do not accept the license, do
+ * not use the software.
+ *
+ * 1. Definitions
+ *
+ * The terms "reproduce," "reproduction," "derivative works," and
+ * "distribution" have the same meaning here as under U.S. copyright law.
+ *
+ * A "contribution" is the original software, or any additions or changes
+ * to the software.
+ *
+ * A "contributor" is any person that distributes its contribution under
+ * this license.
+ *
+ * "Licensed patents" are a contributor's patent claims that read directly
+ * on its contribution.
+ *
+ * 2. Grant of Rights
+ *
+ * (A) Copyright Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free copyright license to reproduce
+ * its contribution, prepare derivative works of its contribution, and
+ * distribute its contribution or any derivative works that you create.
+ *
+ * (B) Patent Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free license under its licensed
+ * patents to make, have made, use, sell, offer for sale, import, and/or
+ * otherwise dispose of its contribution in the software or derivative works
+ * of the contribution in the software.
+ *
+ * 3. Conditions and Limitations
+ *
+ * (A) No Trademark License - This license does not grant you rights to use
+ * any contributors' name, logo, or trademarks.
+ *
+ * (B) If you bring a patent claim against any contributor over patents that
+ * you claim are infringed by the software, your patent license from such
+ * contributor to the software ends automatically.
+ *
+ * (C) If you distribute any portion of the software, you must retain all
+ * copyright, patent, trademark, and attribution notices that are present
+ * in the software.
+ *
+ * (D) If you distribute any portion of the software in source code form,
+ * you may do so only under this license by including a complete copy of
+ * this license with your distribution. If you distribute any portion of
+ * the software in compiled or object code form, you may only do so under
+ * a license that complies with this license.
+ *
+ * (E) The software is licensed "as-is." You bear the risk of using it. The
+ * contributors give no express warranties, guarantees or conditions. You
+ * may have additional consumer rights under your local laws which this
+ * license cannot change. To the extent permitted under your local laws,
+ * the contributors exclude the implied warranties of merchantability,
+ * fitness for a particular purpose and non-infringement.
+ */
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+namespace HockeyApp.Tools
+{
+ public class NotificationAction
+ {
+ #region Properties
+
+ public object Content { get; private set; }
+ public object ContentTemplateKey { get; private set; }
+
+ internal ICommand Command
+ {
+ get;
+ private set;
+ }
+
+ #endregion
+
+ #region NotificationCommand
+
+ private class NotificationCommand : ICommand
+ {
+ private readonly Action _execute;
+ private readonly Func<bool> _canExecute;
+
+ public NotificationCommand(Action execute, Func<bool> canExecute)
+ {
+ _execute = execute;
+ _canExecute = canExecute;
+ }
+
+ bool ICommand.CanExecute(object parameter)
+ {
+ return _canExecute();
+ }
+
+ event EventHandler ICommand.CanExecuteChanged
+ {
+ add { }
+ remove { }
+ }
+
+ void ICommand.Execute(object parameter)
+ {
+ _execute();
+
+ NotificationTool.Close();
+ }
+ }
+
+ #endregion
+
+ #region Ctor
+
+ public NotificationAction(object content, Action execute)
+ : this(content, null, execute, () => true)
+ {
+ }
+
+ public NotificationAction(object content, Action execute, Func<bool> canExecute)
+ : this(content, null, execute, canExecute)
+ {
+ }
+
+ public NotificationAction(object content, object contentTemplateKey, Action execute)
+ : this(content, contentTemplateKey, execute, () => true)
+ {
+ }
+
+ public NotificationAction(object content, object contentTemplateKey, Action execute, Func<bool> canExecute)
+ {
+ Content = content;
+ ContentTemplateKey = contentTemplateKey;
+ Command = new NotificationCommand(execute, canExecute);
+ }
+
+ #endregion
+ }
+}
340 HockeySDK/Tools/NotificationTool.cs
@@ -0,0 +1,340 @@
+/**
+ * Origin:
+ * http://wpassets.codeplex.com/SourceControl/changeset/view/86675
+ *
+ * Microsoft Public License (Ms-PL)
+ * This license governs use of the accompanying software. If you use the
+ * software, you accept this license. If you do not accept the license, do
+ * not use the software.
+ *
+ * 1. Definitions
+ *
+ * The terms "reproduce," "reproduction," "derivative works," and
+ * "distribution" have the same meaning here as under U.S. copyright law.
+ *
+ * A "contribution" is the original software, or any additions or changes
+ * to the software.
+ *
+ * A "contributor" is any person that distributes its contribution under
+ * this license.
+ *
+ * "Licensed patents" are a contributor's patent claims that read directly
+ * on its contribution.
+ *
+ * 2. Grant of Rights
+ *
+ * (A) Copyright Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free copyright license to reproduce
+ * its contribution, prepare derivative works of its contribution, and
+ * distribute its contribution or any derivative works that you create.
+ *
+ * (B) Patent Grant- Subject to the terms of this license, including the
+ * license conditions and limitations in section 3, each contributor grants
+ * you a non-exclusive, worldwide, royalty-free license under its licensed
+ * patents to make, have made, use, sell, offer for sale, import, and/or
+ * otherwise dispose of its contribution in the software or derivative works
+ * of the contribution in the software.
+ *
+ * 3. Conditions and Limitations
+ *
+ * (A) No Trademark License - This license does not grant you rights to use
+ * any contributors' name, logo, or trademarks.
+ *
+ * (B) If you bring a patent claim against any contributor over patents that
+ * you claim are infringed by the software, your patent license from such
+ * contributor to the software ends automatically.
+ *
+ * (C) If you distribute any portion of the software, you must retain all
+ * copyright, patent, trademark, and attribution notices that are present
+ * in the software.
+ *
+ * (D) If you distribute any portion of the software in source code form,
+ * you may do so only under this license by including a complete copy of
+ * this license with your distribution. If you distribute any portion of
+ * the software in compiled or object code form, you may only do so under
+ * a license that complies with this license.
+ *
+ * (E) The software is licensed "as-is." You bear the risk of using it. The
+ * contributors give no express warranties, guarantees or conditions. You
+ * may have additional consumer rights under your local laws which this
+ * license cannot change. To the extent permitted under your local laws,
+ * the contributors exclude the implied warranties of merchantability,
+ * fitness for a particular purpose and non-infringement.
+ */
+
+using System;
+using System.ComponentModel;
+using System.IO.IsolatedStorage;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using System.Windows.Controls.Primitives;
+using System.Windows.Threading;
+using Microsoft.Phone.Controls;
+using HockeyApp.Controls.NotificationBox;
+
+namespace HockeyApp.Tools
+{
+ public class NotificationTool
+ {
+ #region Consts
+
+ public const double NotificationWidth = 480;
+ public const double NotificationHeight = 800;
+
+ #endregion
+
+ #region Properties
+
+ private static Popup Popup { get; set; }
+ private static bool AppBarVisibility { get; set; }
+
+ private static NotificationBox Notification
+ {
+ get
+ {
+ if (Popup == null)
+ {
+ return null;
+ }
+
+ return Popup.Child as NotificationBox;
+ }
+ }
+
+ /// <summary>
+ /// Gets value indicating whether a message is shown to the user.
+ /// </summary>
+ public static bool IsShown
+ {
+ get
+ {
+ return Popup != null && Popup.IsOpen;
+ }
+ }
+
+ private static IsolatedStorageSettings Settings
+ {
+ get { return IsolatedStorageSettings.ApplicationSettings; }
+ }
+
+ private static string UniqueKey { get; set; }
+
+ private static Action<bool> SuppressionCallback { get; set; }
+
+ #endregion
+
+ #region Utilities
+
+ /// <summary>
+ /// Displays a notification box with title, message and custom actions.
+ /// </summary>
+ /// <param name="title">The title of this message.</param>
+ /// <param name="message">The message body text.</param>
+ /// <param name="actions">A collection of actions.</param>
+ public static void Show(string title, string message, params NotificationAction[] actions)
+ {
+ if (IsShown)
+ {
+ ClosePopup();
+ }
+
+ Popup = new Popup
+ {
+ Child = CreateNotificationBox(title, message, actions)
+ };
+
+ OpenPopup();
+ }
+
+ /// <summary>
+ /// Displays a notification box with title, message and custom actions.
+ /// In addition a message asking if this message should be shown again next time.
+ /// </summary>
+ /// <param name="title">The title of this message.</param>
+ /// <param name="message">The message body text.</param>
+ /// <param name="showAgainText">The text asking if this message should be shown again.</param>
+ /// <param name="forceShowAgain">Value indicating whether to force message display in case that the user suppressed this message, </param>
+ /// <param name="suppression">Callback for indicating whether message suppressed or not..</param>
+ /// <param name="uniqueKey">Unique key representing a specific message identity.</param>
+ /// <param name="actions">A collection of actions.</param>
+ public static void ShowAgain(string title, string message, string showAgainText, bool forceShowAgain, Action<bool> suppression, string uniqueKey, params NotificationAction[] actions)
+ {
+ if (IsShown)
+ {
+ ClosePopup();
+ }
+
+ bool showAgain;
+ if (!Settings.TryGetValue(uniqueKey, out showAgain))
+ {
+ showAgain = true;
+ Settings[uniqueKey] = showAgain;
+ }
+
+ if (showAgain || forceShowAgain)
+ {
+ Popup = new Popup
+ {
+ Child = CreateNotificationBox(title, message, actions, Visibility.Visible, showAgain, showAgainText, uniqueKey)
+ };
+
+ SuppressionCallback = suppression;
+ UniqueKey = uniqueKey;
+ OpenPopup();
+ }
+ }
+
+ /// <summary>
+ /// Displays a notification box with title, message and custom actions.
+ /// In addition a message asking if this message should be shown again next time.
+ /// </summary>
+ /// <param name="title">The title of this message.</param>
+ /// <param name="message">The message body text.</param>
+ /// <param name="forceShowAgain">Value indicating whether to force message display in case that the user suppressed this message, </param>
+ /// <param name="suppression">Callback for indicating whether message suppressed or not..</param>
+ /// <param name="uniqueKey">Unique key representing a specific message identity.</param>
+ /// <param name="commands">A collection of actions.</param>
+ public static void ShowAgain(string title, string message, bool forceShowAgain, Action<bool> suppression, string uniqueKey, params NotificationAction[] commands)
+ {
+ ShowAgain(title, message, "Show this message again", forceShowAgain, suppression, uniqueKey, commands);
+ }
+
+ internal static void Close()
+ {
+ if (SuppressionCallback != null)
+ {
+ SuppressionCallback(!Notification.ShowAgainOption);
+ }
+
+ ClosePopup();
+ }
+
+ #endregion
+
+ private static PhoneApplicationFrame RootFrame
+ {
+ get
+ {
+ return Application.Current.RootVisual as PhoneApplicationFrame;
+ }
+ }
+
+ private static PhoneApplicationPage CurrentPage
+ {
+ get
+ {
+ PhoneApplicationPage currentPage = null;
+ if (RootFrame != null)
+ {
+ currentPage = RootFrame.Content as PhoneApplicationPage;
+ }
+
+ return currentPage;
+ }
+ }
+
+ private static void SafeShow(Dispatcher dispatcher, Action showAction)
+ {
+
+ if (RootFrame != null)
+ {
+ showAction();
+ }
+ else
+ {
+ dispatcher.BeginInvoke(showAction);
+ }
+ }
+
+ private static void HandleBackKeyAndAppBar()
+ {
+ RootFrame.BackKeyPress += parentPage_BackKeyPress;
+ if (CurrentPage.ApplicationBar != null)
+ {
+ AppBarVisibility = CurrentPage.ApplicationBar.IsVisible;
+ CurrentPage.ApplicationBar.IsVisible = false;
+ }
+ }
+
+ private static void parentPage_BackKeyPress(object sender, CancelEventArgs e)
+ {
+ RootFrame.BackKeyPress -= parentPage_BackKeyPress;
+ if (IsShown)
+ {
+ ClosePopup();
+ e.Cancel = true;
+ }
+ }
+
+ private static NotificationBox CreateNotificationBox(string title, string message, NotificationAction[] commands, Visibility showAgainVisibility = Visibility.Collapsed, bool showAgain = true, string showAgainText = null, string uniqueKey = null)
+ {
+ var notificationBox = new NotificationBox
+ {
+ Width = NotificationWidth,
+ Height = NotificationHeight,
+ Title = title,
+ Message = message,
+ ShowAgainOption = showAgain,
+ ShowAgainText = showAgainText,
+ ShowAgainVisibility = showAgainVisibility,
+ UniqueKey = uniqueKey
+ };
+
+ foreach (var action in commands)
+ {
+ var notificationBoxItem = new NotificationBoxItem
+ {
+ Content = action.Content,
+ Command = action.Command,
+ ContentTemplate = TryFindTemplate(action.ContentTemplateKey)
+ };
+
+ notificationBox.Items.Add(notificationBoxItem);
+ }
+
+ return notificationBox;
+ }
+
+ private static DataTemplate TryFindTemplate(object templateKey)
+ {
+ DataTemplate template = null;
+ if (templateKey != null && Application.Current.Resources.Contains(templateKey))
+ {
+ template = Application.Current.Resources[templateKey] as DataTemplate;
+ }
+
+ return template;
+ }
+
+ private static void OpenPopup()
+ {
+ SafeShow(Popup.Dispatcher, () =>
+ {
+ HandleBackKeyAndAppBar();
+ Popup.IsOpen = true;
+ });
+ }
+
+ private static void ClosePopup()
+ {
+ if (Popup != null)
+ {
+ Popup.IsOpen = false;
+ Popup = null;
+ }
+
+ if (CurrentPage.ApplicationBar != null)
+ {
+ CurrentPage.ApplicationBar.IsVisible = AppBarVisibility;
+ }
+ }
+ }
+}
98 LICENSE.txt
@@ -0,0 +1,98 @@
+## Authors
+
+Thomas Dohmke <thomas@dohmke.de>
+Tomer Shamam
+
+## Licenses
+
+The Hockey SDK is provided under the following license:
+
+ The MIT License
+ Copyright (c) 2012 Codenauts UG (haftungsbeschränkt). All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+The classes of the NotificationTool are based on the following project:
+http://wpassets.codeplex.com/
+
+It is provided under the following license:
+
+ Microsoft Public License (Ms-PL)
+ This license governs use of the accompanying software. If you use the
+ software, you accept this license. If you do not accept the license, do
+ not use the software.
+
+ 1. Definitions
+
+ The terms "reproduce," "reproduction," "derivative works," and
+ "distribution" have the same meaning here as under U.S. copyright law.
+
+ A "contribution" is the original software, or any additions or changes
+ to the software.
+
+ A "contributor" is any person that distributes its contribution under
+ this license.
+
+ "Licensed patents" are a contributor's patent claims that read directly
+ on its contribution.
+
+ 2. Grant of Rights
+
+ (A) Copyright Grant- Subject to the terms of this license, including the
+ license conditions and limitations in section 3, each contributor grants
+ you a non-exclusive, worldwide, royalty-free copyright license to reproduce
+ its contribution, prepare derivative works of its contribution, and
+ distribute its contribution or any derivative works that you create.
+
+ (B) Patent Grant- Subject to the terms of this license, including the
+ license conditions and limitations in section 3, each contributor grants
+ you a non-exclusive, worldwide, royalty-free license under its licensed
+ patents to make, have made, use, sell, offer for sale, import, and/or
+ otherwise dispose of its contribution in the software or derivative works
+ of the contribution in the software.
+
+ 3. Conditions and Limitations
+
+ (A) No Trademark License - This license does not grant you rights to use
+ any contributors' name, logo, or trademarks.
+
+ (B) If you bring a patent claim against any contributor over patents that
+ you claim are infringed by the software, your patent license from such
+ contributor to the software ends automatically.
+
+ (C) If you distribute any portion of the software, you must retain all
+ copyright, patent, trademark, and attribution notices that are present
+ in the software.
+
+ (D) If you distribute any portion of the software in source code form,
+ you may do so only under this license by including a complete copy of
+ this license with your distribution. If you distribute any portion of
+ the software in compiled or object code form, you may only do so under
+ a license that complies with this license.
+
+ (E) The software is licensed "as-is." You bear the risk of using it. The
+ contributors give no express warranties, guarantees or conditions. You
+ may have additional consumer rights under your local laws which this
+ license cannot change. To the extent permitted under your local laws,
+ the contributors exclude the implied warranties of merchantability,
+ fitness for a particular purpose and non-infringement.
+ /
0  README.md
No changes.
Please sign in to comment.
Something went wrong with that request. Please try again.