Implemented basic theme feature. Missing are import, export and asset proxy
This commit is contained in:
parent
f57aac4f6c
commit
a67829035e
|
@ -16,6 +16,12 @@ public class ConfigV1
|
||||||
|
|
||||||
[JsonProperty("Store")] public StoreData Store { get; set; } = new();
|
[JsonProperty("Store")] public StoreData Store { get; set; } = new();
|
||||||
|
|
||||||
|
[JsonProperty("Theme")] public ThemeData Theme { get; set; } = new();
|
||||||
|
public class ThemeData
|
||||||
|
{
|
||||||
|
[JsonProperty("EnableDefault")] public bool EnableDefault { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
||||||
public class StoreData
|
public class StoreData
|
||||||
{
|
{
|
||||||
[JsonProperty("Currency")]
|
[JsonProperty("Currency")]
|
||||||
|
|
|
@ -35,6 +35,9 @@ public class DataContext : DbContext
|
||||||
public DbSet<Ticket> Tickets { get; set; }
|
public DbSet<Ticket> Tickets { get; set; }
|
||||||
public DbSet<TicketMessage> TicketMessages { get; set; }
|
public DbSet<TicketMessage> TicketMessages { get; set; }
|
||||||
|
|
||||||
|
// Themes
|
||||||
|
public DbSet<Theme> Themes { get; set; }
|
||||||
|
|
||||||
public DataContext(ConfigService configService)
|
public DataContext(ConfigService configService)
|
||||||
{
|
{
|
||||||
ConfigService = configService;
|
ConfigService = configService;
|
||||||
|
|
13
Moonlight/App/Database/Entities/Theme.cs
Normal file
13
Moonlight/App/Database/Entities/Theme.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
namespace Moonlight.App.Database.Entities;
|
||||||
|
|
||||||
|
public class Theme
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
public string Author { get; set; } = "";
|
||||||
|
public string? DonateUrl { get; set; } = "";
|
||||||
|
public string CssUrl { get; set; } = "";
|
||||||
|
public string? JsUrl { get; set; } = "";
|
||||||
|
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
}
|
697
Moonlight/App/Database/Migrations/20231222100225_AddThemeModel.Designer.cs
generated
Normal file
697
Moonlight/App/Database/Migrations/20231222100225_AddThemeModel.Designer.cs
generated
Normal file
|
@ -0,0 +1,697 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Moonlight.App.Database;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Moonlight.App.Database.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DataContext))]
|
||||||
|
[Migration("20231222100225_AddThemeModel")]
|
||||||
|
partial class AddThemeModel
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "7.0.2");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.Post", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AuthorId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Content")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AuthorId");
|
||||||
|
|
||||||
|
b.ToTable("Posts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.PostComment", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AuthorId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Content")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("PostId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AuthorId");
|
||||||
|
|
||||||
|
b.HasIndex("PostId");
|
||||||
|
|
||||||
|
b.ToTable("PostComments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.PostLike", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("PostId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PostId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("PostLikes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.WordFilter", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Filter")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("WordFilters");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Category", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Categories");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Coupon", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Amount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Code")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Percent")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Coupons");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.CouponUse", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("CouponId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CouponId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("CouponUses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.GiftCode", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Amount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Code")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<double>("Value")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("GiftCodes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.GiftCodeUse", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("GiftCodeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("GiftCodeId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("GiftCodeUses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Product", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConfigJson")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Duration")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("MaxPerUser")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<double>("Price")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("Slug")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Stock")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.ToTable("Products");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Service", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConfigJsonOverride")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Nickname")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("OwnerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ProductId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("RenewAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Suspended")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
|
b.HasIndex("ProductId");
|
||||||
|
|
||||||
|
b.ToTable("Services");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.ServiceShare", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("ServiceId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServiceId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("ServiceShares");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Transaction", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("Price")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("Text")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("Transaction");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Theme", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CssUrl")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("DonateUrl")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Enabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("JsUrl")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Themes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Tickets.Ticket", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("CreatorId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Open")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Priority")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("ServiceId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Tries")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CreatorId");
|
||||||
|
|
||||||
|
b.HasIndex("ServiceId");
|
||||||
|
|
||||||
|
b.ToTable("Tickets");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Tickets.TicketMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Attachment")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Content")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSupport")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("SenderId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("TicketId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SenderId");
|
||||||
|
|
||||||
|
b.HasIndex("TicketId");
|
||||||
|
|
||||||
|
b.ToTable("TicketMessages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Avatar")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<double>("Balance")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Flags")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Permissions")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TokenValidTimestamp")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("TotpKey")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.Post", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", "Author")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AuthorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Author");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.PostComment", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", "Author")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AuthorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Community.Post", null)
|
||||||
|
.WithMany("Comments")
|
||||||
|
.HasForeignKey("PostId");
|
||||||
|
|
||||||
|
b.Navigation("Author");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.PostLike", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Community.Post", null)
|
||||||
|
.WithMany("Likes")
|
||||||
|
.HasForeignKey("PostId");
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.CouponUse", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Store.Coupon", "Coupon")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CouponId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", null)
|
||||||
|
.WithMany("CouponUses")
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
|
||||||
|
b.Navigation("Coupon");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.GiftCodeUse", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Store.GiftCode", "GiftCode")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GiftCodeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", null)
|
||||||
|
.WithMany("GiftCodeUses")
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
|
||||||
|
b.Navigation("GiftCode");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Product", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Store.Category", "Category")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Service", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Store.Product", "Product")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ProductId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
|
||||||
|
b.Navigation("Product");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.ServiceShare", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Store.Service", null)
|
||||||
|
.WithMany("Shares")
|
||||||
|
.HasForeignKey("ServiceId");
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Transaction", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", null)
|
||||||
|
.WithMany("Transactions")
|
||||||
|
.HasForeignKey("UserId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Tickets.Ticket", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", "Creator")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CreatorId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Store.Service", "Service")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServiceId");
|
||||||
|
|
||||||
|
b.Navigation("Creator");
|
||||||
|
|
||||||
|
b.Navigation("Service");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Tickets.TicketMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.User", "Sender")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("SenderId");
|
||||||
|
|
||||||
|
b.HasOne("Moonlight.App.Database.Entities.Tickets.Ticket", null)
|
||||||
|
.WithMany("Messages")
|
||||||
|
.HasForeignKey("TicketId");
|
||||||
|
|
||||||
|
b.Navigation("Sender");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Community.Post", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Comments");
|
||||||
|
|
||||||
|
b.Navigation("Likes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Store.Service", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Shares");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Tickets.Ticket", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Messages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("CouponUses");
|
||||||
|
|
||||||
|
b.Navigation("GiftCodeUses");
|
||||||
|
|
||||||
|
b.Navigation("Transactions");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Moonlight.App.Database.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddThemeModel : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Themes",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
Author = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
DonateUrl = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
CssUrl = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
JsUrl = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Enabled = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Themes", x => x.Id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Themes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -357,6 +357,38 @@ namespace Moonlight.App.Database.Migrations
|
||||||
b.ToTable("Transaction");
|
b.ToTable("Transaction");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Theme", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("CssUrl")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("DonateUrl")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("Enabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("JsUrl")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Themes");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Tickets.Ticket", b =>
|
modelBuilder.Entity("Moonlight.App.Database.Entities.Tickets.Ticket", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
|
12
Moonlight/App/Models/Abstractions/ApplicationTheme.cs
Normal file
12
Moonlight/App/Models/Abstractions/ApplicationTheme.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Moonlight.App.Models.Abstractions;
|
||||||
|
|
||||||
|
public class ApplicationTheme
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
public string Author { get; set; } = "";
|
||||||
|
public string? DonateUrl { get; set; } = "";
|
||||||
|
public string CssUrl { get; set; } = "";
|
||||||
|
public string? JsUrl { get; set; } = "";
|
||||||
|
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
}
|
23
Moonlight/App/Models/Forms/Admin/Sys/Themes/AddThemeForm.cs
Normal file
23
Moonlight/App/Models/Forms/Admin/Sys/Themes/AddThemeForm.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Models.Forms.Admin.Sys.Themes;
|
||||||
|
|
||||||
|
public class AddThemeForm
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "You need to specify a name for your theme")]
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify an author for your theme")]
|
||||||
|
public string Author { get; set; } = "";
|
||||||
|
|
||||||
|
[Description("Enter a url to date for your theme here in order to show up when other people use this theme")]
|
||||||
|
public string? DonateUrl { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify a style sheet url")]
|
||||||
|
[Description("A url to your stylesheet")]
|
||||||
|
public string CssUrl { get; set; } = "";
|
||||||
|
|
||||||
|
[Description("(Optional) A url to your javascript file")]
|
||||||
|
public string? JsUrl { get; set; } = null;
|
||||||
|
}
|
26
Moonlight/App/Models/Forms/Admin/Sys/Themes/EditThemeForm.cs
Normal file
26
Moonlight/App/Models/Forms/Admin/Sys/Themes/EditThemeForm.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Models.Forms.Admin.Sys.Themes;
|
||||||
|
|
||||||
|
public class EditThemeForm
|
||||||
|
{
|
||||||
|
[Required(ErrorMessage = "You need to specify a name for your theme")]
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify an author for your theme")]
|
||||||
|
public string Author { get; set; } = "";
|
||||||
|
|
||||||
|
[Description("Enter a url to date for your theme here in order to show up when other people use this theme")]
|
||||||
|
public string? DonateUrl { get; set; } = "";
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "You need to specify a style sheet url")]
|
||||||
|
[Description("A url to your stylesheet")]
|
||||||
|
public string CssUrl { get; set; } = "";
|
||||||
|
|
||||||
|
[Description("(Optional) A url to your javascript file")]
|
||||||
|
public string? JsUrl { get; set; } = null;
|
||||||
|
|
||||||
|
[Description("Enable the theme for this instance")]
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
}
|
|
@ -7,11 +7,15 @@ namespace Moonlight.App.Services.Sys;
|
||||||
public class MoonlightService // This service can be used to perform strictly panel specific actions
|
public class MoonlightService // This service can be used to perform strictly panel specific actions
|
||||||
{
|
{
|
||||||
private readonly ConfigService ConfigService;
|
private readonly ConfigService ConfigService;
|
||||||
public WebApplication Application { get; set; } // Do NOT modify using a plugin
|
private readonly IServiceProvider ServiceProvider;
|
||||||
|
|
||||||
public MoonlightService(ConfigService configService)
|
public WebApplication Application { get; set; } // Do NOT modify using a plugin
|
||||||
|
public MoonlightThemeService Theme { get; set; }
|
||||||
|
|
||||||
|
public MoonlightService(ConfigService configService, IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
ConfigService = configService;
|
ConfigService = configService;
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Restart()
|
public async Task Restart()
|
||||||
|
|
57
Moonlight/App/Services/Sys/MoonlightThemeService.cs
Normal file
57
Moonlight/App/Services/Sys/MoonlightThemeService.cs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
using Moonlight.App.Database.Entities;
|
||||||
|
using Moonlight.App.Models.Abstractions;
|
||||||
|
using Moonlight.App.Repositories;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Services.Sys;
|
||||||
|
|
||||||
|
public class MoonlightThemeService
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider ServiceProvider;
|
||||||
|
private readonly ConfigService ConfigService;
|
||||||
|
|
||||||
|
public MoonlightThemeService(IServiceProvider serviceProvider, ConfigService configService)
|
||||||
|
{
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
|
ConfigService = configService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ApplicationTheme[]> GetInstalled()
|
||||||
|
{
|
||||||
|
using var scope = ServiceProvider.CreateScope();
|
||||||
|
var themeRepo = scope.ServiceProvider.GetRequiredService<Repository<Theme>>();
|
||||||
|
|
||||||
|
var themes = new List<ApplicationTheme>();
|
||||||
|
|
||||||
|
themes.AddRange(themeRepo
|
||||||
|
.Get()
|
||||||
|
.ToArray()
|
||||||
|
.Select(x => new ApplicationTheme()
|
||||||
|
{
|
||||||
|
Name = x.Name,
|
||||||
|
Author = x.Author,
|
||||||
|
CssUrl = x.CssUrl,
|
||||||
|
JsUrl = x.JsUrl,
|
||||||
|
Enabled = x.Enabled,
|
||||||
|
DonateUrl = x.DonateUrl
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (ConfigService.Get().Theme.EnableDefault)
|
||||||
|
{
|
||||||
|
themes.Insert(0, new()
|
||||||
|
{
|
||||||
|
Name = "Moonlight Default",
|
||||||
|
Author = "MasuOwO",
|
||||||
|
Enabled = true,
|
||||||
|
CssUrl = "/css/theme.css",
|
||||||
|
DonateUrl = "https://ko-fi.com/masuowo"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(themes.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ApplicationTheme[]> GetEnabled() =>
|
||||||
|
(await GetInstalled())
|
||||||
|
.Where(x => x.Enabled)
|
||||||
|
.ToArray();
|
||||||
|
}
|
|
@ -1,8 +1,15 @@
|
||||||
@page "/"
|
@page "/"
|
||||||
@using Microsoft.AspNetCore.Components.Web
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
|
@using Moonlight.App.Services.Sys
|
||||||
@namespace Moonlight.Pages
|
@namespace Moonlight.Pages
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
|
||||||
|
@inject MoonlightThemeService MoonlightThemeService
|
||||||
|
|
||||||
|
@{
|
||||||
|
var themes = await MoonlightThemeService.GetEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" data-bs-theme="dark">
|
<html lang="en" data-bs-theme="dark">
|
||||||
<head>
|
<head>
|
||||||
|
@ -15,7 +22,12 @@
|
||||||
|
|
||||||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered"/>
|
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered"/>
|
||||||
|
|
||||||
<link href="/css/theme.css" rel="stylesheet" type="text/css"/>
|
@foreach (var theme in themes)
|
||||||
|
{
|
||||||
|
<!-- Theme: @(theme.Name) by @(theme.Author) -->
|
||||||
|
<link href="@(theme.CssUrl)" rel="stylesheet" type="text/css"/>
|
||||||
|
}
|
||||||
|
|
||||||
<link href="/css/utils.css" rel="stylesheet" type="text/css"/>
|
<link href="/css/utils.css" rel="stylesheet" type="text/css"/>
|
||||||
<link href="/css/blazor.css" rel="stylesheet" type="text/css"/>
|
<link href="/css/blazor.css" rel="stylesheet" type="text/css"/>
|
||||||
<link href="/css/boxicons.min.css" rel="stylesheet" type="text/css"/>
|
<link href="/css/boxicons.min.css" rel="stylesheet" type="text/css"/>
|
||||||
|
@ -40,6 +52,16 @@
|
||||||
<script src="/_content/BlazorTable/BlazorTable.min.js"></script>
|
<script src="/_content/BlazorTable/BlazorTable.min.js"></script>
|
||||||
<script src="/js/sweetalert2.js"></script>
|
<script src="/js/sweetalert2.js"></script>
|
||||||
<script src="/js/ckeditor.js"></script>
|
<script src="/js/ckeditor.js"></script>
|
||||||
|
|
||||||
|
@foreach (var theme in themes)
|
||||||
|
{
|
||||||
|
if (theme.JsUrl != null)
|
||||||
|
{
|
||||||
|
<!-- Theme: @(theme.Name) by @(theme.Author) -->
|
||||||
|
<script src="@(theme.JsUrl)"></script>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<script src="/_framework/blazor.server.js"></script>
|
<script src="/_framework/blazor.server.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -19,7 +19,6 @@ using Moonlight.App.Services.Utils;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
var configService = new ConfigService();
|
var configService = new ConfigService();
|
||||||
var moonlightService = new MoonlightService(configService);
|
|
||||||
|
|
||||||
Directory.CreateDirectory(PathBuilder.Dir("storage"));
|
Directory.CreateDirectory(PathBuilder.Dir("storage"));
|
||||||
Directory.CreateDirectory(PathBuilder.Dir("storage", "logs"));
|
Directory.CreateDirectory(PathBuilder.Dir("storage", "logs"));
|
||||||
|
@ -95,7 +94,8 @@ builder.Services.AddSingleton(configService);
|
||||||
builder.Services.AddSingleton<SessionService>();
|
builder.Services.AddSingleton<SessionService>();
|
||||||
builder.Services.AddSingleton<BucketService>();
|
builder.Services.AddSingleton<BucketService>();
|
||||||
builder.Services.AddSingleton<MailService>();
|
builder.Services.AddSingleton<MailService>();
|
||||||
builder.Services.AddSingleton(moonlightService);
|
builder.Services.AddSingleton<MoonlightService>();
|
||||||
|
builder.Services.AddSingleton<MoonlightThemeService>();
|
||||||
|
|
||||||
builder.Services.AddRazorPages();
|
builder.Services.AddRazorPages();
|
||||||
builder.Services.AddServerSideBlazor();
|
builder.Services.AddServerSideBlazor();
|
||||||
|
@ -112,7 +112,6 @@ var config =
|
||||||
builder.Logging.AddConfiguration(config.Build());
|
builder.Logging.AddConfiguration(config.Build());
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
moonlightService.Application = app;
|
|
||||||
|
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
@ -124,8 +123,10 @@ app.MapControllers();
|
||||||
// Auto start background services
|
// Auto start background services
|
||||||
app.Services.GetRequiredService<AutoMailSendService>();
|
app.Services.GetRequiredService<AutoMailSendService>();
|
||||||
|
|
||||||
var serviceService = app.Services.GetRequiredService<ServiceDefinitionService>();
|
var moonlightService = app.Services.GetRequiredService<MoonlightService>();
|
||||||
|
moonlightService.Application = app;
|
||||||
|
|
||||||
|
var serviceService = app.Services.GetRequiredService<ServiceDefinitionService>();
|
||||||
serviceService.Register<DummyServiceDefinition>(ServiceType.Server);
|
serviceService.Register<DummyServiceDefinition>(ServiceType.Server);
|
||||||
|
|
||||||
await pluginService.RunPrePost(app);
|
await pluginService.RunPrePost(app);
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
<i class="bx bx-sm bx-cog me-2"></i> Settings
|
<i class="bx bx-sm bx-cog me-2"></i> Settings
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item mt-2">
|
||||||
|
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 2 ? "active" : "")" href="/admin/sys/themes">
|
||||||
|
<i class="bx bx-sm bx-palette me-2"></i> Themes
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
72
Moonlight/Shared/Views/Admin/Sys/Themes.razor
Normal file
72
Moonlight/Shared/Views/Admin/Sys/Themes.razor
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
@page "/admin/sys/themes"
|
||||||
|
|
||||||
|
@using Moonlight.App.Extensions.Attributes
|
||||||
|
@using Moonlight.App.Models.Enums
|
||||||
|
@using Moonlight.App.Models.Forms.Admin.Sys.Themes
|
||||||
|
@using Moonlight.App.Repositories
|
||||||
|
@using Moonlight.App.Services.Sys
|
||||||
|
@using BlazorTable
|
||||||
|
@using Moonlight.App.Models.Abstractions
|
||||||
|
|
||||||
|
@attribute [RequirePermission(Permission.AdminRoot)]
|
||||||
|
|
||||||
|
@inject MoonlightThemeService MoonlightThemeService
|
||||||
|
|
||||||
|
<AdminSysNavigation Index="2"/>
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<AutoCrud TItem="Theme"
|
||||||
|
TCreateForm="AddThemeForm"
|
||||||
|
TUpdateForm="EditThemeForm"
|
||||||
|
Title="Manage themes"
|
||||||
|
Load="LoadData">
|
||||||
|
<Column TableItem="Theme" Title="Id" Field="@(x => x.Id)" Sortable="true" Filterable="true"/>
|
||||||
|
<Column TableItem="Theme" Title="Name" Field="@(x => x.Name)" Sortable="true" Filterable="true"/>
|
||||||
|
<Column TableItem="Theme" Title="Author" Field="@(x => x.Author)" Sortable="true" Filterable="true"/>
|
||||||
|
<Column TableItem="Theme" Field="@(x => x.Id)" Title="" Filterable="false" Sortable="false">
|
||||||
|
<Template>
|
||||||
|
@if (EnabledThemes
|
||||||
|
.Any(x => x.Name == context.Name && x.Author == context.Author))
|
||||||
|
{
|
||||||
|
<span class="text-success">Enabled</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span class="text-muted">Disabled</span>
|
||||||
|
}
|
||||||
|
</Template>
|
||||||
|
</Column>
|
||||||
|
<Column TableItem="Theme" Field="@(x => x.Id)" Title="" Filterable="false" Sortable="false">
|
||||||
|
<Template>
|
||||||
|
<div class="text-end">
|
||||||
|
<div class="btn-group">
|
||||||
|
@if (context.DonateUrl != null)
|
||||||
|
{
|
||||||
|
<a class="btn btn-sm btn-info" href="@(context.DonateUrl)" target="_blank">Donate</a>
|
||||||
|
}
|
||||||
|
<WButton OnClick="() => ExportTheme(context)" Text="Export" CssClasses="btn btn-sm btn-secondary"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Template>
|
||||||
|
</Column>
|
||||||
|
<Pager ShowPageNumber="true" ShowTotalCount="true" AlwaysShow="true"/>
|
||||||
|
</AutoCrud>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
private ApplicationTheme[] EnabledThemes;
|
||||||
|
|
||||||
|
private Theme[] LoadData(Repository<Theme> repository)
|
||||||
|
{
|
||||||
|
// No async => .Result needs to be used. :c
|
||||||
|
EnabledThemes = MoonlightThemeService.GetEnabled().Result;
|
||||||
|
|
||||||
|
return repository.Get().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task ExportTheme(Theme theme)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
3
Moonlight/wwwroot/css/demotheme.css
vendored
Normal file
3
Moonlight/wwwroot/css/demotheme.css
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
body {
|
||||||
|
background-color: #0d8ddc !important;
|
||||||
|
}
|
Loading…
Reference in a new issue