Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Refresh.Database/GameDatabaseContext.Playlists.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,19 @@ public GamePlaylist CreateRootPlaylist(GameUser user)
public GamePlaylist? GetUserRootPlaylist(GameUser user)
=> this.GamePlaylistsIncluded.FirstOrDefault(p => p.IsRoot && p.PublisherId == user.UserId);

public void UpdatePlaylist(GamePlaylist playlist, ISerializedCreatePlaylistInfo updateInfo)
public GamePlaylist UpdatePlaylist(GamePlaylist playlist, ISerializedCreatePlaylistInfo updateInfo)
{
GameLocation location = updateInfo.Location ?? new GameLocation(playlist.LocationX, playlist.LocationY);

this.Write(() =>
{
playlist.Name = updateInfo.Name ?? playlist.Name;
playlist.Description = updateInfo.Description ?? playlist.Description;
playlist.IconHash = updateInfo.Icon ?? playlist.IconHash;
playlist.LocationX = location.X;
playlist.LocationY = location.Y;
playlist.LastUpdateDate = this._time.Now;
});
playlist.Name = updateInfo.Name ?? playlist.Name;
playlist.Description = updateInfo.Description ?? playlist.Description;
playlist.IconHash = updateInfo.Icon ?? playlist.IconHash;
playlist.LocationX = location.X;
playlist.LocationY = location.Y;
playlist.LastUpdateDate = this._time.Now;
this.SaveChanges();

return playlist;
}

public void DeletePlaylist(GamePlaylist playlist)
Expand Down
4 changes: 2 additions & 2 deletions Refresh.Database/Query/ISerializedCreatePlaylistInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ namespace Refresh.Database.Query;

