public async Task ActiveItemsChanged(string userId, FocusManageResult result) { foreach (var item in result.ActiveItems) { await NotifyOrInstall(userId, item); } }
public async Task RefreshGeofencesForActiveNavigations(string userId, FocusManageResult manageResult, DateTimeOffset now) { var freshFences = await GetNewGeofencesForActiveNavigations(userId, manageResult, now); await _locationStore.AddGeofenceRequests(userId, freshFences); }
private async Task <DateTimeOffset?> RequestLocationForItems(string userId, FocusManageResult manageResult, DateTimeOffset now, DateTimeOffset locationTimeStamp) { var candidates = manageResult.ActiveItems.Where( v => null != v.DirectionsMetadata && null != v.Directions && v.DirectionsMetadata.TravelStatus != TravelStatus.Finished); var requirement = UpdateTimes(candidates, now, locationTimeStamp).OrderBy(v => v.Time).FirstOrDefault(); if (null != requirement) { await logger.LogForFocusItem(userId, requirement.FocusItem.Id, $"Location update for {requirement.Reason} {requirement.FocusItem.CalendarEvent?.Subject} at {requirement.Time:t}"); if (requirement.Time < now + FocusConstants.ShortestLocationUpdateTime) { return(now + FocusConstants.ShortestLocationUpdateTime); } return(requirement.Time); } return(null); }
public async Task <FocusManageResult> Update(string userId, FocusUpdateRequest focusUpdateRequest) { if (null != focusUpdateRequest.Location) { await _focusGeofenceService.UpdateFocusItems(userId, focusUpdateRequest.Location); } var res = new FocusManageResult(); var activeItems = await focusStore.GetActiveAsync(userId); var updatedItemIds = new HashSet <string>(focusUpdateRequest.ItemSyncResult != null ? focusUpdateRequest.ItemSyncResult.ChangedItems.Select(v => v.Id) : new string[0]); foreach (var item in activeItems) { var evt = await calendarServiceClient.Users[userId].Feeds[item.CalendarEventFeedId].Events.Get(item.CalendarEventId); TransitDirections directions; if (null != focusUpdateRequest.ItemSyncResult && ( focusUpdateRequest.ItemSyncResult.AddedItems.Any(v => v.Id == item.Id) || focusUpdateRequest.ItemSyncResult.ChangedItems.Any(v => v.Id == item.Id)) || null == item.DirectionsMetadata?.Key) { directions = await GetFreshDirections(userId, evt, item, focusUpdateRequest.Location); } else { var directionsRes = await GetCachedDirectionsOrNew(userId, evt, item, focusUpdateRequest.Location); directions = directionsRes.Directions; if (directionsRes.IsNew) { updatedItemIds.Add(item.Id); } if (null != directions && null != focusUpdateRequest.ChangedDirections && focusUpdateRequest.ChangedDirections.Contains( item.DirectionsMetadata.Key)) { await logger.LogForFocusItem(userId, item.Id, $"Received direction updates for {evt.Subject}", DigitTraceAction.DirectionsUpdate); updatedItemIds.Add(item.Id); } } DateTimeOffset indicateTime; if (null == directions) { await logger.LogForFocusItem(userId, item.Id, $"No departure time found, using {FocusConstants.DefaultTravelTime.TotalMinutes:0} minutes for {evt.Subject}"); indicateTime = evt.Start - FocusConstants.DefaultTravelTime; } else { indicateTime = directions.Routes[item.DirectionsMetadata.PeferredRoute].DepatureTime; } item.IndicateTime = indicateTime; await focusStore.UpdateIndicateTime(item.Id, indicateTime); res.ActiveItems.Add(new FocusItemWithExternalData() { Start = item.Start, IndicateTime = item.IndicateTime, CalendarEvent = evt, Directions = directions, DirectionsMetadata = item.DirectionsMetadata, End = item.End, Id = item.Id }); } await _focusGeofenceService.RefreshGeofencesForActiveNavigations(userId, res, DateTimeOffset.Now); var active = await focusStore.GetActiveItem(userId); var activeItemChanged = await focusStore.UpdateActiveItem(userId, active?.Id); if (activeItemChanged || (null != active && updatedItemIds.Contains(active.Id))) { if (null != active) { await Task.WhenAll(focusSubscribers.Select(v => v.ActiveItemChanged(userId, res.ActiveItems.Where(d => d.Id == active.Id).Single()))); } else { await Task.WhenAll(focusSubscribers.Select(v => v.ActiveItemChanged(userId, null))); } } if (updatedItemIds.Count > 0) { await Task.WhenAll(focusSubscribers.Select(v => v.ActiveItemsChanged(userId, res))); } return(res); }
public async Task ActiveItemsChanged(string userId, FocusManageResult res) { await hubContext.Clients.User(userId).SendAsync("focusChanged", res.ActiveItems); }
public async Task <GeofenceRequest[]> GetNewGeofencesForActiveNavigations(string userId, FocusManageResult manageResult, DateTimeOffset now) { var geofences = manageResult.ActiveItems.Where(v => null != v.DirectionsMetadata && null == v.DirectionsMetadata.Error) .Where(v => v.Directions.Routes[v.DirectionsMetadata.PeferredRoute].DepatureTime - now < FocusConstants.DeparturePending) .SelectMany(item => GetGeofences(item)); return((await Task.WhenAll(geofences.Select(async gfr => new { gfr, exists = await _locationStore.Exists(userId, gfr) }))) .Where(v => !v.exists).Select(v => v.gfr).ToArray()); }
public Task ActiveItemsChanged(string userId, FocusManageResult res) { return(Task.CompletedTask); }
public async Task <LocationRequestResult> RequestLocationAsync(string userId, DateTimeOffset requestTime, FocusManageResult focusManageResult) { var storedLocation = await locationStore.GetLastLocationAsync(userId); bool requestLocation = false; string requestReason = null; if (null == storedLocation) { requestLocation = true; requestReason = "No Location stored"; } else if (storedLocation.Timestamp < (requestTime - FocusConstants.LastLocationCacheTime)) { requestLocation = true; requestReason = $"Last Location outdated {(requestTime - storedLocation.Timestamp).TotalMinutes:0}"; } if (requestLocation) { var res = await pushSyncService.RequestLocationSync(userId, requestTime, requestTime.Add(FocusConstants.LocationRequestExpectedTime)); return(new LocationRequestResult() { LocationRequestSent = res.SyncRequested, LocationRequestTime = res.SyncRequested ? requestTime : res.SyncPendingFor }); } else { await logger.LogForUser(userId, $"Not requesting location because cached location from {storedLocation.Timestamp:s} is used"); return(new LocationRequestResult() { LocationRequestSent = false, LocationRequestTime = null }); } }
public async Task <LocationResponse> LocationUpdateReceivedAsync(string userId, Location location, DateTimeOffset now, FocusManageResult focusManageResult) { await pushSyncService.SetLocationRequestDone(userId); await locationStore.UpdateLocationAsync(userId, location); //if (location.RequestSupport.HasValue && !location.RequestSupport.Value) //{ // return new LocationResponse(); //} var response = new LocationResponse() { NextUpdateRequiredAt = await RequestLocationForItems(userId, focusManageResult, now, location.Timestamp), Geofences = await locationStore.GetActiveGeofenceRequests(userId, now) }; if (response.NextUpdateRequiredAt.HasValue) { await pushSyncService.SetLocationRequestedExternal(userId, response.NextUpdateRequiredAt.Value); } return(response); }