Expand out Web Manifest; App Insights Tracking

This commit is contained in:
Thomas Hounsell 2017-01-06 19:21:12 +00:00
parent 8038be53dc
commit 275478b5cc
8 changed files with 259 additions and 221 deletions

View File

@ -1,12 +1,13 @@
using System.Web.Mvc; using System.Web.Mvc;
using BuildFeed.Code;
namespace BuildFeed namespace BuildFeed
{ {
public class FilterConfig public class FilterConfig
{ {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{ {
filters.Add(new HandleErrorAttribute()); filters.Add(new AiHandleErrorAttribute());
} }
} }
} }

View File

@ -192,6 +192,7 @@
<Compile Include="Areas\admin\Controllers\baseController.cs" /> <Compile Include="Areas\admin\Controllers\baseController.cs" />
<Compile Include="Areas\admin\Controllers\metaController.cs" /> <Compile Include="Areas\admin\Controllers\metaController.cs" />
<Compile Include="Areas\admin\Models\ViewModel\MetaListing.cs" /> <Compile Include="Areas\admin\Models\ViewModel\MetaListing.cs" />
<Compile Include="Code\AiHandleErrorAttribute.cs" />
<Compile Include="Code\CustomContentTypeAttribute.cs" /> <Compile Include="Code\CustomContentTypeAttribute.cs" />
<Compile Include="Code\DateTimeModelBinder.cs" /> <Compile Include="Code\DateTimeModelBinder.cs" />
<Compile Include="Code\DisplayHelpers.cs" /> <Compile Include="Code\DisplayHelpers.cs" />

View File

@ -0,0 +1,25 @@
using System;
using System.Web.Mvc;
using Microsoft.ApplicationInsights;
namespace BuildFeed.Code
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class AiHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext?.HttpContext != null && filterContext.Exception != null)
{
//If customError is Off, then AI HTTPModule will report the exception
if (filterContext.HttpContext.IsCustomErrorEnabled)
{
// Note: A single instance of telemetry client is sufficient to track multiple telemetry items.
TelemetryClient ai = new TelemetryClient();
ai.TrackException(filterContext.Exception);
}
}
base.OnException(filterContext);
}
}
}

View File

@ -100,7 +100,11 @@ public async Task<bool> AddWin10Builds(NewBuildPost apiModel)
AppId = Guid.Parse(ConfigurationManager.AppSettings["push:AppId"]), AppId = Guid.Parse(ConfigurationManager.AppSettings["push:AppId"]),
IncludedSegments = new List<string> IncludedSegments = new List<string>
{ {
#if DEBUG
"Testers"
#else
"All" "All"
#endif
}, },
Headings = Headings =
{ {
@ -110,12 +114,7 @@ public async Task<bool> AddWin10Builds(NewBuildPost apiModel)
{ {
{LanguageCodes.English, build.AlternateBuildString} {LanguageCodes.English, build.AlternateBuildString}
}, },
Url = "https://www.buildfeed.net" + Url.Route(nameof(FrontController.ViewBuild), Url = $"https://buildfeed.net{Url.Route(nameof(FrontController.ViewBuild), new { controller = "Front", id = build.Id })}?utm_source=notification&utm_campaign=new_build"
new
{
controller = "Front",
id = build.Id
})
}); });
} }
return true; return true;

View File

