Skip to content

Commit

Permalink
UI Updates, Win10 Live Tiles, Flagged Photo Push Notifications (#30)
Browse files Browse the repository at this point in the history
* merge

* merge

* reverted file
  • Loading branch information
jessicamtz authored Aug 5, 2016
1 parent e6cfb40 commit b7b937a
Show file tree
Hide file tree
Showing 44 changed files with 1,650 additions and 616 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public PhotoContract ToContract(ICollection<UserDocument> userDocumentsForPhotos
NumberOfGoldVotes = GoldCount,
NumberOfAnnotations = Annotations.Count,
OSPlatform = OSPlatform,
Reports = Reports.Select(r => r.ToContract(Id, ContentType.Photo)).ToList(),
Reports = Reports.Select( r => r.ToContract(Id, ContentType.Photo)).ToList(),
Status = Status
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function getRecentPhotosForCategories(numberOfPhotos, currentDocumentVersion) {

if (!result.isAccepted) {
throw new Error("Sproc is too close to violating resource limit, aborting.");
}
}
}

function getRecentPhotosForCategory(categoryId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ public async Task<IList<CategoryPreviewContract>> GetCategoriesPreview(int numbe
numberOfThumbnails,
_currentDocumentVersion);


var mostRecentCategoryPhotos = photosQuery.Response;

if (mostRecentCategoryPhotos != null && mostRecentCategoryPhotos.Any())
Expand Down Expand Up @@ -1059,8 +1059,16 @@ public async Task<ReportContract> InsertReport(ReportContract reportContract, st
photoDocument.Reports.Add(reportDocument);

if (photoDocument.Reports.Count >= _maxReportsPermitted)
{
{
photoDocument.Status = PhotoStatus.UnderReview;

var user = GetUserDocumentByUserId(photoDocument.UserId);
if (user.ProfilePhotoId == photoDocument.Id)
{
user.ProfilePhotoId = null;
user.ProfilePhotoUrl = null;
await UpdateUser(user.ToContract());
}
}

await ReplacePhotoDocument(photoDocument);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector"/>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
<!--
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector"/>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
<!--
Use the following syntax here to collect additional performance counters:
<Counters>
Expand All @@ -24,35 +24,36 @@
??APP_W3SVC_PROC?? - instance name of the application IIS worker process for IIS/ASP.NET counters.
??APP_CLR_PROC?? - instance name of the application CLR process for .NET counters.
-->
</Add>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DeveloperModeWithDebuggerAttachedTelemetryModule, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.ExceptionTrackingTelemetryModule, Microsoft.AI.Web"/>
</TelemetryModules>
<TelemetryChannel Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel, Microsoft.AI.ServerTelemetryChannel"/>
<!--
</Add>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DeveloperModeWithDebuggerAttachedTelemetryModule, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.ExceptionTrackingTelemetryModule, Microsoft.AI.Web"/>
</TelemetryModules>
<TelemetryChannel Type="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel, Microsoft.AI.ServerTelemetryChannel"/>
<!--
Learn more about Application Insights configuration with ApplicationInsights.config here:
http://go.microsoft.com/fwlink/?LinkID=513840
Note: If not present, please add <InstrumentationKey>Your Key</InstrumentationKey> to the top of this file.
-->
<TelemetryInitializers>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureRoleEnvironmentTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DomainNameRoleInstanceTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.BuildInfoConfigComponentVersionTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DeviceTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.Web.SyntheticTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.ClientIpHeaderTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.UserAgentTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.OperationNameTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.OperationIdTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.UserTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.SessionTelemetryInitializer, Microsoft.AI.Web"/>
</TelemetryInitializers>
<!--
<TelemetryInitializers>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.AzureRoleEnvironmentTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DomainNameRoleInstanceTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.BuildInfoConfigComponentVersionTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.WindowsServer.DeviceTelemetryInitializer, Microsoft.AI.WindowsServer"/>
<Add Type="Microsoft.ApplicationInsights.Web.SyntheticTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.ClientIpHeaderTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.UserAgentTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.OperationNameTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.OperationIdTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.UserTelemetryInitializer, Microsoft.AI.Web"/>
<Add Type="Microsoft.ApplicationInsights.Web.SessionTelemetryInitializer, Microsoft.AI.Web"/>
</TelemetryInitializers>
<!--
Learn more about Application Insights configuration with ApplicationInsights.config here:
http://go.microsoft.com/fwlink/?LinkID=513840
Note: If not present, please add <InstrumentationKey>Your Key</InstrumentationKey> to the top of this file.
--></ApplicationInsights>
-->
</ApplicationInsights>
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ public override string StorageAccountName
get { return "[Your Azure Storage account name]"; }
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public void Init()
_userRegistrationReferenceProviderMock = new UserRegistrationReferenceProviderMock();

_annotationController = new AnnotationController(
_repository,
new TelemetryClient(),
_repository,
new TelemetryClient(),
new NotificationHandler(),
_userRegistrationReferenceProviderMock
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PhotoSharingApp.AppService.Controllers;
using PhotoSharingApp.AppService.Shared.Repositories;
using PhotoSharingApp.AppService.Tests.Helpers;
using PhotoSharingApp.AppService.Tests.Context;
using PhotoSharingApp.AppService.Tests.Helpers;

namespace PhotoSharingApp.AppService.Tests.Controllers
{
Expand All @@ -48,7 +48,7 @@ public void Init()
_userRegistrationReferenceProviderMock = new UserRegistrationReferenceProviderMock();

_categoryController = new CategoryController(
_repository,
_repository,
new TelemetryClient(),
_userRegistrationReferenceProviderMock);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// The MIT License (MIT)
Expand Down Expand Up @@ -82,4 +82,4 @@ public async Task GetHeroPhotosTest()
Assert.IsTrue(actionResult.Any(p => p.Id == photo3.Id), "photo3 wasn't returned as a hero photo");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using Microsoft.ApplicationInsights;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PhotoSharingApp.AppService.Controllers;
using PhotoSharingApp.AppService.Notifications;
using PhotoSharingApp.AppService.Shared.Repositories;
using PhotoSharingApp.AppService.Tests.Context;
using PhotoSharingApp.AppService.Tests.Helpers;
Expand All @@ -37,18 +38,20 @@ namespace PhotoSharingApp.AppService.Tests.Controllers
[TestClass]
public class ReportControllerTests : BaseTest
{
private INotificationHandler _notificationHandler;
private ReportController _reportController;
private IRepository _repository;
private UserRegistrationReferenceProviderMock _userRegistrationReferenceProviderMock;

[TestInitialize]
public void Init()
{
_notificationHandler = new NotificationHandler();
_repository = new DocumentDbRepository(new TestEnvironmentDefinition());
_userRegistrationReferenceProviderMock = new UserRegistrationReferenceProviderMock();

_reportController = new ReportController(_repository, new TelemetryClient(),
_userRegistrationReferenceProviderMock);
_notificationHandler, _userRegistrationReferenceProviderMock);
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PhotoSharingApp.AppService.Controllers;
using PhotoSharingApp.AppService.Shared.Repositories;
using PhotoSharingApp.AppService.Tests.Helpers;
using PhotoSharingApp.AppService.Tests.Context;
using PhotoSharingApp.AppService.Tests.Helpers;

namespace PhotoSharingApp.AppService.Tests.Controllers
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public async Task PhotoStatusChangeAfterReportsTest()
var maxReports = _environmentDefinition.MaxReports;

// Verify that every report before maxReports does not change photo status.
for (int i = 0; i < maxReports - 1; i++)
for (int i = 0; i < maxReports-1; i++)
{
var newUser = await _repository.CreateUser("test user " + System.DateTime.UtcNow.Ticks);
var newReport = CreateTestReport(photo.Id, ContentType.Photo, ReportReason.Spam, newUser.UserId);
Expand All @@ -202,7 +202,7 @@ public async Task PhotoStatusChangeAfterReportsTest()

// Sanity checks
Assert.AreEqual(PhotoStatus.Active, updatedPhoto.Status);
Assert.AreEqual(i + 1, updatedPhoto.Reports.Count);
Assert.AreEqual(i+1, updatedPhoto.Reports.Count);
}

var user2 = await _repository.CreateUser("test user " + System.DateTime.UtcNow.Ticks);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
using PhotoSharingApp.AppService.Notifications;
using PhotoSharingApp.AppService.Shared.Repositories;
using PhotoSharingApp.AppService.Shared.Validation;
using PhotoSharingApp.AppService.Tests.Helpers;
using PhotoSharingApp.AppService.Tests.Context;
using PhotoSharingApp.AppService.Tests.Helpers;

namespace PhotoSharingApp.AppService.Tests.E2E
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,19 @@ public async Task<AnnotationContract> PostAsync(AnnotationContract annotation)
var insertedAnnotation = await _repository.InsertAnnotation(annotation);

var photoContract = await _repository.GetPhoto(annotation.PhotoId);
var receiver = await _repository.GetUser(photoContract.User.UserId);
var goldBalance = receiver.GoldBalance;

try
{
_telemetryClient.TrackEvent("Gold received Push notification invoked.");

// Send push notification to the user receiving Gold
await
_notificationHandler.PushGoldReceivedNotificationAsync(PushNotificationPlatform.Windows,
_notificationHandler.SendPushAsync(PushNotificationPlatform.Windows,
"user:" + annotation.PhotoOwnerId,
"You have received GOLD!",
photoContract.ThumbnailUrl, annotation.PhotoId);
photoContract.ThumbnailUrl, annotation.PhotoId, goldBalance);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using Microsoft.ApplicationInsights;
using Microsoft.Azure.Mobile.Server.Config;
using PhotoSharingApp.AppService.Helpers;
using PhotoSharingApp.AppService.Notifications;
using PhotoSharingApp.AppService.ServiceCore;
using PhotoSharingApp.AppService.Shared;
using PhotoSharingApp.AppService.Shared.Repositories;
Expand All @@ -40,19 +41,23 @@ namespace PhotoSharingApp.AppService.Controllers
[MobileAppController]
public class ReportController : BaseController
{
private readonly INotificationHandler _notificationHandler;
private readonly IRepository _repository;
private readonly TelemetryClient _telemetryClient;

/// <summary>
/// Report controller constructor.
/// </summary>
/// <param name="notificationHandler">The notification handler.</param>
/// <param name="repository">The repository interface.</param>
/// <param name="telemetryClient">The telemetry client.</param>
/// <param name="userRegistrationReferenceProvider">The user registration reference provider.</param>
public ReportController(IRepository repository, TelemetryClient telemetryClient,
INotificationHandler notificationHandler,
IUserRegistrationReferenceProvider userRegistrationReferenceProvider)
: base(userRegistrationReferenceProvider)
{
_notificationHandler = notificationHandler;
_repository = repository;
_telemetryClient = telemetryClient;
}
Expand All @@ -71,7 +76,18 @@ public async Task<ReportContract> PostAsync(ReportContract report)
try
{
var registrationReference = await ValidateAndReturnCurrentUserId();
return await _repository.InsertReport(report, registrationReference);
var reportContract = await _repository.InsertReport(report, registrationReference);
var photoContract = await _repository.GetPhoto(reportContract.ContentId);

if (photoContract.Status == PhotoStatus.UnderReview)
{
await _notificationHandler.SendPushAsync(PushNotificationPlatform.Windows,
"user:" + photoContract.User.UserId,
"Your photo has been placed under review.",
photoContract.ThumbnailUrl, photoContract.Id);
}

return reportContract;
}
catch (DataLayerException ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public async Task<UserContract> UpdateUserProfile(UserContract user)
}

// Refreshing profile photo url
user.ProfilePhotoUrl = photo.ThumbnailUrl;
user.ProfilePhotoUrl = photo.StandardUrl;

var existingUser = await _repository.UpdateUser(user);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,19 @@ namespace PhotoSharingApp.AppService.Notifications
public interface INotificationHandler
{
/// <summary>
/// Sends a Push notification for receiving Gold to a specified registered user.
/// The thumbnail of the photo receiving gold is also sent.
/// Sends a rich push notification message with a thumbnail image and arguments to lauch the image
/// if the optional parameters are passed.
/// Otherwise, only a simple text push message is sent.
/// </summary>
/// <param name="platform">The platform specific notification service to use.</param>
/// <param name="userNotificationTag">The user notification tag to send notification to.</param>
/// <param name="message">The message to display on the notification toast.</param>
/// <param name="thumbnailUrl">The thumbnail Url of the photo to display in notification.</param>
/// <param name="photoId">The photoId of the photo to send as activation argument.</param>
/// <param name="thumbnailUrl">Optional - The thumbnail Url of the photo to display in notification.</param>
/// <param name="photoId">Optional - The photoId of the photo to send as activation argument.</param>
/// <param name="goldCount">Optional - The goldCount of the photo's user.</param>
/// <returns>HttpStatusCode of the request.</returns>
Task<HttpStatusCode> PushGoldReceivedNotificationAsync(PushNotificationPlatform platform,
string userNotificationTag, string message,
string thumbnailUrl, string photoId);

/// <summary>
/// Send a text push notification to a specified registered user.
/// </summary>
/// <param name="platform">The platform specific notification service to use.</param>
/// <param name="userNotificationTag">The user notification tag to send notification to.</param>
/// <param name="message">The message to display on the notification toast.</param>
/// <returns>HttpStatusCode of the request.</returns>
Task<HttpStatusCode> PushMessageNotificationAsync(PushNotificationPlatform platform, string userNotificationTag,
string message);
Task<HttpStatusCode> SendPushAsync(PushNotificationPlatform platform, string userNotificationTag,
string message,
string thumbnailUrl = "", string photoId = "", int goldCount = 0);
}
}
Loading

0 comments on commit b7b937a

Please sign in to comment.