Add image management functionality: introduce Image entity and related API endpoints, update database schema to support image storage, and enhance UI with a new gallery feature for image selection and upload. Update translations for gallery-related terms.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
|
||||
namespace TeleWave.Infrastructure.Media;
|
||||
|
||||
/// <summary>Файловое хранилище общего реестра изображений: images/{imageId}{ext}.</summary>
|
||||
public sealed class ImageStore(MediaPathResolver paths) : IImageStore
|
||||
{
|
||||
public async Task SaveAsync(
|
||||
Guid imageId,
|
||||
string extension,
|
||||
Stream content,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
Directory.CreateDirectory(paths.ImagesDir);
|
||||
var path = paths.ImagePath(imageId, Normalize(extension));
|
||||
await using var fs = File.Create(path);
|
||||
await content.CopyToAsync(fs, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task SaveAsync(
|
||||
Guid imageId,
|
||||
string extension,
|
||||
byte[] content,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
Directory.CreateDirectory(paths.ImagesDir);
|
||||
var path = paths.ImagePath(imageId, Normalize(extension));
|
||||
await File.WriteAllBytesAsync(path, content, cancellationToken);
|
||||
}
|
||||
|
||||
public void Delete(Guid imageId, string extension)
|
||||
{
|
||||
var path = paths.ImagePath(imageId, Normalize(extension));
|
||||
if (File.Exists(path))
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
public string? ResolvePath(Guid imageId, string extension)
|
||||
{
|
||||
var path = paths.ImagePath(imageId, Normalize(extension));
|
||||
return File.Exists(path) ? path : null;
|
||||
}
|
||||
|
||||
private static string Normalize(string extension) =>
|
||||
extension.StartsWith('.') ? extension : "." + extension;
|
||||
}
|
||||
@@ -19,6 +19,7 @@ public sealed class MediaPathResolver
|
||||
AssetsDir = Path.Combine(_root, "assets");
|
||||
BumpersDir = Path.Combine(_root, "bumpers");
|
||||
MetadataDir = Path.Combine(_root, "metadata");
|
||||
ImagesDir = Path.Combine(_root, "images");
|
||||
}
|
||||
|
||||
public string InboxDir { get; }
|
||||
@@ -32,6 +33,9 @@ public sealed class MediaPathResolver
|
||||
/// <summary>Картинки метаданных (постеры/кадры), скачанные локально.</summary>
|
||||
public string MetadataDir { get; }
|
||||
|
||||
/// <summary>Общий реестр изображений (галерея): файлы images/{imageId}{ext}.</summary>
|
||||
public string ImagesDir { get; }
|
||||
|
||||
public void EnsureDirectories()
|
||||
{
|
||||
Directory.CreateDirectory(InboxDir);
|
||||
@@ -40,6 +44,7 @@ public sealed class MediaPathResolver
|
||||
Directory.CreateDirectory(AssetsDir);
|
||||
Directory.CreateDirectory(BumpersDir);
|
||||
Directory.CreateDirectory(MetadataDir);
|
||||
Directory.CreateDirectory(ImagesDir);
|
||||
}
|
||||
|
||||
public string MetadataShowDir(Guid showId) =>
|
||||
@@ -86,6 +91,10 @@ public sealed class MediaPathResolver
|
||||
public string BumperTemplateFilePath(Guid templateId, string kind, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(BumpersDir, templateId.ToString("N"), kind + extension));
|
||||
|
||||
/// <summary>Путь к файлу изображения общего реестра (extension — с точкой).</summary>
|
||||
public string ImagePath(Guid imageId, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(ImagesDir, imageId.ToString("N") + extension));
|
||||
|
||||
public string OriginalPath(Guid assetId, string extension) =>
|
||||
EnsureWithinRoot(Path.Combine(OriginalsDir, assetId.ToString("N") + extension));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user