@ -422,7 +422,11 @@ public async Task<ActionResult> AddBuild(Build build)
AppId = Guid.Parse(ConfigurationManager.AppSettings["push:AppId"]), AppId = Guid.Parse(ConfigurationManager.AppSettings["push:AppId"]),
IncludedSegments = new List<string> IncludedSegments = new List<string>
{ {
#if DEBUG
"Testers"
#else
"All" "All"
#endif
}, },
Headings = Headings =
{ {
@ -432,11 +436,7 @@ public async Task<ActionResult> AddBuild(Build build)
{ {
{LanguageCodes.English, build.AlternateBuildString} {LanguageCodes.English, build.AlternateBuildString}
}, },
Url = "https://www.buildfeed.net" + Url.Action(nameof(ViewBuild), Url = $"https://buildfeed.net{Url.Action(nameof(ViewBuild), new { id = build.Id })}?utm_source=notification&utm_campaign=new_build"
new
{
id = build.Id
})
}); });
return RedirectToAction(nameof(ViewBuild), return RedirectToAction(nameof(ViewBuild),

View File

@ -2,51 +2,42 @@
@using BuildFeed.Code.Options @using BuildFeed.Code.Options
@using BuildFeed.Controllers @using BuildFeed.Controllers
@{ @{
bool isRtl = CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft; bool isRtl = CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft;
Response.PushPromise("/res/css/default.css"); Response.PushPromise("/res/css/default.css");
Response.PushPromise(VirtualPathUtility.ToAbsolute(((Theme)ViewBag.Theme).CssPath)); Response.PushPromise(VirtualPathUtility.ToAbsolute(((Theme)ViewBag.Theme).CssPath));
if (isRtl) if (isRtl)
{ {
Response.PushPromise("/res/css/rtl.css"); Response.PushPromise("/res/css/rtl.css");
} }
Response.PushPromise("/res/ts/bfs.js"); Response.PushPromise("/res/ts/bfs.js");
} }
<!DOCTYPE html> <!DOCTYPE html>
<html dir="@(isRtl <html dir="@(isRtl
? "rtl" ? "rtl"
: "ltr")" lang="@CultureInfo.CurrentUICulture.TwoLetterISOLanguageName"> : "ltr")" lang="@CultureInfo.CurrentUICulture.TwoLetterISOLanguageName">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="format-detection" content="telephone=no" /> <meta name="format-detection" content="telephone=no" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,700" rel="stylesheet" type="text/css" /> <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,700" rel="stylesheet" type="text/css" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" /> <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
<link rel="shortcut icon" href="~/favicon.ico" /> <link rel="shortcut icon" href="~/favicon.ico" />
<link rel="icon" href="~/favicon.ico" /> <link rel="icon" href="~/favicon.ico" />
<link rel="canonical" href="@Url.Action()" /> <meta name="theme-color" content="#373736">
<meta name="application-name" content="@InvariantTerms.SiteName" /> <link rel="canonical" href="@Url.Action()" />
<meta name="application-name" content="@InvariantTerms.SiteName" />
<link href="/res/css/default.css" rel="stylesheet" type="text/css" /> <link href="/res/css/default.css" rel="stylesheet" type="text/css" />
<link href="@(VirtualPathUtility.ToAbsolute(((Theme)ViewBag.Theme).CssPath))" rel="stylesheet" type="text/css" /> <link href="@(VirtualPathUtility.ToAbsolute(((Theme)ViewBag.Theme).CssPath))" rel="stylesheet" type="text/css" />
@if (isRtl) @if (isRtl)
{ {
<link href="/res/css/rtl.css" rel="stylesheet" type="text/css" /> <link href="/res/css/rtl.css" rel="stylesheet" type="text/css" />
} }
<title>@ViewBag.Title</title> <title>@ViewBag.Title</title>
@RenderSection("head", false) @RenderSection("head", false)
<script type="text/javascript">
var appInsights = window.appInsights || function (config) {
function r(config) { t[config] = function () { var i = arguments; t.queue.push(function () { t[config].apply(t, i) }) } } var t = { config: config }, u = document, e = window, o = "script", s = u.createElement(o), i, f; for (s.src = config.url || "//az416426.vo.msecnd.net/scripts/a/ai.0.js", u.getElementsByTagName(o)[0].parentNode.appendChild(s), t.cookie = u.cookie, t.queue = [], i = ["Event", "Exception", "Metric", "PageView", "Trace"]; i.length;) r("track" + i.pop()); return r("setAuthenticatedUserContext"), r("clearAuthenticatedUserContext"), config.disableExceptionTracking || (i = "onerror", r("_" + i), f = e[i], e[i] = function (config, r, u, e, o) { var s = f && f(config, r, u, e, o); return s !== !0 && t["_" + i](config, r, u, e, o), s }), t;
}({
instrumentationKey: "4632419f-7a2f-4ab5-8374-34384b650f42"
});
window.appInsights = appInsights;
appInsights.trackPageView();
</script>
<link rel="manifest" href="/manifest.json"> <link rel="manifest" href="/manifest.json">
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async></script> <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async></script>
@ -54,6 +45,8 @@
var OneSignal = window.OneSignal || []; var OneSignal = window.OneSignal || [];
OneSignal.push(["init", { OneSignal.push(["init", {
appId: "94384f83-dced-4d66-a88c-c2b6e3cdfbaa", appId: "94384f83-dced-4d66-a88c-c2b6e3cdfbaa",
safari_web_id: "web.onesignal.auto.4cc30974-98f9-47ba-8e02-4635d2d477f2",
persistNotification: false,
allowLocalhostAsSecureOrigin: true, allowLocalhostAsSecureOrigin: true,
autoRegister: true, autoRegister: true,
notifyButton: { notifyButton: {
@ -61,204 +54,214 @@
} }
}]); }]);
</script> </script>
<script type="text/javascript">
var appInsights = window.appInsights || function (config) {
function i(config) { t[config] = function () { var i = arguments; t.queue.push(function () { t[config].apply(t, i) }) } } var t = { config: config }, u = document, e = window, o = "script", s = "AuthenticatedUserContext", h = "start", c = "stop", l = "Track", a = l + "Event", v = l + "Page", y = u.createElement(o), r, f; y.src = config.url || "https://az416426.vo.msecnd.net/scripts/a/ai.0.js"; u.getElementsByTagName(o)[0].parentNode.appendChild(y); try { t.cookie = u.cookie } catch (p) { } for (t.queue = [], t.version = "1.0", r = ["Event", "Exception", "Metric", "PageView", "Trace", "Dependency"]; r.length;)i("track" + r.pop()); return i("set" + s), i("clear" + s), i(h + a), i(c + a), i(h + v), i(c + v), i("flush"), config.disableExceptionTracking || (r = "onerror", i("_" + r), f = e[r], e[r] = function (config, i, u, e, o) { var s = f && f(config, i, u, e, o); return s !== !0 && t["_" + r](config, i, u, e, o), s }), t
} ({
instrumentationKey: "4632419f-7a2f-4ab5-8374-34384b650f42"
});
window.appInsights = appInsights;
appInsights.trackPageView();
</script>
</head> </head>
<body> <body>
<script> <script>
(function (i, s, o, g, r, a, m) { (function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () { i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments); (i[r].q = i[r].q || []).push(arguments);
}, i[r].l = 1 * new Date(); a = s.createElement(o), }, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m); m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m);
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-55417692-1', 'auto'); ga('create', 'UA-55417692-1', 'auto');
ga('require', 'displayfeatures'); ga('require', 'displayfeatures');
ga('require', 'linkid', 'linkid.js'); ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview'); ga('send', 'pageview');
</script> </script>
<header id="page-header"> <header id="page-header">
<div class="container"> <div class="container">
<h1> <h1>
@Html.ActionLink(InvariantTerms.SiteName, nameof(FrontController.Index), new @Html.ActionLink(InvariantTerms.SiteName, nameof(FrontController.Index), new
{ {
controller = "Front", controller = "Front",
area = "" area = ""
}) })
</h1> </h1>
</div> </div>
</header> </header>
<nav id="page-navigation" role="navigation"> <nav id="page-navigation" role="navigation">
<div class="container"> <div class="container">
<button id="page-navigation-toggle"> <button id="page-navigation-toggle">
<i class="fa fa-bars"></i>&ensp;@VariantTerms.Common_ToggleNavigation <i class="fa fa-bars"></i>&ensp;@VariantTerms.Common_ToggleNavigation
</button> </button>
<ul id="page-navigation-links"> <ul id="page-navigation-links">
@if (!User.Identity.IsAuthenticated) @if (!User.Identity.IsAuthenticated)
{ {
<li> <li>
<a href="@Url.Action(nameof(SupportController.Login), new <a href="@Url.Action(nameof(SupportController.Login), new
{ {
controller = "Support", controller = "Support",
area = "" area = ""
})" title="@VariantTerms.Common_LogIn"> })" title="@VariantTerms.Common_LogIn">
<i class="fa fa-fw fa-user"></i> @VariantTerms.Common_LogIn <i class="fa fa-fw fa-user"></i> @VariantTerms.Common_LogIn
</a> </a>
</li> </li>
} }
else else
{ {
if (Roles.IsUserInRole("Administrators")) if (Roles.IsUserInRole("Administrators"))
{ {
<li> <li>
<a href="@Url.Action("index", new <a href="@Url.Action("index", new
{ {
controller = "base", controller = "base",
area = "admin" area = "admin"
})" title="@VariantTerms.Common_Admin"> })" title="@VariantTerms.Common_Admin">
<i class="fa fa-fw fa-cogs"></i> @VariantTerms.Common_Admin <i class="fa fa-fw fa-cogs"></i> @VariantTerms.Common_Admin
</a> </a>
</li> </li>
} }
<li> <li>
<a href="@Url.Action(nameof(FrontController.AddBuild), new <a href="@Url.Action(nameof(FrontController.AddBuild), new
{ {
controller = "Front", controller = "Front",
area = "" area = ""
})" title="@VariantTerms.Common_AddBuild"> })" title="@VariantTerms.Common_AddBuild">
<i class="fa fa-fw fa-plus-square"></i> @VariantTerms.Common_AddBuild <i class="fa fa-fw fa-plus-square"></i> @VariantTerms.Common_AddBuild
</a> </a>
</li> </li>
<li> <li>
<a href="@Url.Action(nameof(SupportController.Logout), new <a href="@Url.Action(nameof(SupportController.Logout), new
{ {
controller = "Support", controller = "Support",
area = "" area = ""
})" title="@VariantTerms.Common_LogOut"> })" title="@VariantTerms.Common_LogOut">
<i class="fa fa-fw fa-user"></i> @VariantTerms.Common_LogOut <i class="fa fa-fw fa-user"></i> @VariantTerms.Common_LogOut
</a> </a>
</li> </li>
} }
<li> <li>
<a href="#" id="page-navigation-search" title="@VariantTerms.Search_Title"> <a href="#" id="page-navigation-search" title="@VariantTerms.Search_Title">
<i class="fa fa-fw fa-search"></i> @VariantTerms.Search_Title <i class="fa fa-fw fa-search"></i> @VariantTerms.Search_Title
</a> </a>
</li> </li>
<li> <li>
<a href="@Url.Action(nameof(SupportController.Rss), new <a href="@Url.Action(nameof(SupportController.Rss), new
{ {
controller = "Support", controller = "Support",
area = "" area = ""
})" title="@VariantTerms.Common_RssFeeds"> })" title="@VariantTerms.Common_RssFeeds">
<i class="fa fa-fw fa-rss"></i> @VariantTerms.Common_RssFeeds <i class="fa fa-fw fa-rss"></i> @VariantTerms.Common_RssFeeds
</a> </a>
</li> </li>
<li> <li>
<a href="https://twitter.com/buildfeed" title="@VariantTerms.Common_Twitter" target="_blank"> <a href="https://twitter.com/buildfeed" title="@VariantTerms.Common_Twitter" target="_blank">
<i class="fa fa-fw fa-twitter"></i> @VariantTerms.Common_Twitter <i class="fa fa-fw fa-twitter"></i> @VariantTerms.Common_Twitter
</a> </a>
</li> </li>
<li class="dropdown-parent"> <li class="dropdown-parent">
<a href="#"> <a href="#">
<i class="fa fa-gear"></i> <i class="fa fa-gear"></i>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li id="settings-theme-menu" class="dropdown-menu-block"> <li id="settings-theme-menu" class="dropdown-menu-block">
<h4>@VariantTerms.Common_NavigationTheme</h4> <h4>@VariantTerms.Common_NavigationTheme</h4>
<ul> <ul>
@foreach (Theme item in Theme.AvailableThemes) @foreach (Theme item in Theme.AvailableThemes)
{
<li>
<a href="#" data-theme="@item.CookieValue">@item.DisplayName</a>
</li>
}
</ul>
</li>
<li id="settings-lang-menu" class="dropdown-menu-block">
<h4>@VariantTerms.Common_NavigationLanguage</h4>
<ul>
@foreach (Locale locale in Locale.AvailableLocales)
{
<li>
<a href="#" data-lang="@locale.LocaleId" dir="@(locale.Info.TextInfo.IsRightToLeft
? "rtl"
: "ltr")">
@locale.DisplayName</a>
</li>
}
</ul>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<article id="page-content">
<div class="container">
@RenderBody()
</div>
</article>
<footer id="page-footer">
<div class="container">
<div class="footer-flex">
<div class="footer-flex-item">
<p>
<a href="@Url.Action(nameof(SupportController.Sitemap), new
{
controller = "Support",
area = ""
})">
@VariantTerms.Common_Sitemap</a>
</p>
<p>
<i class="fa fa-language"></i>&ensp;
@CultureInfo.CurrentUICulture.NativeName
(<a href="@Url.Action(nameof(SupportController.Credits), new
{ {
controller = "Support", <li>
area = "" <a href="#" data-theme="@item.CookieValue">@item.DisplayName</a>
})"> </li>
@VariantTerms.Common_Credits }
</a>) </ul>
</p> </li>
<li id="settings-lang-menu" class="dropdown-menu-block">
<h4>@VariantTerms.Common_NavigationLanguage</h4>
<ul>
@foreach (Locale locale in Locale.AvailableLocales)
{
<li>
<a href="#" data-lang="@locale.LocaleId" dir="@(locale.Info.TextInfo.IsRightToLeft
? "rtl"
: "ltr")">
@locale.DisplayName</a>
</li>
}
</ul>
</li>
</ul>
</li>
</ul>
</div>
</nav>
<article id="page-content">
<div class="container">
@RenderBody()
</div>
</article>
<footer id="page-footer">
<div class="container">
<div class="footer-flex">
<div class="footer-flex-item">
<p>
<a href="@Url.Action(nameof(SupportController.Sitemap), new
{
controller = "Support",
area = ""
})">
@VariantTerms.Common_Sitemap</a>
</p>
<p>
<i class="fa fa-language"></i>&ensp;
@CultureInfo.CurrentUICulture.NativeName
(<a href="@Url.Action(nameof(SupportController.Credits), new
{
controller = "Support",
area = ""
})">
@VariantTerms.Common_Credits
</a>)
</p>
</div> </div>
<div class="footer-flex-item"> <div class="footer-flex-item">
<p> <p>
&copy; 2013 - @DateTime.Now.Year.ToString(), <span dir="ltr">@InvariantTerms.SiteName</span> &copy; 2013 - @DateTime.Now.Year.ToString(), <span dir="ltr">@InvariantTerms.SiteName</span>
</p> </p>
<p> <p>
@Html.Raw(string.Format(VariantTerms.Common_DevelopedBy, $"<a href=\"https://twitter.com/tomhounsell\" target=\"_blank\" dir=\"ltr\">{InvariantTerms.DeveloperName}</a>")) @Html.Raw(string.Format(VariantTerms.Common_DevelopedBy, $"<a href=\"https://twitter.com/tomhounsell\" target=\"_blank\" dir=\"ltr\">{InvariantTerms.DeveloperName}</a>"))
</p> </p>
<p> <p>
@Html.Raw(string.Format(VariantTerms.Common_ContributeOn, "<a href=\"https://github.com/hounsell/BuildFeed\" target=\"_blank\" dir=\"ltr\"><i class=\"fa fa-github\"></i>&ensp;GitHub</a>")) @Html.Raw(string.Format(VariantTerms.Common_ContributeOn, "<a href=\"https://github.com/hounsell/BuildFeed\" target=\"_blank\" dir=\"ltr\"><i class=\"fa fa-github\"></i>&ensp;GitHub</a>"))
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</footer> </footer>
<div id="modal-search-overlay"> <div id="modal-search-overlay">
<div id="modal-search"> <div id="modal-search">
<h3>@VariantTerms.Search_BuildFeed</h3> <h3>@VariantTerms.Search_BuildFeed</h3>
<div id="modal-search-box"> <div id="modal-search-box">
<input id="modal-search-input" type="text" placeholder="@VariantTerms.Search_TypePlaceholder" /> <input id="modal-search-input" type="text" placeholder="@VariantTerms.Search_TypePlaceholder" />
<button id="modal-search-button"> <button id="modal-search-button">
<i class="fa fa-search"></i> <i class="fa fa-search"></i>
</button> </button>
</div> </div>
<div id="modal-search-result"></div> <div id="modal-search-result"></div>
</div> </div>
</div> </div>
<div id="menu-open-overlay"></div> <div id="menu-open-overlay"></div>
<script type="text/javascript" t src="https://cdnjs.cloudflare.com/ajax/libs/jsrender/1.0.0-rc.70/jsrender.min.js" integrity="sha256-3UBtL0tzgKVuJU8ZZiWLXEWGEjXEr6Z023rpauMnBUE=" crossorigin="anonymous"></script> <script type="text/javascript" t src="https://cdnjs.cloudflare.com/ajax/libs/jsrender/1.0.0-rc.70/jsrender.min.js" integrity="sha256-3UBtL0tzgKVuJU8ZZiWLXEWGEjXEr6Z023rpauMnBUE=" crossorigin="anonymous"></script>
<script type="text/javascript" src="/res/ts/bfs.js"></script> <script type="text/javascript" src="/res/ts/bfs.js"></script>
@RenderSection("scripts", false) @RenderSection("scripts", false)
<script id="result-template" type="text/x-jsrender"> <script id="result-template" type="text/x-jsrender">
<a href="{{:Url}}" class="search-result-item" title="{{:Title}}"> <a href="{{:Url}}" class="search-result-item" title="{{:Title}}">
<h4 class="search-result-heading no-wrapping">{{:Label}}</h4> <h4 class="search-result-heading no-wrapping">{{:Label}}</h4>
<p class="search-result-text">{{:Group}}</p> <p class="search-result-text">{{:Group}}</p>
</a> </a>
</script> </script>
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5431719a661cbfd0" async="async"></script> <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5431719a661cbfd0" async="async"></script>
</body> </body>
</html> </html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,7 +1,16 @@
{ {
"name": "BuildFeed", "name": "BuildFeed",
"short_name": "BuildFeed", "short_name": "BuildFeed",
"start_url": "/", "background_color": "#373736",
"theme_color": "#373736",
"description": "Learn what Dona Sarkar won't tell you. Keep up to date with the latest Microsoft Windows developments with BuildFeed, the comprehensive build tracker.",
"icons": [
{
"src": "https://buildfeed.net/content/tile/notify.png",
"sizes": "any"
}
],
"start_url": "https://buildfeed.net/",
"display": "standalone", "display": "standalone",
"gcm_sender_id": "482941778795" "gcm_sender_id": "482941778795"
} }