1+ using System . Net . Mime ;
2+ using Asp . Versioning ;
3+ using Microsoft . AspNetCore . Mvc ;
4+ using Microsoft . EntityFrameworkCore ;
5+ using OpenShock . API . Models . Requests ;
6+ using OpenShock . API . Services . DeviceUpdate ;
7+ using OpenShock . Common . Authentication . Attributes ;
8+ using OpenShock . Common . Errors ;
9+ using OpenShock . Common . Models ;
10+ using OpenShock . Common . Problems ;
11+
12+ namespace OpenShock . API . Controller . Shares . UserShares ;
13+
14+ public sealed partial class UserSharesController
15+ {
16+ /// <summary>
17+ /// Update user shares for a shocker
18+ /// </summary>
19+ /// <param name="userId"></param>
20+ /// <param name="body"></param>
21+ /// <param name="deviceUpdateService"></param>
22+ /// <response code="200">Successfully updated share code</response>
23+ /// <response code="404">The share code does not exist or you do not have access to it.</response>
24+ [ HttpPatch ( "{userId:guid}/shockers" ) ]
25+ [ TokenPermission ( PermissionType . Shockers_Edit ) ]
26+ [ Consumes ( MediaTypeNames . Application . Json ) ]
27+ [ ProducesResponseType ( StatusCodes . Status200OK ) ]
28+ [ ProducesResponseType < OpenShockProblem > ( StatusCodes . Status404NotFound ,
29+ MediaTypeNames . Application . ProblemJson ) ] // ShockerNotFound
30+ [ MapToApiVersion ( "2" ) ]
31+ public async Task < IActionResult > BulkUserShareShockersUpdate (
32+ [ FromRoute ] Guid userId ,
33+ [ FromBody ] BulkUserShareShockersUpdateRequest body ,
34+ [ FromServices ] IDeviceUpdateService deviceUpdateService )
35+ {
36+ var affected = await _db . UserShares . Where ( x =>
37+ body . Shockers . Contains ( x . ShockerId ) && x . SharedWithUserId == userId &&
38+ x . Shocker . Device . OwnerId == CurrentUser . Id ) . Select ( x =>
39+ new { Share = x , x . Shocker . DeviceId , Owner = x . Shocker . Device . OwnerId } )
40+ . ToArrayAsync ( ) ;
41+
42+ var missingShockers = body . Shockers . Except ( affected . Select ( x => x . Share . ShockerId ) ) . ToArray ( ) ;
43+ if ( missingShockers . Length > 0 )
44+ {
45+ return Problem ( ShockerError . ShockerNotFound ) ;
46+ }
47+
48+ foreach ( var share in affected )
49+ {
50+ share . Share . AllowShock = body . Permissions . Shock ;
51+ share . Share . AllowVibrate = body . Permissions . Vibrate ;
52+ share . Share . AllowSound = body . Permissions . Sound ;
53+ share . Share . AllowLiveControl = body . Permissions . Live ;
54+ share . Share . MaxIntensity = body . Limits . Intensity ;
55+ share . Share . MaxDuration = body . Limits . Duration ;
56+
57+ _db . UserShares . Update ( share . Share ) ;
58+ }
59+
60+ await _db . SaveChangesAsync ( ) ;
61+
62+ var uniqueHubIds = affected . Select ( x => x . Share . Shocker . DeviceId ) . Distinct ( ) ;
63+ var updateTasks = uniqueHubIds . Select ( device =>
64+ deviceUpdateService . UpdateDevice ( CurrentUser . Id , device , DeviceUpdateType . ShockerUpdated , userId ) ) ;
65+ await Task . WhenAll ( updateTasks ) ;
66+
67+ return Ok ( ) ;
68+ }
69+ }
70+
71+ public sealed class BulkUserShareShockersUpdateRequest : ShockerPermLimitPair
72+ {
73+ public required IReadOnlyList < Guid > Shockers { get ; set ; }
74+ }
0 commit comments