public interface ISerializedCreatePlaylistInfo
{
string Name { get; }
string Description { get; }
string? Name { get; }
string? Description { get; }
string? Icon { get; }
GameLocation? Location { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,16 @@ public class ApiNotFoundError : ApiError

public const string VerifiedIpMissingErrorWhen = "The verified IP could not be found";
public static readonly ApiNotFoundError VerifiedIpMissingError = new(VerifiedIpMissingErrorWhen);


public const string PlaylistMissingErrorWhen = "The playlist could not be found";
public static readonly ApiNotFoundError PlaylistMissingError = new(PlaylistMissingErrorWhen);

public const string ParentPlaylistMissingErrorWhen = "The parent playlist could not be found";
public static readonly ApiNotFoundError ParentPlaylistMissingError = new(ParentPlaylistMissingErrorWhen);

public const string SubPlaylistMissingErrorWhen = "The sub-playlist could not be found";
public static readonly ApiNotFoundError SubPlaylistMissingError = new(SubPlaylistMissingErrorWhen);

private ApiNotFoundError() : base("The requested resource was not found", NotFound)
{}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public class ApiValidationError : ApiError
public const string IpAddressParseErrorWhen = "The IP address could not be parsed by the server";
public static readonly ApiValidationError IpAddressParseError = new(IpAddressParseErrorWhen);

public const string InvalidPlaylistIdWhen = "The playlist ID couldn't be parsed by the server";
public static readonly ApiValidationError InvalidPlaylistId = new(InvalidPlaylistIdWhen);

public const string NoPhotoDeletionPermissionErrorWhen = "You do not have permission to delete someone else's photo";
public static readonly ApiValidationError NoPhotoDeletionPermissionError = new(NoPhotoDeletionPermissionErrorWhen);

Expand Down Expand Up @@ -52,6 +55,12 @@ public class ApiValidationError : ApiError

public const string BodyMustBeImageErrorWhen = "The asset must be a PNG/JPEG file";
public static readonly ApiValidationError BodyMustBeImageError = new(BodyMustBeImageErrorWhen);

public const string IconMustBeImageErrorWhen = "The icon must be a PNG/JPEG file";
public static readonly ApiValidationError IconMustBeImageError = new(IconMustBeImageErrorWhen);

public const string IconMissingErrorWhen = "The icon is missing from the server";
public static readonly ApiValidationError IconMissingError = new(IconMissingErrorWhen);

public const string ResourceExistsErrorWhen = "The resource you are attempting to create already exists.";
public static readonly ApiValidationError ResourceExistsError = new(ResourceExistsErrorWhen);
Expand Down Expand Up @@ -88,7 +97,13 @@ public class ApiValidationError : ApiError

public const string UsernameTakenErrorWhen = "This username is already taken!";
public static readonly ApiValidationError UsernameTakenError = new(UsernameTakenErrorWhen);


public const string NoPlaylistEditPermissionErrorWhen = "You do not have permission to update this playlist";
public static readonly ApiValidationError NoPlaylistEditPermissionError = new(NoPlaylistEditPermissionErrorWhen);

public const string NoPlaylistDeletePermissionErrorWhen = "You do not have permission to delete this playlist";
public static readonly ApiValidationError NoPlaylistDeletePermissionError = new(NoPlaylistDeletePermissionErrorWhen);

// TODO: Split off error messages which are actually 401 or anything else that isn't 400
public ApiValidationError(string message) : base(message) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Refresh.Database.Models;
using Refresh.Database.Query;

namespace Refresh.Interfaces.APIv3.Endpoints.DataTypes.Request;

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class ApiPlaylistCreationRequest : ISerializedCreatePlaylistInfo
{
public string? Name { get; set; }
public string? Icon { get; set; }
public string? Description { get; set; }
public GameLocation? Location { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Refresh.Core.Types.Data;
using Refresh.Database.Models.Playlists;

namespace Refresh.Interfaces.APIv3.Endpoints.DataTypes.Response.Playlists;

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class ApiGamePlaylistOwnRelationsResponse
{
public bool IsHearted { get; set; }

public static ApiGamePlaylistOwnRelationsResponse? FromOld(GamePlaylist? old, DataContext dataContext)
{
if (old == null || dataContext.User == null) return null;

return new()
{
IsHearted = dataContext.Database.IsPlaylistFavouritedByUser(old, dataContext.User),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Diagnostics;
using Refresh.Core.Types.Data;
using Refresh.Database.Models.Playlists;
using Refresh.Interfaces.APIv3.Endpoints.DataTypes.Response.Data;
using Refresh.Interfaces.APIv3.Endpoints.DataTypes.Response.Users;

namespace Refresh.Interfaces.APIv3.Endpoints.DataTypes.Response.Playlists;

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class ApiGamePlaylistResponse : IApiResponse, IDataConvertableFrom<ApiGamePlaylistResponse, GamePlaylist>
{
public required int PlaylistId { get; set; }
public required ApiGameUserResponse? Publisher { get; set; }

public required string Name { get; set; }
public required string IconHash { get; set; }
public required string Description { get; set; }
public required ApiGameLocationResponse Location { get; set; }

public required DateTimeOffset CreationDate { get; set; }
public required DateTimeOffset UpdateDate { get; set; }

public ApiGamePlaylistStatisticsResponse? Statistics { get; set; }
public ApiGamePlaylistOwnRelationsResponse? OwnRelations { get; set; }

public static ApiGamePlaylistResponse? FromOld(GamePlaylist? playlist, DataContext dataContext)
{
if (playlist == null) return null;

if (playlist.Statistics == null)
dataContext.Database.RecalculatePlaylistStatistics(playlist);

Debug.Assert(playlist.Statistics != null);

return new()
{
PlaylistId = playlist.PlaylistId,
Publisher = ApiGameUserResponse.FromOld(playlist.Publisher, dataContext),
Name = playlist.Name,
IconHash = dataContext.GetIconFromHash(playlist.IconHash),
Description = playlist.Description,
Location = ApiGameLocationResponse.FromLocation(playlist.LocationX, playlist.LocationY)!,
CreationDate = playlist.CreationDate,
UpdateDate = playlist.LastUpdateDate,
Statistics = ApiGamePlaylistStatisticsResponse.FromOld(playlist.Statistics, dataContext),
OwnRelations = ApiGamePlaylistOwnRelationsResponse.FromOld(playlist, dataContext),
};
}

public static IEnumerable<ApiGamePlaylistResponse> FromOldList(IEnumerable<GamePlaylist> oldList, DataContext dataContext)
=> oldList.Select(old => FromOld(old, dataContext)).ToList()!;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Refresh.Core.Types.Data;
using Refresh.Database.Models.Statistics;

namespace Refresh.Interfaces.APIv3.Endpoints.DataTypes.Response.Playlists;

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class ApiGamePlaylistStatisticsResponse
{
public required int Levels { get; set; }
public required int SubPlaylists { get; set; }
public required int ParentPlaylists { get; set; }
public required int Hearts { get; set; }

public static ApiGamePlaylistStatisticsResponse? FromOld(GamePlaylistStatistics? old, DataContext dataContext)
{
if (old == null) return null;

return new()
{
Levels = old.LevelCount,
SubPlaylists = old.SubPlaylistCount,
ParentPlaylists = old.ParentPlaylistCount,
Hearts = old.FavouriteCount,
};
}
}
Loading