start moving media into separate table
This commit is contained in:
@@ -91,24 +91,24 @@ namespace zero.Core.Api
|
||||
}
|
||||
|
||||
// find all media items in model
|
||||
List<ObjectTraverser.Result<Media>> media = ObjectTraverser.Find<Media>(model);
|
||||
//List<ObjectTraverser.Result<Media>> media = ObjectTraverser.Find<Media>(model);
|
||||
|
||||
// upload media items
|
||||
Dictionary<string, Media> mediaItems = new Dictionary<string, Media>();
|
||||
//Dictionary<string, Media> mediaItems = new Dictionary<string, Media>();
|
||||
|
||||
foreach (ObjectTraverser.Result<Media> item in media)
|
||||
{
|
||||
string id = item.Item?.Id;
|
||||
//foreach (ObjectTraverser.Result<Media> item in media)
|
||||
//{
|
||||
// string id = item.Item?.Id;
|
||||
|
||||
if (!Media.Upload(item.Item, out bool uploaded, out string uploadError))
|
||||
{
|
||||
return EntityResult<T>.Fail(item.Path, uploadError);
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaItems.Add(id, item.Item);
|
||||
}
|
||||
}
|
||||
// if (!Media.Upload(item.Item, out bool uploaded, out string uploadError))
|
||||
// {
|
||||
// return EntityResult<T>.Fail(item.Path, uploadError);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// mediaItems.Add(id, item.Item);
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (operation.Media != null)
|
||||
//{
|
||||
@@ -155,7 +155,11 @@ namespace zero.Core.Api
|
||||
|
||||
using (IAsyncDocumentSession session = Raven.OpenAsyncSession())
|
||||
{
|
||||
// store entity
|
||||
await session.StoreAsync(model);
|
||||
|
||||
// store media
|
||||
|
||||
await session.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,15 +44,18 @@ namespace zero.Core.Api
|
||||
return true;
|
||||
}
|
||||
|
||||
// generate new id
|
||||
media.Id = IdGenerator.Create();
|
||||
// set id to null in case it was prefixed to signal an upload
|
||||
media.Id = null;
|
||||
|
||||
// generate file id which is used as the folder name on disk
|
||||
media.FileId = IdGenerator.Create();
|
||||
|
||||
// get bytes for media content
|
||||
string byteString = media.Source.Split(SEP)[1];
|
||||
byte[] bytes = Convert.FromBase64String(byteString);
|
||||
|
||||
// build folder and full file path
|
||||
string folderPath = Path.Combine(Paths.Media, media.Id);
|
||||
string folderPath = Path.Combine(Paths.Media, media.FileId);
|
||||
string filePath = Path.Combine(folderPath, media.Name);
|
||||
|
||||
Paths.Create(folderPath);
|
||||
@@ -81,15 +84,19 @@ namespace zero.Core.Api
|
||||
Size = new Size(100, 100),
|
||||
Mode = ResizeMode.Max
|
||||
}));
|
||||
image.Save(filePath.Replace(extension, THUMB_EXTENSION + extension));
|
||||
|
||||
media.HasThumbnail = true;
|
||||
string thumbFileName = media.Name.Replace(extension, THUMB_EXTENSION + extension);
|
||||
string thumbSourcePath = Path.Combine(Paths.Media, media.FileId, thumbFileName);
|
||||
|
||||
image.Save(thumbSourcePath);
|
||||
|
||||
media.ThumbnailSource = Path.Combine(PATH_PREFIX, media.FileId, thumbFileName).Replace(Path.DirectorySeparatorChar, PATH_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
// set new properties
|
||||
media.LastModifiedDate = DateTimeOffset.Now;
|
||||
media.Source = Path.Combine(PATH_PREFIX, media.Id, media.Name).Replace(Path.DirectorySeparatorChar, PATH_SEPARATOR);
|
||||
media.Source = Path.Combine(PATH_PREFIX, media.FileId, media.Name).Replace(Path.DirectorySeparatorChar, PATH_SEPARATOR);
|
||||
media.Size = bytes.Length;
|
||||
|
||||
uploaded = true;
|
||||
|
||||
@@ -5,16 +5,16 @@ namespace zero.Core.Entities
|
||||
/// <summary>
|
||||
/// A media file (can contain an image or other media like videos and documents)
|
||||
/// </summary>
|
||||
public class Media : IMedia, IZeroDbConventions
|
||||
public class Media : ZeroEntity, IMedia
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name { get; set; }
|
||||
public string FileId { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FolderId { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string AlternativeText { get; set; }
|
||||
@@ -26,7 +26,7 @@ namespace zero.Core.Entities
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasThumbnail { get; set; }
|
||||
public string ThumbnailSource { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Size { get; set; }
|
||||
@@ -39,18 +39,20 @@ namespace zero.Core.Entities
|
||||
|
||||
/// <inheritdoc />
|
||||
public MediaFocalPoint FocalPoint { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string FolderId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public interface IMedia : IZeroIdEntity, IAppAwareEntity
|
||||
public interface IMedia : IZeroEntity, IAppAwareEntity, IZeroDbConventions
|
||||
{
|
||||
/// <summary>
|
||||
/// File name
|
||||
/// Id/name of the folder which is stored on disk/cloud
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string FileId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id of the media folder
|
||||
/// </summary>
|
||||
public string FolderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Alternative text which is used when the image can't be loaded
|
||||
@@ -68,9 +70,9 @@ namespace zero.Core.Entities
|
||||
string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this file has a thumbnail
|
||||
/// For images this is the source for a 100x100px thumbnail
|
||||
/// </summary>
|
||||
bool HasThumbnail { get; set; }
|
||||
string ThumbnailSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Filesize in bytes
|
||||
@@ -91,10 +93,5 @@ namespace zero.Core.Entities
|
||||
/// Optional focal point for an image
|
||||
/// </summary>
|
||||
MediaFocalPoint FocalPoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id of the folder
|
||||
/// </summary>
|
||||
public string FolderId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
/// <summary>
|
||||
/// A media folder contains media and other folders
|
||||
/// </summary>
|
||||
public class MediaFolder : ZeroEntity
|
||||
public class MediaFolder : ZeroEntity, IAppAwareEntity, IZeroDbConventions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parent folder id
|
||||
/// </summary>
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace zero.Core.Entities
|
||||
public string SecurityStamp { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Media Avatar { get; set; }
|
||||
public string AvatarId { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string LanguageId { get; set; }
|
||||
@@ -101,7 +101,7 @@ namespace zero.Core.Entities
|
||||
/// <summary>
|
||||
/// Avatar image
|
||||
/// </summary>
|
||||
Media Avatar { get; set; }
|
||||
string AvatarId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Backoffice display language
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
<ui-dropdown align="left bottom">
|
||||
<template v-slot:button>
|
||||
<button type="button" class="app-nav-account-button">
|
||||
<img class="-image" :src="user.avatar.source" :alt="user.name" />
|
||||
<img class="-image" v-if="user.avatar" :src="user.avatar.source" :alt="user.name" />
|
||||
<span class="-image" v-if="!user.avatar"><i class="fth-user"></i></span>
|
||||
<p class="-text"><strong>{{user.name}}</strong><br>{{user.email}}</p>
|
||||
<i class="-arrow fth-chevron-down"></i>
|
||||
</button>
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
page: true,
|
||||
groups: zero.settingsAreas,
|
||||
tokens: {
|
||||
'zero_version': '1.0.0-alpha.1',
|
||||
'plugin_count': 7
|
||||
'zero_version': zero.version,
|
||||
'plugin_count': zero.pluginCount
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
</ui-property>
|
||||
<ui-property label="@user.fields.avatar" description="@user.fields.avatar_text" :required="true">
|
||||
<ui-media :config="avatarConfig" v-model="model.avatar" :disabled="disabled" />
|
||||
<ui-media :config="avatarConfig" v-model="model.avatarId" :disabled="disabled" />
|
||||
</ui-property>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -165,7 +165,11 @@ a.app-nav-child
|
||||
width: 36px;
|
||||
border-radius: 18px;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
top: -1px;
|
||||
background: var(--color-bg-mid);
|
||||
text-align: center;
|
||||
line-height: 37px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.-text
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace zero.Web.Mapper
|
||||
target.IsSuper = source.IsSuper;
|
||||
target.Email = source.Email;
|
||||
target.IsEmailConfirmed = source.IsEmailConfirmed;
|
||||
target.Avatar = source.Avatar;
|
||||
target.AvatarId = source.AvatarId;
|
||||
target.LanguageId = source.LanguageId;
|
||||
target.Roles = source.Roles;
|
||||
target.Claims = source.Claims;
|
||||
@@ -37,7 +37,7 @@ namespace zero.Web.Mapper
|
||||
target.IsActive = source.IsActive;
|
||||
target.IsSuper = source.IsSuper;
|
||||
target.Email = source.Email;
|
||||
target.Avatar = source.Avatar;
|
||||
target.AvatarId = source.AvatarId;
|
||||
target.LanguageId = source.LanguageId;
|
||||
target.Roles = source.Roles;
|
||||
target.Claims = source.Claims;
|
||||
@@ -49,7 +49,7 @@ namespace zero.Web.Mapper
|
||||
target.Name = source.Name;
|
||||
target.IsActive = source.IsActive && (!source.LockoutEnabled || !source.LockoutEnd.HasValue);
|
||||
target.Email = source.Email;
|
||||
target.Avatar = source.Avatar?.Source;
|
||||
target.AvatarId = source.AvatarId;
|
||||
target.Roles = String.Join(", ", source.Roles); // TODO get name from alias
|
||||
});
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace zero.Web.Models
|
||||
|
||||
public bool IsEmailConfirmed { get; set; }
|
||||
|
||||
public Media Avatar { get; set; }
|
||||
public string AvatarId { get; set; }
|
||||
|
||||
public string LanguageId { get; set; }
|
||||
|
||||
|
||||
@@ -10,6 +10,6 @@
|
||||
|
||||
public string Roles { get; set; }
|
||||
|
||||
public string Avatar { get; set; }
|
||||
public string AvatarId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -15,6 +15,7 @@ using zero.Core.Extensions;
|
||||
using zero.Core.Identity;
|
||||
using zero.Core.Mapper;
|
||||
using zero.Core.Options;
|
||||
using zero.Core.Plugins;
|
||||
using zero.Web.Models;
|
||||
using zero.Web.Sections;
|
||||
|
||||
@@ -32,14 +33,17 @@ namespace zero.Web
|
||||
|
||||
protected IMapper Mapper { get; private set; }
|
||||
|
||||
protected IEnumerable<IZeroPlugin> Plugins { get; private set; }
|
||||
|
||||
public ZeroVue(IZeroOptions options, IWebHostEnvironment env, IApplicationsApi applicationsApi, IAuthenticationApi authenticationApi, IMapper mapper)
|
||||
|
||||
public ZeroVue(IZeroOptions options, IWebHostEnvironment env, IApplicationsApi applicationsApi, IAuthenticationApi authenticationApi, IMapper mapper, IEnumerable<IZeroPlugin> plugins)
|
||||
{
|
||||
Environment = env;
|
||||
Options = options;
|
||||
ApplicationsApi = applicationsApi;
|
||||
AuthenticationApi = authenticationApi;
|
||||
Mapper = mapper;
|
||||
Plugins = plugins;
|
||||
//zero.path = "@Model.BackofficePath.EnsureEndsWith('/')";
|
||||
//zero.translations = @Html.Raw(text);
|
||||
}
|
||||
@@ -53,6 +57,8 @@ namespace zero.Web
|
||||
config.Path = Options.BackofficePath.EnsureEndsWith('/');
|
||||
config.ApiPath = config.Path + "api/";
|
||||
config.PluginPath = "@/Plugins";
|
||||
config.Version = Options.ZeroVersion;
|
||||
config.PluginCount = 2; // TODO Plugins.Count();
|
||||
config.ErrorFieldNone = Constants.ErrorFieldNone;
|
||||
config.Sections = CreateSections();
|
||||
config.Translations = CreateTranslations();
|
||||
@@ -253,6 +259,10 @@ namespace zero.Web
|
||||
|
||||
public string PluginPath { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public int PluginCount { get; set; }
|
||||
|
||||
public string ErrorFieldNone { get; set; }
|
||||
|
||||
public UserEditModel User { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user