Added moonlight resources. Optimised moonlight legacy html rendering
This commit is contained in:
52
Moonlight/App/Database/DataContext.cs
Normal file
52
Moonlight/App/Database/DataContext.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Services;
|
||||
|
||||
namespace Moonlight.App.Database;
|
||||
|
||||
public class DataContext : DbContext
|
||||
{
|
||||
private readonly ConfigService ConfigService;
|
||||
|
||||
public DataContext(ConfigService configService)
|
||||
{
|
||||
ConfigService = configService;
|
||||
}
|
||||
|
||||
public DbSet<DockerImage> DockerImages { get; set; }
|
||||
public DbSet<Image> Images { get; set; }
|
||||
public DbSet<ImageTag> ImageTags { get; set; }
|
||||
public DbSet<ImageVariable> ImageVariables { get; set; }
|
||||
public DbSet<Node> Nodes { get; set; }
|
||||
public DbSet<NodeAllocation> NodeAllocations { get; set; }
|
||||
public DbSet<Server> Servers { get; set; }
|
||||
public DbSet<ServerBackup> ServerBackups { get; set; }
|
||||
public DbSet<ServerVariable> ServerVariables { get; set; }
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<LoadingMessage> LoadingMessages { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
if (!optionsBuilder.IsConfigured)
|
||||
{
|
||||
var config = ConfigService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Database");
|
||||
|
||||
var connectionString = $"host={config.GetValue<string>("Host")};" +
|
||||
$"port={config.GetValue<int>("Port")};" +
|
||||
$"database={config.GetValue<string>("Database")};" +
|
||||
$"uid={config.GetValue<string>("Username")};" +
|
||||
$"pwd={config.GetValue<string>("Password")}";
|
||||
|
||||
optionsBuilder.UseMySql(
|
||||
connectionString,
|
||||
ServerVersion.Parse("5.7.37-mysql"),
|
||||
builder =>
|
||||
{
|
||||
builder.EnableRetryOnFailure(5);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Moonlight/App/Database/Entities/DockerImage.cs
Normal file
8
Moonlight/App/Database/Entities/DockerImage.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class DockerImage
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public bool Default { get; set; } = false;
|
||||
public string Name { get; set; } = "";
|
||||
}
|
||||
20
Moonlight/App/Database/Entities/Image.cs
Normal file
20
Moonlight/App/Database/Entities/Image.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class Image
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Guid Uuid { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public string Description { get; set; } = "";
|
||||
public string ConfigFiles { get; set; } = "{}";
|
||||
public string StopCommand { get; set; } = "";
|
||||
public string StartupDetection { get; set; } = "";
|
||||
public string InstallScript { get; set; } = "";
|
||||
public string InstallDockerImage { get; set; } = "";
|
||||
public string InstallEntrypoint { get; set; } = "";
|
||||
public string Startup { get; set; } = "";
|
||||
|
||||
public List<DockerImage> DockerImages { get; set; } = new();
|
||||
public List<ImageVariable> Variables { get; set; } = new();
|
||||
public List<ImageTag> Tags { get; set; } = new();
|
||||
}
|
||||
7
Moonlight/App/Database/Entities/ImageTag.cs
Normal file
7
Moonlight/App/Database/Entities/ImageTag.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ImageTag
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
}
|
||||
8
Moonlight/App/Database/Entities/ImageVariable.cs
Normal file
8
Moonlight/App/Database/Entities/ImageVariable.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ImageVariable
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Key { get; set; } = "";
|
||||
public string DefaultValue { get; set; } = "";
|
||||
}
|
||||
7
Moonlight/App/Database/Entities/LoadingMessage.cs
Normal file
7
Moonlight/App/Database/Entities/LoadingMessage.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class LoadingMessage
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Message { get; set; } = "";
|
||||
}
|
||||
14
Moonlight/App/Database/Entities/Node.cs
Normal file
14
Moonlight/App/Database/Entities/Node.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class Node
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public string Fqdn { get; set; } = "";
|
||||
public string TokenId { get; set; } = "";
|
||||
public string Token { get; set; } = "";
|
||||
public int SftpPort { get; set; }
|
||||
public int HttpPort { get; set; }
|
||||
public int MoonlightDaemonPort { get; set; }
|
||||
public List<NodeAllocation> Allocations { get; set; } = new();
|
||||
}
|
||||
7
Moonlight/App/Database/Entities/NodeAllocation.cs
Normal file
7
Moonlight/App/Database/Entities/NodeAllocation.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class NodeAllocation
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Port { get; set; }
|
||||
}
|
||||
23
Moonlight/App/Database/Entities/Server.cs
Normal file
23
Moonlight/App/Database/Entities/Server.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class Server
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Guid Uuid { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public int Cpu { get; set; }
|
||||
public long Memory { get; set; }
|
||||
public long Disk { get; set; }
|
||||
public Image Image { get; set; } = null!;
|
||||
public int DockerImageIndex { get; set; } = 0;
|
||||
public string OverrideStartup { get; set; } = "";
|
||||
public bool Installing { get; set; } = false;
|
||||
public bool Suspended { get; set; } = false;
|
||||
|
||||
public List<ServerVariable> Variables { get; set; } = new();
|
||||
public List<ServerBackup> Backups { get; set; } = new();
|
||||
public List<NodeAllocation> Allocations { get; set; } = new();
|
||||
public NodeAllocation MainAllocation { get; set; } = null!;
|
||||
public Node Node { get; set; } = null!;
|
||||
public User Owner { get; set; } = null!;
|
||||
}
|
||||
11
Moonlight/App/Database/Entities/ServerBackup.cs
Normal file
11
Moonlight/App/Database/Entities/ServerBackup.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ServerBackup
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public Guid Uuid { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public bool Created { get; set; } = false;
|
||||
public long Bytes { get; set; }
|
||||
}
|
||||
8
Moonlight/App/Database/Entities/ServerVariable.cs
Normal file
8
Moonlight/App/Database/Entities/ServerVariable.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ServerVariable
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Key { get; set; } = "";
|
||||
public string Value { get; set; } = "";
|
||||
}
|
||||
26
Moonlight/App/Database/Entities/User.cs
Normal file
26
Moonlight/App/Database/Entities/User.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Moonlight.App.Models.Misc;
|
||||
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class User
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string FirstName { get; set; } = "";
|
||||
public string LastName { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public string Password { get; set; } = "";
|
||||
public string Address { get; set; } = "";
|
||||
public string City { get; set; } = "";
|
||||
public string State { get; set; } = "";
|
||||
public string Country { get; set; } = "";
|
||||
public UserStatus Status { get; set; } = UserStatus.Unverified;
|
||||
public bool TotpEnabled { get; set; }
|
||||
public string TotpSecret { get; set; } = "";
|
||||
public DateTime TokenValidTime { get; set; } = DateTime.Now;
|
||||
public long DiscordId { get; set; }
|
||||
public string DiscordUsername { get; set; } = "";
|
||||
public string DiscordDiscriminator { get; set; } = "";
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool Admin { get; set; }
|
||||
}
|
||||
515
Moonlight/App/Database/Migrations/20230215200722_InitialCreate.Designer.cs
generated
Normal file
515
Moonlight/App/Database/Migrations/20230215200722_InitialCreate.Designer.cs
generated
Normal file
@@ -0,0 +1,515 @@
|
||||
// <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("20230215200722_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Default")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("DockerImages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConfigFiles")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallDockerImage")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallEntrypoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallScript")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Startup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StartupDetection")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StopCommand")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Images");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageTags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DefaultValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.LoadingMessage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LoadingMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Fqdn")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("HttpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("MoonlightDaemonPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("SftpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TokenId")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Nodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Port")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("NodeAllocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Cpu")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Disk")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("DockerImageIndex")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Installing")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("MainAllocationId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Memory")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("OverrideStartup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Suspended")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.HasIndex("MainAllocationId");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Servers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Bytes")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<bool>("Created")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerBackups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("Admin")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("City")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("DiscordDiscriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<long>("DiscordId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("DiscordUsername")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("State")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("TokenValidTime")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("TotpEnabled")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("TotpSecret")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("DockerImages")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Tags")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("NodeId");
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", "Image")
|
||||
.WithMany()
|
||||
.HasForeignKey("ImageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.NodeAllocation", "MainAllocation")
|
||||
.WithMany()
|
||||
.HasForeignKey("MainAllocationId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", "Node")
|
||||
.WithMany()
|
||||
.HasForeignKey("NodeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Image");
|
||||
|
||||
b.Navigation("MainAllocation");
|
||||
|
||||
b.Navigation("Node");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Backups")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Navigation("DockerImages");
|
||||
|
||||
b.Navigation("Tags");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
|
||||
b.Navigation("Backups");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.App.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Images",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Uuid = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ConfigFiles = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
StopCommand = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
StartupDetection = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
InstallScript = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
InstallDockerImage = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
InstallEntrypoint = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Startup = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Images", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "LoadingMessages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Message = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_LoadingMessages", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Nodes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Fqdn = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
TokenId = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Token = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
SftpPort = table.Column<int>(type: "int", nullable: false),
|
||||
HttpPort = table.Column<int>(type: "int", nullable: false),
|
||||
MoonlightDaemonPort = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Nodes", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Users",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
FirstName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
LastName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Email = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Password = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Address = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
City = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
State = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Country = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
TotpEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TotpSecret = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
TokenValidTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
DiscordId = table.Column<long>(type: "bigint", nullable: false),
|
||||
DiscordUsername = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
DiscordDiscriminator = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
Admin = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Users", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DockerImages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Default = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ImageId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DockerImages", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_DockerImages_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ImageTags",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ImageId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ImageTags", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ImageTags_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ImageVariables",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Key = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
DefaultValue = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ImageId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ImageVariables", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ImageVariables_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "NodeAllocations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Port = table.Column<int>(type: "int", nullable: false),
|
||||
NodeId = table.Column<int>(type: "int", nullable: true),
|
||||
ServerId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_NodeAllocations", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_NodeAllocations_Nodes_NodeId",
|
||||
column: x => x.NodeId,
|
||||
principalTable: "Nodes",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Servers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Uuid = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Cpu = table.Column<int>(type: "int", nullable: false),
|
||||
Memory = table.Column<long>(type: "bigint", nullable: false),
|
||||
Disk = table.Column<long>(type: "bigint", nullable: false),
|
||||
ImageId = table.Column<int>(type: "int", nullable: false),
|
||||
DockerImageIndex = table.Column<int>(type: "int", nullable: false),
|
||||
OverrideStartup = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Installing = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Suspended = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
MainAllocationId = table.Column<int>(type: "int", nullable: false),
|
||||
NodeId = table.Column<int>(type: "int", nullable: false),
|
||||
OwnerId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Servers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_NodeAllocations_MainAllocationId",
|
||||
column: x => x.MainAllocationId,
|
||||
principalTable: "NodeAllocations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_Nodes_NodeId",
|
||||
column: x => x.NodeId,
|
||||
principalTable: "Nodes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_Users_OwnerId",
|
||||
column: x => x.OwnerId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerBackups",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Uuid = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
Created = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Bytes = table.Column<long>(type: "bigint", nullable: false),
|
||||
ServerId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServerBackups", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ServerBackups_Servers_ServerId",
|
||||
column: x => x.ServerId,
|
||||
principalTable: "Servers",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerVariables",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Key = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Value = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ServerId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServerVariables", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ServerVariables_Servers_ServerId",
|
||||
column: x => x.ServerId,
|
||||
principalTable: "Servers",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DockerImages_ImageId",
|
||||
table: "DockerImages",
|
||||
column: "ImageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ImageTags_ImageId",
|
||||
table: "ImageTags",
|
||||
column: "ImageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ImageVariables_ImageId",
|
||||
table: "ImageVariables",
|
||||
column: "ImageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_NodeAllocations_NodeId",
|
||||
table: "NodeAllocations",
|
||||
column: "NodeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_NodeAllocations_ServerId",
|
||||
table: "NodeAllocations",
|
||||
column: "ServerId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServerBackups_ServerId",
|
||||
table: "ServerBackups",
|
||||
column: "ServerId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Servers_ImageId",
|
||||
table: "Servers",
|
||||
column: "ImageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Servers_MainAllocationId",
|
||||
table: "Servers",
|
||||
column: "MainAllocationId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Servers_NodeId",
|
||||
table: "Servers",
|
||||
column: "NodeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Servers_OwnerId",
|
||||
table: "Servers",
|
||||
column: "OwnerId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServerVariables_ServerId",
|
||||
table: "ServerVariables",
|
||||
column: "ServerId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NodeAllocations_Servers_ServerId",
|
||||
table: "NodeAllocations",
|
||||
column: "ServerId",
|
||||
principalTable: "Servers",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Servers_Images_ImageId",
|
||||
table: "Servers");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NodeAllocations_Nodes_NodeId",
|
||||
table: "NodeAllocations");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Servers_Nodes_NodeId",
|
||||
table: "Servers");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NodeAllocations_Servers_ServerId",
|
||||
table: "NodeAllocations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DockerImages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ImageTags");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ImageVariables");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "LoadingMessages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ServerBackups");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ServerVariables");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Images");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Nodes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Servers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "NodeAllocations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Users");
|
||||
}
|
||||
}
|
||||
}
|
||||
512
Moonlight/App/Database/Migrations/DataContextModelSnapshot.cs
Normal file
512
Moonlight/App/Database/Migrations/DataContextModelSnapshot.cs
Normal file
@@ -0,0 +1,512 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Moonlight.App.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.App.Database.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
partial class DataContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Default")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("DockerImages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConfigFiles")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallDockerImage")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallEntrypoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallScript")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Startup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StartupDetection")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StopCommand")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Images");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageTags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DefaultValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.LoadingMessage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LoadingMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Fqdn")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("HttpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("MoonlightDaemonPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("SftpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TokenId")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Nodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Port")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("NodeAllocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Cpu")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Disk")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("DockerImageIndex")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Installing")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("MainAllocationId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Memory")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("OverrideStartup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Suspended")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.HasIndex("MainAllocationId");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Servers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Bytes")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<bool>("Created")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerBackups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("Admin")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("City")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("DiscordDiscriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<long>("DiscordId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("DiscordUsername")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("State")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("TokenValidTime")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("TotpEnabled")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("TotpSecret")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("DockerImages")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Tags")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("NodeId");
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", "Image")
|
||||
.WithMany()
|
||||
.HasForeignKey("ImageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.NodeAllocation", "MainAllocation")
|
||||
.WithMany()
|
||||
.HasForeignKey("MainAllocationId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", "Node")
|
||||
.WithMany()
|
||||
.HasForeignKey("NodeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Image");
|
||||
|
||||
b.Navigation("MainAllocation");
|
||||
|
||||
b.Navigation("Node");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Backups")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Navigation("DockerImages");
|
||||
|
||||
b.Navigation("Tags");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
|
||||
b.Navigation("Backups");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
58
Moonlight/App/Helpers/TranslationHelper.cs
Normal file
58
Moonlight/App/Helpers/TranslationHelper.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Logging.Net;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Moonlight.App.Helpers
|
||||
{
|
||||
public class TranslationHelper
|
||||
{
|
||||
private readonly Dictionary<string, IConfiguration> Languages;
|
||||
|
||||
public TranslationHelper()
|
||||
{
|
||||
Languages = new();
|
||||
|
||||
foreach (var file in Directory.GetFiles("resources/lang"))
|
||||
{
|
||||
var langKey = Path.GetFileName(file)
|
||||
.Replace(Path.GetExtension(file), "");
|
||||
|
||||
Languages.Add(langKey, new ConfigurationBuilder()
|
||||
.AddJsonFile(file)
|
||||
.Build());
|
||||
}
|
||||
}
|
||||
|
||||
public string? Get(string langKey, string key)
|
||||
{
|
||||
if (Languages.ContainsKey(langKey))
|
||||
{
|
||||
var parts = key.Split(".");
|
||||
|
||||
IConfigurationSection? section = null;
|
||||
foreach (var part in parts)
|
||||
{
|
||||
if (part == parts.Last())
|
||||
{
|
||||
if (section == null)
|
||||
return Languages[langKey].GetValue<string>(part);
|
||||
else
|
||||
return section.GetValue<string>(part);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (section == null)
|
||||
section = Languages[langKey].GetSection(part);
|
||||
else
|
||||
section = section.GetSection(part);
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Invalid lang key";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Moonlight/App/Models/IpLocate/Resources/IpLocate.cs
Normal file
48
Moonlight/App/Models/IpLocate/Resources/IpLocate.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Moonlight.App.Models.IpLocate.Resources;
|
||||
|
||||
public class IpLocate
|
||||
{
|
||||
[JsonProperty("query")]
|
||||
public string Query { get; set; }
|
||||
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
|
||||
[JsonProperty("country")]
|
||||
public string Country { get; set; }
|
||||
|
||||
[JsonProperty("countryCode")]
|
||||
public string CountryCode { get; set; }
|
||||
|
||||
[JsonProperty("region")]
|
||||
public string Region { get; set; }
|
||||
|
||||
[JsonProperty("regionName")]
|
||||
public string RegionName { get; set; }
|
||||
|
||||
[JsonProperty("city")]
|
||||
public string City { get; set; }
|
||||
|
||||
[JsonProperty("zip")]
|
||||
public string Zip { get; set; }
|
||||
|
||||
[JsonProperty("lat")]
|
||||
public double Lat { get; set; }
|
||||
|
||||
[JsonProperty("lon")]
|
||||
public double Lon { get; set; }
|
||||
|
||||
[JsonProperty("timezone")]
|
||||
public string Timezone { get; set; }
|
||||
|
||||
[JsonProperty("isp")]
|
||||
public string Isp { get; set; }
|
||||
|
||||
[JsonProperty("org")]
|
||||
public string Org { get; set; }
|
||||
|
||||
[JsonProperty("as")]
|
||||
public string As { get; set; }
|
||||
}
|
||||
15
Moonlight/App/Models/Misc/Session.cs
Normal file
15
Moonlight/App/Models/Misc/Session.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Moonlight.App.Services.Interop;
|
||||
|
||||
namespace Moonlight.App.Models.Misc;
|
||||
|
||||
public class Session
|
||||
{
|
||||
public string Ip { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Device { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public NavigationManager Navigation { get; set; }
|
||||
public AlertService AlertService { get; set; }
|
||||
}
|
||||
12
Moonlight/App/Models/Misc/UserStatus.cs
Normal file
12
Moonlight/App/Models/Misc/UserStatus.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Moonlight.App.Models.Misc;
|
||||
|
||||
public enum UserStatus
|
||||
{
|
||||
Unverified,
|
||||
Verified,
|
||||
VerifyPending,
|
||||
VerifyFailed,
|
||||
Warned,
|
||||
Banned,
|
||||
Disabled
|
||||
}
|
||||
44
Moonlight/App/Repositories/NodeRepository.cs
Normal file
44
Moonlight/App/Repositories/NodeRepository.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories;
|
||||
|
||||
public class NodeRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public NodeRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<Node> Get()
|
||||
{
|
||||
return DataContext.Nodes;
|
||||
}
|
||||
|
||||
public Node Add(Node node)
|
||||
{
|
||||
var x = DataContext.Nodes.Add(node);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(Node node)
|
||||
{
|
||||
DataContext.Nodes.Update(node);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(Node node)
|
||||
{
|
||||
DataContext.Nodes.Remove(node);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
||||
44
Moonlight/App/Repositories/Servers/ServerBackupRepository.cs
Normal file
44
Moonlight/App/Repositories/Servers/ServerBackupRepository.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories.Servers;
|
||||
|
||||
public class ServerBackupRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public ServerBackupRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<ServerBackup> Get()
|
||||
{
|
||||
return DataContext.ServerBackups;
|
||||
}
|
||||
|
||||
public ServerBackup Add(ServerBackup serverBackup)
|
||||
{
|
||||
var x = DataContext.ServerBackups.Add(serverBackup);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(ServerBackup serverBackup)
|
||||
{
|
||||
DataContext.ServerBackups.Update(serverBackup);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(ServerBackup serverBackup)
|
||||
{
|
||||
DataContext.ServerBackups.Remove(serverBackup);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
||||
44
Moonlight/App/Repositories/Servers/ServerRepository.cs
Normal file
44
Moonlight/App/Repositories/Servers/ServerRepository.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories.Servers;
|
||||
|
||||
public class ServerRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public ServerRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<Server> Get()
|
||||
{
|
||||
return DataContext.Servers;
|
||||
}
|
||||
|
||||
public Server Add(Server server)
|
||||
{
|
||||
var x = DataContext.Servers.Add(server);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(Server server)
|
||||
{
|
||||
DataContext.Servers.Update(server);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(Server server)
|
||||
{
|
||||
DataContext.Servers.Remove(server);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
||||
37
Moonlight/App/Repositories/SessionRepository.cs
Normal file
37
Moonlight/App/Repositories/SessionRepository.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Moonlight.App.Models.Misc;
|
||||
|
||||
namespace Moonlight.App.Repositories;
|
||||
|
||||
public class SessionRepository
|
||||
{
|
||||
private readonly List<Session> Sessions;
|
||||
|
||||
public SessionRepository()
|
||||
{
|
||||
Sessions = new();
|
||||
}
|
||||
|
||||
public Session[] Get()
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
return Sessions.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(Session session)
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
Sessions.Add(session);
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(Session session)
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
Sessions.Remove(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Moonlight/App/Repositories/UserRepository.cs
Normal file
44
Moonlight/App/Repositories/UserRepository.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories;
|
||||
|
||||
public class UserRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public UserRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<User> Get()
|
||||
{
|
||||
return DataContext.Users;
|
||||
}
|
||||
|
||||
public User Add(User user)
|
||||
{
|
||||
var x = DataContext.Users.Add(user);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(User user)
|
||||
{
|
||||
DataContext.Users.Update(user);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(User user)
|
||||
{
|
||||
DataContext.Users.Remove(user);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
||||
46
Moonlight/App/Services/ConfigService.cs
Normal file
46
Moonlight/App/Services/ConfigService.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.Text;
|
||||
using Logging.Net;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Moonlight.App.Services;
|
||||
|
||||
public class ConfigService : IConfiguration
|
||||
{
|
||||
private IConfiguration Configuration;
|
||||
|
||||
public bool DebugMode { get; private set; } = false;
|
||||
|
||||
public ConfigService()
|
||||
{
|
||||
Configuration = new ConfigurationBuilder().AddJsonStream(
|
||||
new MemoryStream(Encoding.ASCII.GetBytes(File.ReadAllText("..\\..\\appsettings.json")))
|
||||
).Build();
|
||||
|
||||
// Env vars
|
||||
var debugVar = Environment.GetEnvironmentVariable("ML_DEBUG");
|
||||
|
||||
if (debugVar != null)
|
||||
DebugMode = bool.Parse(debugVar);
|
||||
}
|
||||
|
||||
public IEnumerable<IConfigurationSection> GetChildren()
|
||||
{
|
||||
return Configuration.GetChildren();
|
||||
}
|
||||
|
||||
public IChangeToken GetReloadToken()
|
||||
{
|
||||
return Configuration.GetReloadToken();
|
||||
}
|
||||
|
||||
public IConfigurationSection GetSection(string key)
|
||||
{
|
||||
return Configuration.GetSection(key);
|
||||
}
|
||||
|
||||
public string this[string key]
|
||||
{
|
||||
get => Configuration[key];
|
||||
set => Configuration[key] = value;
|
||||
}
|
||||
}
|
||||
82
Moonlight/App/Services/Interop/AlertService.cs
Normal file
82
Moonlight/App/Services/Interop/AlertService.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using CurrieTechnologies.Razor.SweetAlert2;
|
||||
|
||||
namespace Moonlight.App.Services.Interop;
|
||||
|
||||
public class AlertService
|
||||
{
|
||||
private readonly SweetAlertService SweetAlertService;
|
||||
|
||||
public AlertService(SweetAlertService service)
|
||||
{
|
||||
SweetAlertService = service;
|
||||
}
|
||||
|
||||
public async Task Info(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Info
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Success(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Success
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Warning(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Warning
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Error(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Error
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<bool> YesNo(string title, string desciption, string yesText, string noText)
|
||||
{
|
||||
var result = await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
ShowCancelButton = false,
|
||||
ShowDenyButton = true,
|
||||
ShowConfirmButton = true,
|
||||
ConfirmButtonText = yesText,
|
||||
DenyButtonText = noText
|
||||
});
|
||||
|
||||
return result.IsConfirmed;
|
||||
}
|
||||
|
||||
public async Task<string> Text(string title, string desciption, string setValue)
|
||||
{
|
||||
var result = await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Input = SweetAlertInputType.Text,
|
||||
InputValue = setValue
|
||||
});
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
}
|
||||
18
Moonlight/App/Services/Interop/ClipboardService.cs
Normal file
18
Moonlight/App/Services/Interop/ClipboardService.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Moonlight.App.Services.Interop;
|
||||
|
||||
public class ClipboardService
|
||||
{
|
||||
private readonly IJSRuntime JsRuntime;
|
||||
|
||||
public ClipboardService(IJSRuntime jsRuntime)
|
||||
{
|
||||
JsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public async Task CopyToClipboard(string data)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("copyTextToClipboard", data);
|
||||
}
|
||||
}
|
||||
33
Moonlight/App/Services/Interop/ToastService.cs
Normal file
33
Moonlight/App/Services/Interop/ToastService.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Moonlight.App.Services.Interop;
|
||||
|
||||
public class ToastService
|
||||
{
|
||||
private readonly IJSRuntime JsRuntime;
|
||||
|
||||
public ToastService(IJSRuntime jsRuntime)
|
||||
{
|
||||
JsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public async Task Info(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showInfoToast", message);
|
||||
}
|
||||
|
||||
public async Task Error(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showErrorToast", message);
|
||||
}
|
||||
|
||||
public async Task Warning(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showWarningToast", message);
|
||||
}
|
||||
|
||||
public async Task Success(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showSuccessToast", message);
|
||||
}
|
||||
}
|
||||
51
Moonlight/App/Services/Sessions/CookieService.cs
Normal file
51
Moonlight/App/Services/Sessions/CookieService.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class CookieService
|
||||
{
|
||||
private readonly IJSRuntime JsRuntime;
|
||||
private string Expires = "";
|
||||
|
||||
public CookieService(IJSRuntime jsRuntime)
|
||||
{
|
||||
JsRuntime = jsRuntime;
|
||||
ExpireDays = 300;
|
||||
}
|
||||
|
||||
public async Task SetValue(string key, string value, int? days = null)
|
||||
{
|
||||
var curExp = (days != null) ? (days > 0 ? DateToUTC(days.Value) : "") : Expires;
|
||||
await SetCookie($"{key}={value}; expires={curExp}; path=/");
|
||||
}
|
||||
|
||||
public async Task<string> GetValue(string key, string def = "")
|
||||
{
|
||||
var cValue = await GetCookie();
|
||||
if (string.IsNullOrEmpty(cValue)) return def;
|
||||
|
||||
var vals = cValue.Split(';');
|
||||
foreach (var val in vals)
|
||||
if(!string.IsNullOrEmpty(val) && val.IndexOf('=') > 0)
|
||||
if(val.Substring(1, val.IndexOf('=') - 1).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
|
||||
return val.Substring(val.IndexOf('=') + 1);
|
||||
return def;
|
||||
}
|
||||
|
||||
private async Task SetCookie(string value)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{value}\"");
|
||||
}
|
||||
|
||||
private async Task<string> GetCookie()
|
||||
{
|
||||
return await JsRuntime.InvokeAsync<string>("eval", $"document.cookie");
|
||||
}
|
||||
|
||||
private int ExpireDays
|
||||
{
|
||||
set => Expires = DateToUTC(value);
|
||||
}
|
||||
|
||||
private static string DateToUTC(int days) => DateTime.Now.AddDays(days).ToUniversalTime().ToString("R");
|
||||
}
|
||||
167
Moonlight/App/Services/Sessions/IdentityService.cs
Normal file
167
Moonlight/App/Services/Sessions/IdentityService.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System.Text;
|
||||
using JWT.Algorithms;
|
||||
using JWT.Builder;
|
||||
using JWT.Exceptions;
|
||||
using Logging.Net;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Repositories;
|
||||
using UAParser;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class IdentityService
|
||||
{
|
||||
private readonly UserRepository UserRepository;
|
||||
private readonly CookieService CookieService;
|
||||
private readonly IHttpContextAccessor HttpContextAccessor;
|
||||
private readonly string Secret;
|
||||
|
||||
private User? UserCache;
|
||||
|
||||
public IdentityService(
|
||||
CookieService cookieService,
|
||||
UserRepository userRepository,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
ConfigService configService)
|
||||
{
|
||||
CookieService = cookieService;
|
||||
UserRepository = userRepository;
|
||||
HttpContextAccessor = httpContextAccessor;
|
||||
|
||||
Secret = configService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Security")
|
||||
.GetValue<string>("Token");
|
||||
}
|
||||
|
||||
public async Task<User?> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (UserCache != null)
|
||||
return UserCache;
|
||||
|
||||
var token = "none";
|
||||
|
||||
// Load token via http context if available
|
||||
if (HttpContextAccessor.HttpContext != null)
|
||||
{
|
||||
var request = HttpContextAccessor.HttpContext.Request;
|
||||
|
||||
if (request.Cookies.ContainsKey("token"))
|
||||
{
|
||||
token = request.Cookies["token"];
|
||||
}
|
||||
}
|
||||
else // if not we check the cookies manually via js. this may not often work
|
||||
{
|
||||
token = await CookieService.GetValue("token", "none");
|
||||
}
|
||||
|
||||
if (token == "none")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return null;
|
||||
|
||||
var json = "";
|
||||
|
||||
try
|
||||
{
|
||||
json = JwtBuilder.Create()
|
||||
.WithAlgorithm(new HMACSHA256Algorithm())
|
||||
.WithSecret(Secret)
|
||||
.Decode(token);
|
||||
}
|
||||
catch (TokenExpiredException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (SignatureVerificationException)
|
||||
{
|
||||
//TODO: Heavy warn and write it to the logs
|
||||
Logger.Warn("Someone tried to modify his data: " + token);
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Error parsing and validating token");
|
||||
Logger.Warn(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// To make it easier to use the json data
|
||||
var data = new ConfigurationBuilder().AddJsonStream(
|
||||
new MemoryStream(Encoding.ASCII.GetBytes(json))
|
||||
).Build();
|
||||
|
||||
var userid = data.GetValue<int>("userid");
|
||||
var user = UserRepository.Get().FirstOrDefault(y => y.Id == userid);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
Logger.Warn($"Cannot find user with the id '{userid}' in the database. Maybe the user has been deleted or a token has been successfully faked by a hacker");
|
||||
return null;
|
||||
}
|
||||
|
||||
var iat = data.GetValue<long>("iat", -1);
|
||||
|
||||
if (iat == -1)
|
||||
{
|
||||
Logger.Debug("Legacy token found (without the time the token has been issued at)");
|
||||
return null;
|
||||
}
|
||||
|
||||
var issuedAt = DateTimeOffset.FromUnixTimeSeconds(iat).DateTime;
|
||||
|
||||
if (issuedAt < user.TokenValidTime.ToUniversalTime())
|
||||
{
|
||||
//TODO: Remove at publish
|
||||
//Logger.Debug($"Old token found: {issuedAt.ToShortDateString()} {issuedAt.ToShortTimeString()} Current valid token time {userData.TokenValidTime.ToUniversalTime().ToShortDateString()} {userData.TokenValidTime.ToUniversalTime().ToShortTimeString()}");
|
||||
return null;
|
||||
}
|
||||
|
||||
UserCache = user;
|
||||
return UserCache;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Error loading user");
|
||||
Logger.Warn(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetIp()
|
||||
{
|
||||
if (HttpContextAccessor.HttpContext == null)
|
||||
return "N/A";
|
||||
|
||||
if(HttpContextAccessor.HttpContext.Request.Headers.ContainsKey("X-Real-IP"))
|
||||
{
|
||||
return HttpContextAccessor.HttpContext.Request.Headers["X-Real-IP"]!;
|
||||
}
|
||||
|
||||
return HttpContextAccessor.HttpContext.Connection.RemoteIpAddress!.ToString();
|
||||
}
|
||||
|
||||
public string GetDevice()
|
||||
{
|
||||
if (HttpContextAccessor.HttpContext == null)
|
||||
return "N/A";
|
||||
|
||||
try
|
||||
{
|
||||
var uaParser = Parser.GetDefault();
|
||||
var info = uaParser.Parse(HttpContextAccessor.HttpContext.Request.Headers.UserAgent);
|
||||
|
||||
return $"{info.OS} - {info.Device}";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return "UserAgent not present";
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Moonlight/App/Services/Sessions/IpLocateService.cs
Normal file
37
Moonlight/App/Services/Sessions/IpLocateService.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Net;
|
||||
using Moonlight.App.Models.IpLocate.Resources;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class IpLocateService
|
||||
{
|
||||
private readonly IdentityService IdentityService;
|
||||
|
||||
public IpLocateService(IdentityService identityService)
|
||||
{
|
||||
IdentityService = identityService;
|
||||
}
|
||||
|
||||
public async Task<string> GetLocation()
|
||||
{
|
||||
var ip = IdentityService.GetIp();
|
||||
var location = "N/A";
|
||||
|
||||
if (ip != "N/A")
|
||||
{
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<IpLocate>(
|
||||
await wc.DownloadStringTaskAsync(
|
||||
$"http://ip-api.com/json/{ip}"
|
||||
)
|
||||
);
|
||||
|
||||
location = $"{res.Country} - {res.RegionName} - {res.City} ({res.Org})";
|
||||
}
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
}
|
||||
77
Moonlight/App/Services/Sessions/SessionService.cs
Normal file
77
Moonlight/App/Services/Sessions/SessionService.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Models.Misc;
|
||||
using Moonlight.App.Repositories;
|
||||
using Moonlight.App.Services.Interop;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class SessionService
|
||||
{
|
||||
private readonly SessionRepository SessionRepository;
|
||||
private readonly IdentityService IdentityService;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
private readonly AlertService AlertService;
|
||||
|
||||
private Session OwnSession;
|
||||
|
||||
public SessionService(
|
||||
SessionRepository sessionRepository,
|
||||
IdentityService identityService,
|
||||
NavigationManager navigationManager,
|
||||
AlertService alertService)
|
||||
{
|
||||
SessionRepository = sessionRepository;
|
||||
IdentityService = identityService;
|
||||
NavigationManager = navigationManager;
|
||||
AlertService = alertService;
|
||||
}
|
||||
|
||||
public async Task Register()
|
||||
{
|
||||
var user = await IdentityService.Get();
|
||||
var userId = -1;
|
||||
|
||||
if (user != null)
|
||||
userId = user.Id;
|
||||
|
||||
OwnSession = new Session()
|
||||
{
|
||||
Ip = IdentityService.GetIp(),
|
||||
Url = NavigationManager.Uri,
|
||||
Device = IdentityService.GetDevice(),
|
||||
CreatedAt = DateTime.Now,
|
||||
UserId = userId,
|
||||
Navigation = NavigationManager,
|
||||
AlertService = AlertService
|
||||
};
|
||||
|
||||
SessionRepository.Add(OwnSession);
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
OwnSession.Url = NavigationManager.Uri;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
SessionRepository.Delete(OwnSession);
|
||||
}
|
||||
|
||||
public Session[] GetAll()
|
||||
{
|
||||
return SessionRepository.Get();
|
||||
}
|
||||
|
||||
public void ReloadUserSessions(User user)
|
||||
{
|
||||
foreach (var session in SessionRepository.Get())
|
||||
{
|
||||
if (session.UserId == user.Id)
|
||||
{
|
||||
session.Navigation.NavigateTo(session.Navigation.Uri, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Moonlight/App/Services/TranslationService.cs
Normal file
98
Moonlight/App/Services/TranslationService.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Moonlight.App.Helpers;
|
||||
|
||||
namespace Moonlight.App.Services
|
||||
{
|
||||
public class TranslationService
|
||||
{
|
||||
private string LanguageCode { get; set; } = "en_us";
|
||||
private readonly string FallbackLanguage = "en_us";
|
||||
|
||||
private TranslationHelper Helper { get; }
|
||||
private HttpContext HttpContext { get; }
|
||||
|
||||
public TranslationService(TranslationHelper helper, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
Helper = helper;
|
||||
HttpContext = httpContextAccessor.HttpContext!;
|
||||
|
||||
LanguageCode = FallbackLanguage;
|
||||
|
||||
try
|
||||
{
|
||||
var langHeader = HttpContext.Request.Headers["Accept-Language"].ToString();
|
||||
var important = langHeader.Split(";").First().ToLower().Split(",");
|
||||
|
||||
foreach (var v in important)
|
||||
{
|
||||
if (v.Contains("de"))
|
||||
{
|
||||
LanguageCode = "de_de";
|
||||
break;
|
||||
}
|
||||
else if (v.Contains("en"))
|
||||
{
|
||||
LanguageCode = "en_us";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var cookies = HttpContext.Request.Headers["Cookie"].ToString().Split(new string[] { ",", ";" }, StringSplitOptions.TrimEntries);
|
||||
|
||||
foreach (var cookie in cookies)
|
||||
{
|
||||
var name = cookie.Split("=").First().Trim();
|
||||
var value = cookie.Split("=").Last().Trim();
|
||||
|
||||
if (name == "lang")
|
||||
{
|
||||
if (value.Contains("de"))
|
||||
{
|
||||
LanguageCode = "de_de";
|
||||
break;
|
||||
}
|
||||
else if (value.Contains("en"))
|
||||
{
|
||||
LanguageCode = "en_us";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public string Translate(string key, params object[] parameters)
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = Helper.Get(LanguageCode, key);
|
||||
|
||||
if (text == null)
|
||||
return key;
|
||||
|
||||
int i = 0;
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
text = text.Replace($"{{{i}}}", param.ToString());
|
||||
i++;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Net.Logger.Error(ex);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public MarkupString TranslateMarkup(string key, params object[] parameters)
|
||||
{
|
||||
return new MarkupString(Translate(key, parameters));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
@using Moonlight.Shared.Layouts
|
||||
|
||||
<Router AppAssembly="@typeof(BlazorApp).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace Moonlight.Data
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace Moonlight.Data
|
||||
{
|
||||
public class WeatherForecastService
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
|
||||
{
|
||||
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = startDate.AddDays(index),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
}).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,56 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="aaPanelSharp" Version="1.0.0" />
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
|
||||
<PackageReference Include="Blazor.ContextMenu" Version="1.15.0" />
|
||||
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
||||
<PackageReference Include="BlazorTable" Version="1.17.0" />
|
||||
<PackageReference Include="CurrieTechnologies.Razor.SweetAlert2" Version="5.4.0" />
|
||||
<PackageReference Include="Discord.Net" Version="3.9.0" />
|
||||
<PackageReference Include="GravatarSharp.Core" Version="0.9.0.2" />
|
||||
<PackageReference Include="JWT" Version="10.0.2" />
|
||||
<PackageReference Include="Logging.Net" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" />
|
||||
<PackageReference Include="MineStat" Version="3.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3-beta1" />
|
||||
<PackageReference Include="Otp.NET" Version="1.3.0" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
|
||||
<PackageReference Include="PteroConsole.NET" Version="1.0.4" />
|
||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
||||
<PackageReference Include="RestSharp" Version="109.0.0-preview.1" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="XtermBlazor" Version="1.6.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\bootstrap\bootstrap.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\bootstrap\bootstrap.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\FONT-LICENSE" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\css\open-iconic-bootstrap.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.eot" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.otf" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.svg" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.ttf" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.woff" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\ICON-LICENSE" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\README.md" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\site.css" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="App\Database\Migrations" />
|
||||
<Folder Include="App\Exceptions" />
|
||||
<Folder Include="App\Http\Controllers" />
|
||||
<Folder Include="App\Http\Middleware" />
|
||||
<Folder Include="App\Http\Requests" />
|
||||
<Folder Include="App\Http\Resources" />
|
||||
<Folder Include="wwwroot\assets\media" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
@page "/counter"
|
||||
|
||||
<PageTitle>Counter</PageTitle>
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p role="status">Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
@page "/fetchdata"
|
||||
|
||||
<PageTitle>Weather forecast</PageTitle>
|
||||
|
||||
@using Moonlight.Data
|
||||
@inject WeatherForecastService ForecastService
|
||||
|
||||
<h1>Weather forecast</h1>
|
||||
|
||||
<p>This component demonstrates fetching data from a service.</p>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.Date.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@code {
|
||||
private WeatherForecast[]? forecasts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
@page "/"
|
||||
|
||||
<PageTitle>Index</PageTitle>
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
||||
|
||||
<SurveyPrompt Title="How is Blazor working for you?" />
|
||||
@@ -5,4 +5,25 @@
|
||||
Layout = "_Layout";
|
||||
}
|
||||
|
||||
<component type="typeof(App)" render-mode="ServerPrerendered" />
|
||||
<component type="typeof(BlazorApp)" render-mode="ServerPrerendered" />
|
||||
|
||||
<div id="components-reconnect-modal" class="my-reconnect-modal components-reconnect-hide">
|
||||
<div class="show">
|
||||
<p>
|
||||
<br/>
|
||||
Connecting to moonlight servers
|
||||
</p>
|
||||
</div>
|
||||
<div class="failed">
|
||||
<p>
|
||||
<br />
|
||||
Connection to moonlight servers failed
|
||||
</p>
|
||||
</div>
|
||||
<div class="rejected">
|
||||
<p>
|
||||
<br />
|
||||
Connection to moonlight servers rejected
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,32 +1,111 @@
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Moonlight.App.Services
|
||||
@namespace Moonlight.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var headerConfig = ConfigService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Html")
|
||||
.GetSection("Headers");
|
||||
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<base href="~/" />
|
||||
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
||||
<link href="css/site.css" rel="stylesheet" />
|
||||
<link href="Moonlight.styles.css" rel="stylesheet" />
|
||||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
|
||||
<meta charset="utf-8"/>
|
||||
|
||||
<meta property="og:locale" content="de_DE"/>
|
||||
<meta property="og:type" content="article"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Title"))" property="og:title"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Description"))" property="og:description"/>
|
||||
<meta content="@(moonlightConfig.GetValue<string>("AppUrl"))" property="og:url"/>
|
||||
<meta content="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" property="og:image"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Color"))" data-react-helmet="true" name="theme-color"/>
|
||||
|
||||
<meta content="@(headerConfig.GetValue<string>("Description"))" name="description"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Keywords"))" name="keywords"/>
|
||||
|
||||
<link rel="shortcut icon" href="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg"/>
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700"/>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/style.bundle.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/flashbang.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/snow.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/invisiblea.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/boxicons.min.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/blazor.css"/>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/_content/XtermBlazor/XtermBlazor.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/_content/Blazor.ContextMenu/blazorContextMenu.min.css"/>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<base href="~/"/>
|
||||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered"/>
|
||||
|
||||
<title>Loading</title>
|
||||
</head>
|
||||
<body>
|
||||
@RenderBody()
|
||||
<body
|
||||
class="app-default"
|
||||
cz-shortcut-listen="true"
|
||||
data-kt-app-layout="dark-sidebar"
|
||||
data-kt-app-header-fixed="true"
|
||||
data-kt-app-sidebar-fixed="true"
|
||||
data-kt-app-sidebar-hoverable="true"
|
||||
data-kt-app-sidebar-push-header="true"
|
||||
data-kt-app-sidebar-push-toolbar="true"
|
||||
data-kt-app-sidebar-push-footer="true"
|
||||
data-kt-app-toolbar-enabled="true">
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
An error has occurred. This application may no longer respond until reloaded.
|
||||
</environment>
|
||||
<environment include="Development">
|
||||
An unhandled exception has occurred. See browser dev tools for details.
|
||||
</environment>
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
@RenderBody()
|
||||
|
||||
<div id="flashbang" class="flashbanglight"></div>
|
||||
|
||||
<div class="app-page-loader flex-column">
|
||||
<img alt="Logo" src="/api/moonlight/resources/images/logo.svg" class="h-25px"/>
|
||||
|
||||
<div class="d-flex align-items-center mt-5">
|
||||
<span class="spinner-border text-primary" role="status"></span>
|
||||
<span class="text-muted fs-6 fw-semibold ms-5">CHANGEME</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
<script src="/_framework/blazor.server.js"></script>
|
||||
|
||||
<script src="/_content/XtermBlazor/XtermBlazor.min.js"></script>
|
||||
<script src="/_content/BlazorTable/BlazorTable.min.js"></script>
|
||||
<script src="/_content/BlazorInputFile/inputfile.js"></script>
|
||||
<script src="/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
|
||||
<script src="/_content/BlazorMonaco/jsInterop.js"></script>
|
||||
<script src="/_content/CurrieTechnologies.Razor.SweetAlert2/sweetAlert2.min.js"></script>
|
||||
<script src="/_content/Blazor-ApexCharts/js/blazor-apex-charts.js"></script>
|
||||
<script src="/_content/Blazor.ContextMenu/blazorContextMenu.min.js"></script>
|
||||
|
||||
<script src="https://www.google.com/recaptcha/api.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-search@0.8.2/lib/xterm-addon-search.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-web-links@0.5.0/lib/xterm-addon-web-links.min.js"></script>
|
||||
|
||||
<script src="/assets/js/scripts.bundle.js"></script>
|
||||
<script src="/assets/js/flashbang.js"></script>
|
||||
<script src="/assets/js/cookieUtils.js"></script>
|
||||
<script src="/assets/js/clipboard.js"></script>
|
||||
<script src="/assets/js/toastUtils.js"></script>
|
||||
<script src="/assets/js/alertUtils.js"></script>
|
||||
<script src="/assets/js/utils.js"></script>
|
||||
<script src="/assets/js/loggingUtils.js"></script>
|
||||
<script src="/assets/js/snow.js"></script>
|
||||
<script src="/assets/js/recaptcha.js"></script>
|
||||
<script src="/assets/js/xtermAddons.js"></script>
|
||||
<script src="/assets/js/monaco.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,9 +1,14 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using BlazorTable;
|
||||
using CurrieTechnologies.Razor.SweetAlert2;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Helpers;
|
||||
using Moonlight.App.Repositories;
|
||||
using Moonlight.App.Repositories.Servers;
|
||||
using Moonlight.App.Services;
|
||||
using Moonlight.App.Services.Interop;
|
||||
using Moonlight.App.Services.Sessions;
|
||||
|
||||
using Moonlight.Data;
|
||||
|
||||
namespace Company.WebApplication1
|
||||
namespace Moonlight
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
@@ -14,7 +19,36 @@ namespace Company.WebApplication1
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddServerSideBlazor();
|
||||
builder.Services.AddSingleton<WeatherForecastService>();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
|
||||
// Databases
|
||||
builder.Services.AddDbContext<DataContext>();
|
||||
|
||||
// Repositories
|
||||
builder.Services.AddSingleton<SessionRepository>();
|
||||
builder.Services.AddScoped<UserRepository>();
|
||||
builder.Services.AddScoped<NodeRepository>();
|
||||
builder.Services.AddScoped<ServerRepository>();
|
||||
builder.Services.AddScoped<ServerBackupRepository>();
|
||||
|
||||
// Services
|
||||
builder.Services.AddScoped<TranslationService>();
|
||||
builder.Services.AddSingleton<ConfigService>();
|
||||
builder.Services.AddScoped<CookieService>();
|
||||
builder.Services.AddScoped<IdentityService>();
|
||||
builder.Services.AddScoped<IpLocateService>();
|
||||
builder.Services.AddScoped<SessionService>();
|
||||
builder.Services.AddScoped<TranslationService>();
|
||||
builder.Services.AddScoped<AlertService>();
|
||||
|
||||
// Helpers
|
||||
builder.Services.AddSingleton<TranslationHelper>();
|
||||
|
||||
// Third party services
|
||||
|
||||
builder.Services.AddBlazorTable();
|
||||
builder.Services.AddSweetAlert2(options => { options.Theme = SweetAlertTheme.Dark; });
|
||||
builder.Services.AddBlazorContextMenu();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
21
Moonlight/Shared/Components/Alerts/BannedAlert.razor
Normal file
21
Moonlight/Shared/Components/Alerts/BannedAlert.razor
Normal file
@@ -0,0 +1,21 @@
|
||||
@using Moonlight.App.Services
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div class="card card-flush w-lg-650px py-5">
|
||||
<div class="card-body py-15 py-lg-20">
|
||||
<div class="mb-14">
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" class="h-40px">
|
||||
</div>
|
||||
<h1 class="fw-bolder text-gray-900 mb-5">@(TranslationService.Translate("Alerts.Banned.Title"))</h1>
|
||||
<div class="fw-semibold fs-6 text-gray-500 mb-8">
|
||||
@(TranslationService.Translate("Alerts.Banned.Details"))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
21
Moonlight/Shared/Components/Alerts/DisabledAlert.razor
Normal file
21
Moonlight/Shared/Components/Alerts/DisabledAlert.razor
Normal file
@@ -0,0 +1,21 @@
|
||||
@using Moonlight.App.Services
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div class="card card-flush w-lg-650px py-5">
|
||||
<div class="card-body py-15 py-lg-20">
|
||||
<div class="mb-14">
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" class="h-40px">
|
||||
</div>
|
||||
<h1 class="fw-bolder text-gray-900 mb-5">@(TranslationService.Translate("Alerts.Disabled.Title"))</h1>
|
||||
<div class="fw-semibold fs-6 text-gray-500 mb-8">
|
||||
@(TranslationService.Translate("Alerts.Disabled.Details"))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,73 @@
|
||||
@using Moonlight.App.Services
|
||||
@using Logging.Net
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@inherits ErrorBoundary
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
@if (CurrentException is null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else if (ErrorContent is not null)
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Component.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Component.Details")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Component.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Component.Details")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
List<Exception> receivedExceptions = new();
|
||||
|
||||
protected override async Task OnErrorAsync(Exception exception)
|
||||
{
|
||||
receivedExceptions.Add(exception);
|
||||
|
||||
var user = await IdentityService.Get();
|
||||
var id = user == null ? -1 : user.Id;
|
||||
|
||||
Logger.Error($"[{id}] An unhanded exception occured:");
|
||||
Logger.Error(exception);
|
||||
|
||||
//TODO: Create error report
|
||||
|
||||
await base.OnErrorAsync(exception);
|
||||
}
|
||||
|
||||
public new void Recover()
|
||||
{
|
||||
receivedExceptions.Clear();
|
||||
base.Recover();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
@using Moonlight.App.Services
|
||||
@using Logging.Net
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@inherits ErrorBoundary
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
@if (CurrentException is null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else if (ErrorContent is not null)
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@(TranslationService.Translate("Crashes.Global.Title"))
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@(TranslationService.Translate("Crashes.Global.Details"))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Global.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Global.Details")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
List<Exception> receivedExceptions = new();
|
||||
|
||||
protected override async Task OnErrorAsync(Exception exception)
|
||||
{
|
||||
receivedExceptions.Add(exception);
|
||||
|
||||
var user = await IdentityService.Get();
|
||||
var id = user == null ? -1 : user.Id;
|
||||
|
||||
Logger.Error($"[{id}] An unhanded exception occured:");
|
||||
Logger.Error(exception);
|
||||
|
||||
await base.OnErrorAsync(exception);
|
||||
}
|
||||
|
||||
public new void Recover()
|
||||
{
|
||||
receivedExceptions.Clear();
|
||||
base.Recover();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
@using Logging.Net
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@inherits ErrorBoundary
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
@if (CurrentException is null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else if (ErrorContent is not null)
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Page.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Page.Details")
|
||||
</div>
|
||||
</div>
|
||||
<img class="mx-auto h-150px h-lg-200px" src="/assets/media/svg/illustrations/broken-cable.svg" alt="Broken cable">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Page.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Page.Details")
|
||||
</div>
|
||||
</div>
|
||||
<img class="mx-auto h-150px h-lg-200px" src="/assets/media/svg/illustrations/broken-cable.svg" alt="Broken cable">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
List<Exception> receivedExceptions = new();
|
||||
|
||||
protected override async Task OnErrorAsync(Exception exception)
|
||||
{
|
||||
receivedExceptions.Add(exception);
|
||||
|
||||
var user = await IdentityService.Get();
|
||||
var id = user == null ? -1 : user.Id;
|
||||
|
||||
Logger.Error($"[{id}] An unhanded exception occured:");
|
||||
Logger.Error(exception);
|
||||
|
||||
await base.OnErrorAsync(exception);
|
||||
}
|
||||
|
||||
public new void Recover()
|
||||
{
|
||||
receivedExceptions.Clear();
|
||||
base.Recover();
|
||||
}
|
||||
}
|
||||
38
Moonlight/Shared/Components/Partials/Footer.razor
Normal file
38
Moonlight/Shared/Components/Partials/Footer.razor
Normal file
@@ -0,0 +1,38 @@
|
||||
@using Moonlight.App.Services
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var marketingConfig = ConfigService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Marketing");
|
||||
}
|
||||
|
||||
<div id="kt_app_footer" class="app-footer">
|
||||
<div class="app-container container-fluid d-flex flex-column flex-md-row flex-center flex-md-stack py-3">
|
||||
<div class="text-dark order-2 order-md-1">
|
||||
<span class="text-muted fw-semibold me-1">2022 - @DateTime.Now.Year©</span>
|
||||
<a href="@(marketingConfig.GetValue<string>("Website"))" target="_blank" class="text-gray-800 text-hover-primary">
|
||||
@(marketingConfig.GetValue<string>("BrandName"))
|
||||
</a>
|
||||
</div>
|
||||
<ul class="menu menu-gray-600 menu-hover-primary fw-semibold order-1">
|
||||
<li class="menu-item">
|
||||
<a href="@(marketingConfig.GetValue<string>("About"))" target="_blank" class="menu-link px-2">
|
||||
@(TranslationService.Translate("Footer.AboutUs"))
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a href="@(marketingConfig.GetValue<string>("Imprint"))" target="_blank" class="menu-link px-2">
|
||||
@(TranslationService.Translate("Footer.Imprint"))
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a href="@(marketingConfig.GetValue<string>("Privacy"))" target="_blank" class="menu-link px-2">
|
||||
@(TranslationService.Translate("Footer.Privacy"))
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
90
Moonlight/Shared/Components/Partials/Navbar.razor
Normal file
90
Moonlight/Shared/Components/Partials/Navbar.razor
Normal file
@@ -0,0 +1,90 @@
|
||||
@using Moonlight.App.Helpers
|
||||
@using Moonlight.App.Repositories
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Services.Sessions
|
||||
@using Moonlight.App.Database.Entities
|
||||
@using Task = System.Threading.Tasks.Task
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject CookieService CookieService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
<div class="app-navbar flex-shrink-0">
|
||||
<div class="app-navbar-item ms-1 ms-lg-3">
|
||||
<ThemeSwitcher
|
||||
ToggleBtnClass="btn btn-icon btn-custom btn-icon-muted btn-active-light btn-active-color-primary w-35px h-35px w-md-40px h-md-40px"
|
||||
ToggleBtnIconClass="svg-icon svg-icon-2">
|
||||
</ThemeSwitcher>
|
||||
</div>
|
||||
|
||||
@if (User != null)
|
||||
{
|
||||
<div class="app-navbar-item ms-1 ms-lg-3">
|
||||
<div class="btn btn-icon btn-custom btn-icon-muted btn-active-light btn-active-color-primary w-35px h-35px w-md-40px h-md-40px position-relative" id="support_ticket_toggle">
|
||||
<span class="svg-icon svg-icon-1">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.3" d="M20 3H4C2.89543 3 2 3.89543 2 5V16C2 17.1046 2.89543 18 4 18H4.5C5.05228 18 5.5 18.4477 5.5 19V21.5052C5.5 22.1441 6.21212 22.5253 6.74376 22.1708L11.4885 19.0077C12.4741 18.3506 13.6321 18 14.8167 18H20C21.1046 18 22 17.1046 22 16V5C22 3.89543 21.1046 3 20 3Z" fill="currentColor"></path>
|
||||
<rect x="6" y="12" width="7" height="2" rx="1" fill="currentColor"></rect>
|
||||
<rect x="6" y="7" width="12" height="2" rx="1" fill="currentColor"></rect>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-navbar-item ms-1 ms-lg-3" id="kt_header_user_menu_toggle">
|
||||
<div class="cursor-pointer symbol symbol-35px symbol-md-40px" data-kt-menu-trigger="click" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<img alt="Avatar" src="/api/moonlight/avatar/@(User.Id)"/>
|
||||
</div>
|
||||
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-800 menu-state-bg menu-state-primary fw-semibold py-4 fs-6 w-275px" data-kt-menu="true">
|
||||
<div class="menu-item px-3">
|
||||
<div class="menu-content d-flex align-items-center px-3">
|
||||
<div class="symbol symbol-50px me-5">
|
||||
<img alt="Avatar" src="/api/moonlight/avatar/@(User.Id)"/>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="fw-bold d-flex align-items-center fs-5">
|
||||
@(User.FirstName) @(User.LastName)
|
||||
|
||||
@if (User.Admin)
|
||||
{
|
||||
<span class="badge badge-light-success fw-bold fs-8 px-2 py-1 ms-2">Admin</span>
|
||||
}
|
||||
</div>
|
||||
<a class="fw-semibold text-muted text-hover-primary fs-7">@(User.Email)</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="separator my-2"></div>
|
||||
<div class="menu-item px-5 my-1">
|
||||
<a href="/settings" class="menu-link px-5">@TranslationService.Translate("Navbar.Account.Settings")</a>
|
||||
</div>
|
||||
<div class="menu-item px-5">
|
||||
<a @onclick="Logout" class="menu-link px-5">@TranslationService.Translate("Navbar.Logout")</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private User? User;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private async void Logout()
|
||||
{
|
||||
await CookieService.SetValue("token", "", 1);
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
||||
}
|
||||
}
|
||||
29
Moonlight/Shared/Components/Partials/PageHeader.razor
Normal file
29
Moonlight/Shared/Components/Partials/PageHeader.razor
Normal file
@@ -0,0 +1,29 @@
|
||||
@using Moonlight.App.Services
|
||||
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div id="kt_app_header" class="app-header">
|
||||
<div class="app-container container-fluid d-flex align-items-stretch justify-content-between">
|
||||
<div class="d-flex align-items-center d-lg-none ms-n2 me-2" title="Show sidebar menu">
|
||||
<div class="btn btn-icon btn-active-color-primary w-35px h-35px" id="kt_app_sidebar_mobile_toggle">
|
||||
<i class="bx bx-menu bx-md"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center flex-grow-1 flex-lg-grow-0">
|
||||
<a href="/" class="d-lg-none">
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="h-30px"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="d-flex align-items-stretch justify-content-between flex-lg-grow-1" id="kt_app_header_wrapper">
|
||||
<div class="app-header-menu app-header-mobile-drawer align-items-stretch" data-kt-drawer="true" data-kt-drawer-name="app-header-menu" data-kt-drawer-activate="{default: true, lg: false}" data-kt-drawer-overlay="true" data-kt-drawer-width="225px" data-kt-drawer-direction="end" data-kt-drawer-toggle="#kt_app_header_menu_toggle" data-kt-swapper="true" data-kt-swapper-mode="{default: 'append', lg: 'prepend'}" data-kt-swapper-parent="{default: '#kt_app_body', lg: '#kt_app_header_wrapper'}">
|
||||
<div class="menu menu-rounded menu-column menu-lg-row my-5 my-lg-0 align-items-stretch fw-semibold px-2 px-lg-0" id="kt_app_header_menu" data-kt-menu="true">
|
||||
</div>
|
||||
</div>
|
||||
<Navbar></Navbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
63
Moonlight/Shared/Components/Partials/Sidebar.razor
Normal file
63
Moonlight/Shared/Components/Partials/Sidebar.razor
Normal file
@@ -0,0 +1,63 @@
|
||||
@using Moonlight.App.Services.Sessions
|
||||
@using Moonlight.App.Database.Entities
|
||||
@using Moonlight.App.Services
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div id="kt_app_sidebar" class="app-sidebar flex-column" data-kt-drawer="true" data-kt-drawer-name="app-sidebar" data-kt-drawer-activate="{default: true, lg: false}" data-kt-drawer-overlay="true" data-kt-drawer-width="225px" data-kt-drawer-direction="start" data-kt-drawer-toggle="#kt_app_sidebar_mobile_toggle">
|
||||
<div class="app-sidebar-logo px-6" id="kt_app_sidebar_logo">
|
||||
<a href="@(User != null ? "/" : "/login")">
|
||||
@if (sidebar == "dark-sidebar")
|
||||
{
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" class="h-45px app-sidebar-logo-default"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sidebar == "light-sidebar")
|
||||
{
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="theme-light-show h-20px app-sidebar-logo-default"/>
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="theme-dark-show h-20px app-sidebar-logo-default"/>
|
||||
}
|
||||
}
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="h-20px app-sidebar-logo-minimize"/>
|
||||
</a>
|
||||
|
||||
<div id="kt_app_sidebar_toggle" class="app-sidebar-toggle btn btn-icon btn-shadow btn-sm btn-color-muted btn-active-color-primary body-bg h-30px w-30px position-absolute top-50 start-100 translate-middle rotate" data-kt-toggle="true" data-kt-toggle-state="active" data-kt-toggle-target="body" data-kt-toggle-name="app-sidebar-minimize">
|
||||
<i class="bx bx-chevrons-left bx-md"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SidebarMenu></SidebarMenu>
|
||||
|
||||
<div class="app-sidebar-footer flex-column-auto pt-2 pb-6 px-6" id="kt_app_sidebar_footer">
|
||||
<a id="support_ticket_toggle_sidebar"
|
||||
class="btn btn-flex flex-center btn-custom btn-primary overflow-hidden text-nowrap px-0 h-40px w-100 btn-label">
|
||||
@(TranslationService.Translate("Sidebar.Footer.OpenSupport"))
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private string sidebar;
|
||||
|
||||
private User? User;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
sidebar = await JsRuntime.InvokeAsync<string>("document.body.getAttribute", "data-kt-app-layout");
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
266
Moonlight/Shared/Components/Partials/SidebarMenu.razor
Normal file
266
Moonlight/Shared/Components/Partials/SidebarMenu.razor
Normal file
@@ -0,0 +1,266 @@
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Services.Sessions
|
||||
@using Moonlight.App.Database.Entities
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject IdentityService IdentityService
|
||||
|
||||
<div class="app-sidebar-menu overflow-hidden flex-column-fluid">
|
||||
<div id="kt_app_sidebar_menu_wrapper" class="app-sidebar-wrapper hover-scroll-overlay-y my-5" data-kt-scroll="true" data-kt-scroll-activate="true" data-kt-scroll-height="auto" data-kt-scroll-dependencies="#kt_app_sidebar_logo, #kt_app_sidebar_footer" data-kt-scroll-wrappers="#kt_app_sidebar_menu" data-kt-scroll-offset="5px" data-kt-scroll-save-state="true">
|
||||
<div class="menu menu-column menu-rounded menu-sub-indention px-3" id="#kt_app_sidebar_menu" data-kt-menu="true" data-kt-menu-expand="false">
|
||||
@if (User == null)
|
||||
{
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/login">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bxs-log-in"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Login")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/register">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-user-plus"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Register")</span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-layer"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Dashboard")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div data-kt-menu-trigger="click" class="menu-item menu-accordion">
|
||||
<span class="menu-link">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-cart-alt"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Order")</span>
|
||||
<span class="menu-arrow"></span>
|
||||
</span>
|
||||
<div class="menu-sub menu-sub-accordion">
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/store/website">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Website")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/store/database">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Database")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/store/domain">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Domain")</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/servers">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-server"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Servers")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/websites">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-globe"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Websites")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/databases">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-data"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Databases")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/domains">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-purchase-tag"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Domains")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/changelog">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-notepad"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Changelog")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
if (User.Admin)
|
||||
{
|
||||
<div class="menu-item pt-5">
|
||||
<div class="menu-content">
|
||||
<span class="menu-heading fw-bold text-uppercase fs-7">@TranslationService.Translate("Sidebar.Menu.Admin")</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-layer"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Dashboard")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/general">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-chip"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.System")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div data-kt-menu-trigger="click" class="menu-item menu-accordion">
|
||||
<span class="menu-link">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-server"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Servers")</span>
|
||||
<span class="menu-arrow"></span>
|
||||
</span>
|
||||
<div class="menu-sub menu-sub-accordion">
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/servers">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Overview")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/servers/manager">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Manager")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/servers/cleanup">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Cleanup")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/nodes">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Nodes")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/images">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Images")</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-kt-menu-trigger="click" class="menu-item menu-accordion">
|
||||
<span class="menu-link">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-cube"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.AaPanel")</span>
|
||||
<span class="menu-arrow"></span>
|
||||
</span>
|
||||
<div class="menu-sub menu-sub-accordion">
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/aapanel/">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Overview")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/aapanel/databases">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Databases")</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/users">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-user"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Users")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/support">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-support"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Support")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/statistics">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-objects-vertical-bottom"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Statistics")</span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private User? User;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
Moonlight/Shared/Components/Partials/ThemeSwitcher.razor
Normal file
52
Moonlight/Shared/Components/Partials/ThemeSwitcher.razor
Normal file
@@ -0,0 +1,52 @@
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
<a href="#" class="@ToggleBtnClass" data-kt-menu-trigger="@Trigger" data-kt-menu-attach="parent" data-kt-menu-placement="@MenuPlacement">
|
||||
<i class="theme-light-show bx bx-sun"></i>
|
||||
<i class="theme-dark-show bx bx-moon" ></i>
|
||||
</a>
|
||||
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-title-gray-700 menu-icon-muted menu-active-bg menu-state-primary fw-semibold py-4 fs-base w-175px" data-kt-menu="true" data-kt-element="theme-mode-menu">
|
||||
<div class="menu-item px-3 my-0">
|
||||
<a href="#" class="menu-link px-3 py-2" data-kt-element="mode" data-kt-value="light" @onclick="TriggerFlashbang">
|
||||
<span class="menu-icon" data-kt-element="icon">
|
||||
<i class="bx bx-sun"></i>
|
||||
</span>
|
||||
<span class="menu-title">Lightmode</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item px-3 my-0">
|
||||
<a href="#" class="menu-link px-3 py-2" data-kt-element="mode" data-kt-value="dark">
|
||||
<span class="menu-icon" data-kt-element="icon">
|
||||
<i class="bx bx-moon"></i>
|
||||
</span>
|
||||
<span class="menu-title">Darkmode</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item px-3 my-0">
|
||||
<a href="#" class="menu-link px-3 py-2" data-kt-element="mode" data-kt-value="system">
|
||||
<span class="menu-icon" data-kt-element="icon">
|
||||
<i class="bx bx-cog"></i>
|
||||
</span>
|
||||
<span class="menu-title">System</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string ToggleBtnClass { get; set; } = "";
|
||||
|
||||
[Parameter]
|
||||
public string MenuPlacement { get; set; } = "bottom-end";
|
||||
|
||||
[Parameter]
|
||||
public string ToggleBtnIconClass { get; set; } = "svg-icon svg-icon-2";
|
||||
|
||||
[Parameter]
|
||||
public string Trigger { get; set; } = "{default:'click'}";
|
||||
|
||||
private async void TriggerFlashbang()
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("flashbang");
|
||||
}
|
||||
}
|
||||
139
Moonlight/Shared/Layouts/MainLayout.razor
Normal file
139
Moonlight/Shared/Layouts/MainLayout.razor
Normal file
@@ -0,0 +1,139 @@
|
||||
@using Moonlight.Shared.Components.ErrorBoundaries
|
||||
@using Moonlight.Shared.Components.Partials
|
||||
@using Moonlight.Shared.Components.Alerts
|
||||
@using Moonlight.App.Database.Entities
|
||||
@using Moonlight.App.Models.Misc
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@layout ThemeInit
|
||||
@implements IDisposable
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@inject IJSRuntime JsRuntime
|
||||
@inject IdentityService IdentityService
|
||||
@inject SessionService SessionService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<GlobalErrorBoundary>
|
||||
<div class="d-flex flex-column flex-root app-root" id="kt_app_root">
|
||||
<div class="app-page flex-column flex-column-fluid" id="kt_app_page">
|
||||
<canvas id="snow" class="snow-canvas"></canvas>
|
||||
|
||||
@{
|
||||
//TODO: Add a way to disable the snow
|
||||
}
|
||||
|
||||
<PageHeader></PageHeader>
|
||||
<div class="app-wrapper flex-column flex-row-fluid" id="kt_app_wrapper">
|
||||
<Sidebar></Sidebar>
|
||||
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
|
||||
<div class="d-flex flex-column flex-column-fluid">
|
||||
<div id="kt_app_content" class="app-content flex-column-fluid">
|
||||
<div id="kt_app_content_container" class="app-container container-fluid">
|
||||
<div class="mt-10">
|
||||
<PageErrorBoundary>
|
||||
@if (User == null)
|
||||
{
|
||||
@Body
|
||||
}
|
||||
else
|
||||
{
|
||||
if (User.Status == UserStatus.Banned)
|
||||
{
|
||||
<BannedAlert></BannedAlert>
|
||||
}
|
||||
else if (User.Status == UserStatus.Disabled)
|
||||
{
|
||||
<DisabledAlert></DisabledAlert>
|
||||
}
|
||||
else
|
||||
{
|
||||
@Body
|
||||
}
|
||||
}
|
||||
</PageErrorBoundary>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer></Footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GlobalErrorBoundary>
|
||||
|
||||
@code
|
||||
{
|
||||
private User? User;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
AddBodyAttribute("data-kt-app-page-loading", "on");
|
||||
}
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
//Initialize classes and attributes for layout with dark sidebar
|
||||
AddBodyAttribute("data-kt-app-reset-transition", "true");
|
||||
|
||||
AddBodyAttribute("data-kt-app-layout", "dark-sidebar");
|
||||
AddBodyAttribute("data-kt-app-header-fixed", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-fixed", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-hoverable", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-push-header", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-push-toolbar", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-push-footer", "true");
|
||||
AddBodyAttribute("data-kt-app-toolbar-enabled", "true");
|
||||
|
||||
AddBodyClass("app-default");
|
||||
|
||||
JsRuntime.InvokeVoidAsync("KTModalUpgradePlan.init");
|
||||
JsRuntime.InvokeVoidAsync("KTCreateApp.init");
|
||||
JsRuntime.InvokeVoidAsync("KTModalUserSearch.init");
|
||||
JsRuntime.InvokeVoidAsync("KTModalNewTarget.init");
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
try
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await Task.Delay(300);
|
||||
|
||||
await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-reset-transition");
|
||||
await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-page-loading");
|
||||
await JsRuntime.InvokeVoidAsync("KTMenu.createInstances");
|
||||
await JsRuntime.InvokeVoidAsync("KTDrawer.createInstances");
|
||||
await JsRuntime.InvokeVoidAsync("createSnow");
|
||||
|
||||
await SessionService.Register();
|
||||
|
||||
NavigationManager.LocationChanged += (sender, args) => { SessionService.Refresh(); };
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SessionService.Close();
|
||||
}
|
||||
|
||||
private void AddBodyAttribute(string attribute, string value)
|
||||
{
|
||||
JsRuntime.InvokeVoidAsync("document.body.setAttribute", attribute, value);
|
||||
}
|
||||
|
||||
private void AddBodyClass(string className)
|
||||
{
|
||||
JsRuntime.InvokeVoidAsync("document.body.classList.add", className);
|
||||
}
|
||||
}
|
||||
78
Moonlight/Shared/Layouts/ThemeInit.razor
Normal file
78
Moonlight/Shared/Layouts/ThemeInit.razor
Normal file
@@ -0,0 +1,78 @@
|
||||
@inherits LayoutComponentBase
|
||||
@inject IJSRuntime JS
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@Body
|
||||
|
||||
<script suppress-error="BL9992">
|
||||
window.emptyBody = function(){
|
||||
document.body.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
@code
|
||||
{
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
JS.InvokeVoidAsync("KTThemeMode.init");
|
||||
JS.InvokeVoidAsync("emptyBody");
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
JS.InvokeVoidAsync("scrollTo", 0, 0);
|
||||
JS.InvokeVoidAsync("KTDialer.init");
|
||||
JS.InvokeVoidAsync("KTDrawer.init");
|
||||
JS.InvokeVoidAsync("KTMenu.init");
|
||||
JS.InvokeVoidAsync("KTImageInput.init");
|
||||
JS.InvokeVoidAsync("KTPasswordMeter.init");
|
||||
JS.InvokeVoidAsync("KTScroll.init");
|
||||
JS.InvokeVoidAsync("KTScrolltop.init");
|
||||
JS.InvokeVoidAsync("KTSticky.init");
|
||||
JS.InvokeVoidAsync("KTSwapper.init");
|
||||
JS.InvokeVoidAsync("KTToggle.init");
|
||||
JS.InvokeVoidAsync("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(NavigationManager.Uri)}");
|
||||
}
|
||||
|
||||
JS.InvokeVoidAsync("KTLayoutSearch.init");
|
||||
JS.InvokeVoidAsync("KTAppSidebar.init");
|
||||
}
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
NavigationManager.LocationChanged += OnLocationChanged;
|
||||
}
|
||||
|
||||
private async void OnLocationChanged(object sender, LocationChangedEventArgs args)
|
||||
{
|
||||
await InvokeJsSave("scrollTo", 0, 0);
|
||||
await InvokeJsSave("KTDrawer.createInstances");
|
||||
await InvokeJsSave("KTMenu.createInstances");
|
||||
await InvokeJsSave("KTImageInput.createInstances");
|
||||
await InvokeJsSave("KTPasswordMeter.createInstances");
|
||||
await InvokeJsSave("KTScroll.createInstances");
|
||||
await InvokeJsSave("KTScrolltop.createInstances");
|
||||
await InvokeJsSave("KTSticky.createInstances");
|
||||
await InvokeJsSave("KTSwapper.createInstances");
|
||||
await InvokeJsSave("KTToggle.createInstances");
|
||||
await InvokeJsSave("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(args.Location)}");
|
||||
await InvokeJsSave("KTAppSidebar.init");
|
||||
}
|
||||
|
||||
private async Task InvokeJsSave(string method, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
await JS.InvokeVoidAsync(method, args);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
NavigationManager.LocationChanged -= OnLocationChanged;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<PageTitle>Moonlight</PageTitle>
|
||||
|
||||
<div class="page">
|
||||
<div class="sidebar">
|
||||
<NavMenu />
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="top-row px-4">
|
||||
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
@@ -1,70 +0,0 @@
|
||||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
.top-row a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row:not(.auth) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-row.auth {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row a, .top-row .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<div class="top-row ps-3 navbar navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="">Moonlight</a>
|
||||
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
|
||||
<nav class="flex-column">
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="oi oi-home" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="counter">
|
||||
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="fetchdata">
|
||||
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
|
||||
</NavLink>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool collapseNavMenu = true;
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private void ToggleNavMenu()
|
||||
{
|
||||
collapseNavMenu = !collapseNavMenu;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
.navbar-toggler {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.oi {
|
||||
width: 2rem;
|
||||
font-size: 1.1rem;
|
||||
vertical-align: text-top;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255,255,255,0.25);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<div class="alert alert-secondary mt-4">
|
||||
<span class="oi oi-pencil me-2" aria-hidden="true"></span>
|
||||
<strong>@Title</strong>
|
||||
|
||||
<span class="text-nowrap">
|
||||
Please take our
|
||||
<a target="_blank" class="font-weight-bold link-dark" href="https://go.microsoft.com/fwlink/?linkid=2149017">brief survey</a>
|
||||
</span>
|
||||
and tell us what you think.
|
||||
</div>
|
||||
|
||||
@code {
|
||||
// Demonstrates how a parent component can supply parameters
|
||||
[Parameter]
|
||||
public string? Title { get; set; }
|
||||
}
|
||||
7
Moonlight/Shared/Views/Index.razor
Normal file
7
Moonlight/Shared/Views/Index.razor
Normal file
@@ -0,0 +1,7 @@
|
||||
@page "/"
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
x
|
||||
</div>
|
||||
</div>
|
||||
@@ -7,4 +7,3 @@
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using Moonlight
|
||||
@using Moonlight.Shared
|
||||
|
||||
@@ -15,38 +15,70 @@ build_property.GenerateRazorMetadataSourceChecksumAttributes =
|
||||
build_property.MSBuildProjectDirectory = C:\Users\marce\source\repos\MoonlightPublic\Moonlight\Moonlight
|
||||
build_property._RazorSourceGeneratorDebug =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/App.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = QXBwLnJhem9y
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/BlazorApp.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = Qmxhem9yQXBwLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/Counter.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcQ291bnRlci5yYXpvcg==
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Alerts/BannedAlert.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcQWxlcnRzXEJhbm5lZEFsZXJ0LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/FetchData.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcRmV0Y2hEYXRhLnJhem9y
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Alerts/DisabledAlert.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcQWxlcnRzXERpc2FibGVkQWxlcnQucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/Index.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcSW5kZXgucmF6b3I=
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/ErrorBoundaries/ComponentErrorBoundary.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcRXJyb3JCb3VuZGFyaWVzXENvbXBvbmVudEVycm9yQm91bmRhcnkucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/SurveyPrompt.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFN1cnZleVByb21wdC5yYXpvcg==
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/ErrorBoundaries/GlobalErrorBoundary.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcRXJyb3JCb3VuZGFyaWVzXEdsb2JhbEVycm9yQm91bmRhcnkucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/ErrorBoundaries/PageErrorBoundary.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcRXJyb3JCb3VuZGFyaWVzXFBhZ2VFcnJvckJvdW5kYXJ5LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/Footer.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcRm9vdGVyLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/Navbar.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcTmF2YmFyLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/PageHeader.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcUGFnZUhlYWRlci5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/Sidebar.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcU2lkZWJhci5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/SidebarMenu.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcU2lkZWJhck1lbnUucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/ThemeSwitcher.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcVGhlbWVTd2l0Y2hlci5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Layouts/MainLayout.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXExheW91dHNcTWFpbkxheW91dC5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Layouts/ThemeInit.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXExheW91dHNcVGhlbWVJbml0LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Views/Index.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEluZGV4LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/_Imports.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = X0ltcG9ydHMucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/MainLayout.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXE1haW5MYXlvdXQucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope = b-0cy8r6qmkj
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/NavMenu.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXE5hdk1lbnUucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope = b-h6mpglkmdc
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/Error.cshtml]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcRXJyb3IuY3NodG1s
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -46,9 +46,95 @@
|
||||
"net6.0": {
|
||||
"targetAlias": "net6.0",
|
||||
"dependencies": {
|
||||
"BCrypt.Net-Next": {
|
||||
"target": "Package",
|
||||
"version": "[4.0.3, )"
|
||||
},
|
||||
"Ben.Demystifier": {
|
||||
"target": "Package",
|
||||
"version": "[0.4.1, )"
|
||||
},
|
||||
"Blazor.ContextMenu": {
|
||||
"target": "Package",
|
||||
"version": "[1.15.0, )"
|
||||
},
|
||||
"BlazorMonaco": {
|
||||
"target": "Package",
|
||||
"version": "[3.0.0, )"
|
||||
},
|
||||
"BlazorTable": {
|
||||
"target": "Package",
|
||||
"version": "[1.17.0, )"
|
||||
},
|
||||
"CurrieTechnologies.Razor.SweetAlert2": {
|
||||
"target": "Package",
|
||||
"version": "[5.4.0, )"
|
||||
},
|
||||
"Discord.Net": {
|
||||
"target": "Package",
|
||||
"version": "[3.9.0, )"
|
||||
},
|
||||
"GravatarSharp.Core": {
|
||||
"target": "Package",
|
||||
"version": "[0.9.0.2, )"
|
||||
},
|
||||
"JWT": {
|
||||
"target": "Package",
|
||||
"version": "[10.0.2, )"
|
||||
},
|
||||
"Logging.Net": {
|
||||
"target": "Package",
|
||||
"version": "[1.1.0, )"
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.Design": {
|
||||
"include": "Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive",
|
||||
"suppressParent": "All",
|
||||
"target": "Package",
|
||||
"version": "[7.0.3, )"
|
||||
},
|
||||
"Microsoft.VisualStudio.Azure.Containers.Tools.Targets": {
|
||||
"target": "Package",
|
||||
"version": "[1.15.1, )"
|
||||
},
|
||||
"MineStat": {
|
||||
"target": "Package",
|
||||
"version": "[3.1.1, )"
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"target": "Package",
|
||||
"version": "[13.0.3-beta1, )"
|
||||
},
|
||||
"Otp.NET": {
|
||||
"target": "Package",
|
||||
"version": "[1.3.0, )"
|
||||
},
|
||||
"Pomelo.EntityFrameworkCore.MySql": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.0, )"
|
||||
},
|
||||
"PteroConsole.NET": {
|
||||
"target": "Package",
|
||||
"version": "[1.0.4, )"
|
||||
},
|
||||
"QRCoder": {
|
||||
"target": "Package",
|
||||
"version": "[1.4.3, )"
|
||||
},
|
||||
"RestSharp": {
|
||||
"target": "Package",
|
||||
"version": "[109.0.0-preview.1, )"
|
||||
},
|
||||
"UAParser": {
|
||||
"target": "Package",
|
||||
"version": "[3.1.47, )"
|
||||
},
|
||||
"XtermBlazor": {
|
||||
"target": "Package",
|
||||
"version": "[1.6.1, )"
|
||||
},
|
||||
"aaPanelSharp": {
|
||||
"target": "Package",
|
||||
"version": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
|
||||
@@ -15,7 +15,14 @@
|
||||
<SourceRoot Include="C:\Program Files\dotnet\sdk\NuGetFallbackFolder\" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)xtermblazor\1.6.1\buildTransitive\XtermBlazor.props" Condition="Exists('$(NuGetPackageRoot)xtermblazor\1.6.1\buildTransitive\XtermBlazor.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.3\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.3\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.props" Condition="Exists('$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore.design\7.0.3\build\net6.0\Microsoft.EntityFrameworkCore.Design.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore.design\7.0.3\build\net6.0\Microsoft.EntityFrameworkCore.Design.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)currietechnologies.razor.sweetalert2\5.4.0\buildTransitive\CurrieTechnologies.Razor.SweetAlert2.props" Condition="Exists('$(NuGetPackageRoot)currietechnologies.razor.sweetalert2\5.4.0\buildTransitive\CurrieTechnologies.Razor.SweetAlert2.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazortable\1.17.0\buildTransitive\BlazorTable.props" Condition="Exists('$(NuGetPackageRoot)blazortable\1.17.0\buildTransitive\BlazorTable.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazormonaco\3.0.0\buildTransitive\BlazorMonaco.props" Condition="Exists('$(NuGetPackageRoot)blazormonaco\3.0.0\buildTransitive\BlazorMonaco.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazor.contextmenu\1.15.0\buildTransitive\Blazor.ContextMenu.props" Condition="Exists('$(NuGetPackageRoot)blazor.contextmenu\1.15.0\buildTransitive\Blazor.ContextMenu.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets Condition=" '$(PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets)' == '' ">C:\Users\marce\.nuget\packages\microsoft.visualstudio.azure.containers.tools.targets\1.15.1</PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\6.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\6.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)system.text.json\7.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\7.0.0\buildTransitive\net6.0\System.Text.Json.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,87 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "yy/NjlE13jUBAfYW0Jby0Um0q1bacbuKsTzQSymbyV/SUAbvE/vTqe61sVtjo+aDJhhfe6IkK+vrTFEXlUUEoA==",
|
||||
"dgSpecHash": "kweG9cyheq0lvUg6tPkk+sPoY2pPlReL0QP5jHLJNWl9pUpDd+CJp7bLfFE9WjjPi9DegeiFh5tJQ1eO1r96RA==",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.visualstudio.azure.containers.tools.targets\\1.15.1\\microsoft.visualstudio.azure.containers.tools.targets.1.15.1.nupkg.sha512"
|
||||
"C:\\Users\\marce\\.nuget\\packages\\aapanelsharp\\1.0.0\\aapanelsharp.1.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\bcrypt.net-next\\4.0.3\\bcrypt.net-next.4.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\ben.demystifier\\0.4.1\\ben.demystifier.0.4.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\blazor.contextmenu\\1.15.0\\blazor.contextmenu.1.15.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\blazormonaco\\3.0.0\\blazormonaco.3.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\blazortable\\1.17.0\\blazortable.1.17.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\currietechnologies.razor.sweetalert2\\5.4.0\\currietechnologies.razor.sweetalert2.5.4.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net\\3.9.0\\discord.net.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.commands\\3.9.0\\discord.net.commands.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.core\\3.9.0\\discord.net.core.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.interactions\\3.9.0\\discord.net.interactions.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.rest\\3.9.0\\discord.net.rest.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.webhook\\3.9.0\\discord.net.webhook.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.websocket\\3.9.0\\discord.net.websocket.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\gravatarsharp.core\\0.9.0.2\\gravatarsharp.core.0.9.0.2.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\humanizer.core\\2.14.1\\humanizer.core.2.14.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\jwt\\10.0.2\\jwt.10.0.2.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\linqkit.core\\1.1.26\\linqkit.core.1.1.26.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\logging.net\\1.1.0\\logging.net.1.1.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\macross.json.extensions\\3.0.0\\macross.json.extensions.3.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.authorization\\6.0.9\\microsoft.aspnetcore.authorization.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components\\6.0.9\\microsoft.aspnetcore.components.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components.analyzers\\6.0.9\\microsoft.aspnetcore.components.analyzers.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components.forms\\6.0.9\\microsoft.aspnetcore.components.forms.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components.web\\6.0.9\\microsoft.aspnetcore.components.web.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.metadata\\6.0.9\\microsoft.aspnetcore.metadata.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore\\7.0.3\\microsoft.entityframeworkcore.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\7.0.3\\microsoft.entityframeworkcore.abstractions.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\7.0.3\\microsoft.entityframeworkcore.analyzers.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.design\\7.0.3\\microsoft.entityframeworkcore.design.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\7.0.3\\microsoft.entityframeworkcore.relational.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\7.0.0\\microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.caching.memory\\7.0.0\\microsoft.extensions.caching.memory.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\7.0.0\\microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\7.0.0\\microsoft.extensions.dependencyinjection.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\7.0.0\\microsoft.extensions.dependencyinjection.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.dependencymodel\\7.0.0\\microsoft.extensions.dependencymodel.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.localization\\3.1.18\\microsoft.extensions.localization.3.1.18.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.localization.abstractions\\3.1.18\\microsoft.extensions.localization.abstractions.3.1.18.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.logging\\7.0.0\\microsoft.extensions.logging.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\7.0.0\\microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.options\\7.0.0\\microsoft.extensions.options.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.primitives\\7.0.0\\microsoft.extensions.primitives.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.jsinterop\\6.0.9\\microsoft.jsinterop.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.visualstudio.azure.containers.tools.targets\\1.15.1\\microsoft.visualstudio.azure.containers.tools.targets.1.15.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\minestat\\3.1.1\\minestat.3.1.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\mono.texttemplating\\2.2.1\\mono.texttemplating.2.2.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\mysqlconnector\\2.2.5\\mysqlconnector.2.2.5.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\newtonsoft.json\\13.0.3-beta1\\newtonsoft.json.13.0.3-beta1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\otp.net\\1.3.0\\otp.net.1.3.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\pomelo.entityframeworkcore.mysql\\7.0.0\\pomelo.entityframeworkcore.mysql.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\pteroconsole.net\\1.0.4\\pteroconsole.net.1.0.4.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\qrcoder\\1.4.3\\qrcoder.1.4.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\restsharp\\109.0.0-preview.1\\restsharp.109.0.0-preview.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.codedom\\4.4.0\\system.codedom.4.4.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.collections.immutable\\5.0.0\\system.collections.immutable.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.interactive.async\\5.0.0\\system.interactive.async.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.io.pipelines\\6.0.3\\system.io.pipelines.6.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.linq.async\\5.0.0\\system.linq.async.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.reactive\\5.0.0\\system.reactive.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.reflection.metadata\\5.0.0\\system.reflection.metadata.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\6.0.0\\system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.text.encodings.web\\7.0.0\\system.text.encodings.web.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.text.json\\7.0.0\\system.text.json.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.valuetuple\\4.5.0\\system.valuetuple.4.5.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\uaparser\\3.1.47\\uaparser.3.1.47.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\xtermblazor\\1.6.1\\xtermblazor.1.6.1.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
"logs": [
|
||||
{
|
||||
"code": "NU1701",
|
||||
"level": "Warning",
|
||||
"warningLevel": 1,
|
||||
"message": "Package 'GravatarSharp.Core 0.9.0.2' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework 'net6.0'. This package may not be fully compatible with your project.",
|
||||
"libraryId": "GravatarSharp.Core",
|
||||
"targetGraphs": [
|
||||
"net6.0"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
"restore":{"projectUniqueName":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","projectName":"Moonlight","projectPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","outputPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages","C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"],"originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"C:\\Users\\marce\\source\\repos\\Logging.Net\\LoggingNet\\LoggingNet\\bin\\Release\\net5.0\\newpublish":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"Microsoft.VisualStudio.Azure.Containers.Tools.Targets":{"target":"Package","version":"[1.15.1, )"}},"imports":["net461","net462","net47","net471","net472","net48"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.AspNetCore.App":{"privateAssets":"none"},"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\6.0.300\\RuntimeIdentifierGraph.json"}}
|
||||
"restore":{"projectUniqueName":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","projectName":"Moonlight","projectPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","outputPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages","C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"],"originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"C:\\Users\\marce\\source\\repos\\Logging.Net\\LoggingNet\\LoggingNet\\bin\\Release\\net5.0\\newpublish":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"BCrypt.Net-Next":{"target":"Package","version":"[4.0.3, )"},"Ben.Demystifier":{"target":"Package","version":"[0.4.1, )"},"Blazor.ContextMenu":{"target":"Package","version":"[1.15.0, )"},"BlazorMonaco":{"target":"Package","version":"[3.0.0, )"},"BlazorTable":{"target":"Package","version":"[1.17.0, )"},"CurrieTechnologies.Razor.SweetAlert2":{"target":"Package","version":"[5.4.0, )"},"Discord.Net":{"target":"Package","version":"[3.9.0, )"},"GravatarSharp.Core":{"target":"Package","version":"[0.9.0.2, )"},"JWT":{"target":"Package","version":"[10.0.2, )"},"Logging.Net":{"target":"Package","version":"[1.1.0, )"},"Microsoft.EntityFrameworkCore.Design":{"include":"Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive","suppressParent":"All","target":"Package","version":"[7.0.3, )"},"Microsoft.VisualStudio.Azure.Containers.Tools.Targets":{"target":"Package","version":"[1.15.1, )"},"MineStat":{"target":"Package","version":"[3.1.1, )"},"Newtonsoft.Json":{"target":"Package","version":"[13.0.3-beta1, )"},"Otp.NET":{"target":"Package","version":"[1.3.0, )"},"Pomelo.EntityFrameworkCore.MySql":{"target":"Package","version":"[7.0.0, )"},"PteroConsole.NET":{"target":"Package","version":"[1.0.4, )"},"QRCoder":{"target":"Package","version":"[1.4.3, )"},"RestSharp":{"target":"Package","version":"[109.0.0-preview.1, )"},"UAParser":{"target":"Package","version":"[3.1.47, )"},"XtermBlazor":{"target":"Package","version":"[1.6.1, )"},"aaPanelSharp":{"target":"Package","version":"[1.0.0, )"}},"imports":["net461","net462","net47","net471","net472","net48"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.AspNetCore.App":{"privateAssets":"none"},"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\6.0.300\\RuntimeIdentifierGraph.json"}}
|
||||
67
Moonlight/resources/lang/en_us.json
Normal file
67
Moonlight/resources/lang/en_us.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"Crashes": {
|
||||
"Component": {
|
||||
"Title": "Ooops. Something went wrong",
|
||||
"Details": "This component has crashed"
|
||||
},
|
||||
"Page": {
|
||||
"Title": "Ooops. Something went wrong",
|
||||
"Details": "This site has crashed"
|
||||
},
|
||||
"Global": {
|
||||
"Title": "Ooops. Something went wrong",
|
||||
"Details": "Your moonlight client has crashed"
|
||||
}
|
||||
},
|
||||
"Footer": {
|
||||
"AboutUs": "About us",
|
||||
"Imprint": "Imprint",
|
||||
"Privacy": "Privacy"
|
||||
},
|
||||
"Alerts": {
|
||||
"Banned": {
|
||||
"Title": "Your account is banned from moonlight",
|
||||
"Details": "Your data will be deleted shortly. For more information contact support"
|
||||
},
|
||||
"Disabled": {
|
||||
"Title": "Your account is temporary banned from moonlight",
|
||||
"Details": "Your data is is still saved but the access to it is not possible at this time. For more information contact support"
|
||||
}
|
||||
},
|
||||
"Navbar": {
|
||||
"Account": {
|
||||
"Settings": "Account settings"
|
||||
},
|
||||
"Logout": "Logout"
|
||||
},
|
||||
"Sidebar": {
|
||||
"Footer": {
|
||||
"OpenSupport": "Open support"
|
||||
},
|
||||
"Menu": {
|
||||
"Login": "Login",
|
||||
"Register": "Register",
|
||||
"Dashboard": "Dashboard",
|
||||
"Order": "Order",
|
||||
"Website": "Website",
|
||||
"Database": "Database",
|
||||
"Domain": "Domain",
|
||||
"Servers": "Servers",
|
||||
"Websites": "Websites",
|
||||
"Databases": "Databases",
|
||||
"Domains": "Domains",
|
||||
"Changelog": "Changelog",
|
||||
"Admin": "Admin",
|
||||
"System": "System",
|
||||
"Overview": "Overview",
|
||||
"Manager": "Manager",
|
||||
"Cleanup": "Cleanup",
|
||||
"Nodes": "Nodes",
|
||||
"Images": "Images",
|
||||
"AaPanel": "AaPanel",
|
||||
"Users": "Users",
|
||||
"Support": "Support",
|
||||
"Statistics": "Statistics"
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Moonlight/resources/public/images/logo.svg
Normal file
14
Moonlight/resources/public/images/logo.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256px" height="301px" viewBox="0 0 256 301" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||
<defs>
|
||||
<linearGradient x1="2.17771739%" y1="34.7938955%" x2="92.7221942%" y2="91.3419405%" id="linearGradient-1">
|
||||
<stop stop-color="#41A7EF" offset="0%"></stop>
|
||||
<stop stop-color="#813DDE" offset="54.2186236%"></stop>
|
||||
<stop stop-color="#8F2EE2" offset="74.4988788%"></stop>
|
||||
<stop stop-color="#A11CE6" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<path d="M124.183681,101.699 C124.183681,66.515 136.256681,34.152 156.486681,8.525 C159.197681,5.092 156.787681,0.069 152.412681,0.012 C151.775681,0.004 151.136681,0 150.497681,0 C67.6206813,0 0.390681343,66.99 0.00168134279,149.775 C-0.386318657,232.369 66.4286813,300.195 149.019681,300.988 C189.884681,301.381 227.036681,285.484 254.376681,259.395 C257.519681,256.396 255.841681,251.082 251.548681,250.42 C179.413681,239.291 124.183681,176.949 124.183681,101.699" fill="url(#linearGradient-1)"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Moonlight/resources/public/images/logolong.png
Normal file
BIN
Moonlight/resources/public/images/logolong.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
58
Moonlight/wwwroot/assets/css/blazor.css
Normal file
58
Moonlight/wwwroot/assets/css/blazor.css
Normal file
@@ -0,0 +1,58 @@
|
||||
.my-reconnect-modal {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.my-reconnect-modal > div {
|
||||
position: fixed;
|
||||
inset: 0px;
|
||||
z-index: 1050;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
transition: visibility 0s linear 500ms;
|
||||
backdrop-filter: blur(20px);
|
||||
background-color: #0008;
|
||||
}
|
||||
|
||||
.components-reconnect-hide > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-show > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-show > .show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-failed > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-failed > .failed {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-rejected > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-rejected > .rejected {
|
||||
display: block;
|
||||
}
|
||||
.components-reconnect-hide > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-failed {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-rejected {
|
||||
display: block;
|
||||
}
|
||||
1
Moonlight/wwwroot/assets/css/boxicons.min.css
vendored
Normal file
1
Moonlight/wwwroot/assets/css/boxicons.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
38
Moonlight/wwwroot/assets/css/flashbang.css
Normal file
38
Moonlight/wwwroot/assets/css/flashbang.css
Normal file
@@ -0,0 +1,38 @@
|
||||
@keyframes flashbang {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
1% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
2% {
|
||||
opacity: 1;
|
||||
}
|
||||
45% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
55% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
90% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.flashbanglight {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
opacity: 1;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
border-radius: 100%;
|
||||
background: transparent;
|
||||
z-index: 999;
|
||||
color: gold;
|
||||
}
|
||||
9
Moonlight/wwwroot/assets/css/invisiblea.css
Normal file
9
Moonlight/wwwroot/assets/css/invisiblea.css
Normal file
@@ -0,0 +1,9 @@
|
||||
.invisible-a {
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.invisible-a:hover {
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
9
Moonlight/wwwroot/assets/css/snow.css
Normal file
9
Moonlight/wwwroot/assets/css/snow.css
Normal file
@@ -0,0 +1,9 @@
|
||||
.snow-canvas {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
}
|
||||
47684
Moonlight/wwwroot/assets/css/style.bundle.css
Normal file
47684
Moonlight/wwwroot/assets/css/style.bundle.css
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Moonlight/wwwroot/assets/fonts/boxicons.eot
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.eot
Normal file
Binary file not shown.
1653
Moonlight/wwwroot/assets/fonts/boxicons.svg
Normal file
1653
Moonlight/wwwroot/assets/fonts/boxicons.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 1.2 MiB |
BIN
Moonlight/wwwroot/assets/fonts/boxicons.ttf
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.ttf
Normal file
Binary file not shown.
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff
Normal file
Binary file not shown.
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff2
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff2
Normal file
Binary file not shown.
68
Moonlight/wwwroot/assets/js/alertUtils.js
Normal file
68
Moonlight/wwwroot/assets/js/alertUtils.js
Normal file
@@ -0,0 +1,68 @@
|
||||
window.showAlertInfo = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'info'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertSuccess = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'success'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertWarning = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'warning'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertError = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'error'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertYesNo = function (title, yesText, noText)
|
||||
{
|
||||
return Swal.fire({
|
||||
title: title,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: yesText,
|
||||
denyButtonText: noText,
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
return true;
|
||||
} else if (result.isDenied) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
window.showAlertText = function (title, description) {
|
||||
const {value: text} = Swal.fire({
|
||||
title: title,
|
||||
input: 'text',
|
||||
inputLabel: description,
|
||||
inputValue: "",
|
||||
showCancelButton: false,
|
||||
inputValidator: (value) => {
|
||||
if (!value) {
|
||||
return 'Es muss ein Wert angegeben werden'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return text;
|
||||
}
|
||||
32
Moonlight/wwwroot/assets/js/clipboard.js
Normal file
32
Moonlight/wwwroot/assets/js/clipboard.js
Normal file
@@ -0,0 +1,32 @@
|
||||
function fallbackCopyTextToClipboard(text) {
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.value = text;
|
||||
|
||||
// Avoid scrolling to bottom
|
||||
textArea.style.top = "0";
|
||||
textArea.style.left = "0";
|
||||
textArea.style.position = "fixed";
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
var successful = document.execCommand('copy');
|
||||
var msg = successful ? 'successful' : 'unsuccessful';
|
||||
} catch (err) {
|
||||
console.error('Fallback: Oops, unable to copy', err);
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
function copyTextToClipboard(text) {
|
||||
if (!navigator.clipboard) {
|
||||
fallbackCopyTextToClipboard(text);
|
||||
return;
|
||||
}
|
||||
navigator.clipboard.writeText(text).then(function() {
|
||||
}, function(err) {
|
||||
console.error('Async: Could not copy text: ', err);
|
||||
});
|
||||
}
|
||||
143
Moonlight/wwwroot/assets/js/consoleUtils.js
Normal file
143
Moonlight/wwwroot/assets/js/consoleUtils.js
Normal file
@@ -0,0 +1,143 @@
|
||||
window.initConsolePlugins = function () {
|
||||
window.XtermBlazor.registerAddon("xterm-addon-fit", new window.FitAddon.FitAddon());
|
||||
|
||||
addEventListener('resize', (event) => {
|
||||
//XtermBlazor.invokeAddonFunction()
|
||||
});
|
||||
};
|
||||
|
||||
window.initGraphs = function () {
|
||||
|
||||
};
|
||||
|
||||
window.initCpu = function () {
|
||||
var element = document.getElementById('cpuchart');
|
||||
|
||||
var height = parseInt(KTUtil.css(element, 'height'));
|
||||
var labelColor = KTUtil.getCssVariableValue('--kt-gray-500');
|
||||
var borderColor = KTUtil.getCssVariableValue('--kt-gray-200');
|
||||
var baseColor = KTUtil.getCssVariableValue('--kt-info');
|
||||
var lightColor = KTUtil.getCssVariableValue('--kt-info-light');
|
||||
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'CPU Auslastung',
|
||||
data: [0, 0, 0, 0, 0, 0, 0]
|
||||
}],
|
||||
chart: {
|
||||
fontFamily: 'inherit',
|
||||
type: 'area',
|
||||
height: height,
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
fill: {
|
||||
type: 'solid',
|
||||
opacity: 1
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
show: true,
|
||||
width: 3,
|
||||
colors: [baseColor]
|
||||
},
|
||||
xaxis: {
|
||||
categories: [],
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '12px'
|
||||
}
|
||||
},
|
||||
crosshairs: {
|
||||
position: 'front',
|
||||
stroke: {
|
||||
color: baseColor,
|
||||
width: 1,
|
||||
dashArray: 3
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false,
|
||||
formatter: undefined,
|
||||
offsetY: 0,
|
||||
style: {
|
||||
fontSize: '12px'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '12px'
|
||||
}
|
||||
}
|
||||
},
|
||||
states: {
|
||||
normal: {
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
active: {
|
||||
allowMultipleDataPointsSelection: false,
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
colors: [lightColor],
|
||||
grid: {
|
||||
borderColor: borderColor,
|
||||
strokeDashArray: 4,
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: true
|
||||
}
|
||||
}
|
||||
},
|
||||
markers: {
|
||||
strokeColor: baseColor,
|
||||
strokeWidth: 3
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(element, options);
|
||||
chart.render();
|
||||
|
||||
window.console.cpuchart = chart;
|
||||
};
|
||||
|
||||
window.updateCpu = function (value) {
|
||||
window.console.cpuchart.appendSeries({
|
||||
name: 'CPU Auslastung',
|
||||
data: value
|
||||
});
|
||||
};
|
||||
26
Moonlight/wwwroot/assets/js/cookieUtils.js
Normal file
26
Moonlight/wwwroot/assets/js/cookieUtils.js
Normal file
@@ -0,0 +1,26 @@
|
||||
window.setCookie = function (key, value, days) {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
let expires = "expires=" + d.toUTCString();
|
||||
document.cookie = key + "=" + value + ";" + expires + ";path=/";
|
||||
}
|
||||
|
||||
window.deleteCookie = function (key) {
|
||||
window.setCookie(key, "", 0);
|
||||
}
|
||||
|
||||
window.getCookie = function (cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
12
Moonlight/wwwroot/assets/js/flashbang.js
Normal file
12
Moonlight/wwwroot/assets/js/flashbang.js
Normal file
@@ -0,0 +1,12 @@
|
||||
function flashbang() {
|
||||
const light = document.getElementById("flashbang");
|
||||
light.style.boxShadow = "0 0 10000px 10000px white, 0 0 250px 10px #FFFFFF";
|
||||
light.style.animation = "flashbang 5s linear forwards";
|
||||
light.onanimationend = clearFlashbang;
|
||||
}
|
||||
|
||||
function clearFlashbang() {
|
||||
const light = document.getElementById("flashbang");
|
||||
light.style.animation = "";
|
||||
light.style.opacity = "0";
|
||||
}
|
||||
51
Moonlight/wwwroot/assets/js/loggingUtils.js
Normal file
51
Moonlight/wwwroot/assets/js/loggingUtils.js
Normal file
@@ -0,0 +1,51 @@
|
||||
window.logInfo = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cINFO%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: aqua', // INFO
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
||||
|
||||
window.logWarn = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cWARN%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: orange', // WARN
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
||||
|
||||
window.logError = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cERROR%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: red', // ERROR
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
||||
|
||||
window.logDebug = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cDEBUG%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: green', // DEBUG
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
||||
1
Moonlight/wwwroot/assets/js/monaco.js
Normal file
1
Moonlight/wwwroot/assets/js/monaco.js
Normal file
@@ -0,0 +1 @@
|
||||
require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });
|
||||
9
Moonlight/wwwroot/assets/js/recaptcha.js
Normal file
9
Moonlight/wwwroot/assets/js/recaptcha.js
Normal file
@@ -0,0 +1,9 @@
|
||||
window.recaptcha = new Object();
|
||||
window.recaptcha.render = function (id, sitekey, page)
|
||||
{
|
||||
return grecaptcha.render(id, {
|
||||
'sitekey': sitekey,
|
||||
'callback': (response) => { page.invokeMethodAsync('CallbackOnSuccess', response); },
|
||||
'expired-callback': () => { page.invokeMethodAsync('CallbackOnExpired'); }
|
||||
});
|
||||
}
|
||||
7832
Moonlight/wwwroot/assets/js/scripts.bundle.js
Normal file
7832
Moonlight/wwwroot/assets/js/scripts.bundle.js
Normal file
File diff suppressed because it is too large
Load Diff
118
Moonlight/wwwroot/assets/js/snow.js
Normal file
118
Moonlight/wwwroot/assets/js/snow.js
Normal file
@@ -0,0 +1,118 @@
|
||||
window.createSnow = function () {
|
||||
(function () {
|
||||
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
|
||||
function (callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
window.requestAnimationFrame = requestAnimationFrame;
|
||||
})();
|
||||
|
||||
|
||||
var flakes = [],
|
||||
canvas = document.getElementById("snow"),
|
||||
ctx = canvas.getContext("2d"),
|
||||
flakeCount = 200,
|
||||
mX = -100,
|
||||
mY = -100
|
||||
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
|
||||
function snow() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
for (var i = 0; i < flakeCount; i++) {
|
||||
var flake = flakes[i],
|
||||
x = mX,
|
||||
y = mY,
|
||||
minDist = 150,
|
||||
x2 = flake.x,
|
||||
y2 = flake.y;
|
||||
|
||||
var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
|
||||
dx = x2 - x,
|
||||
dy = y2 - y;
|
||||
|
||||
if (dist < minDist) {
|
||||
var force = minDist / (dist * dist),
|
||||
xcomp = (x - x2) / dist,
|
||||
ycomp = (y - y2) / dist,
|
||||
deltaV = force / 2;
|
||||
|
||||
flake.velX -= deltaV * xcomp;
|
||||
flake.velY -= deltaV * ycomp;
|
||||
|
||||
} else {
|
||||
flake.velX *= .98;
|
||||
if (flake.velY <= flake.speed) {
|
||||
flake.velY = flake.speed
|
||||
}
|
||||
flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
|
||||
}
|
||||
|
||||
ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")";
|
||||
flake.y += flake.velY;
|
||||
flake.x += flake.velX;
|
||||
|
||||
if (flake.y >= canvas.height || flake.y <= 0) {
|
||||
reset(flake);
|
||||
}
|
||||
|
||||
|
||||
if (flake.x >= canvas.width || flake.x <= 0) {
|
||||
reset(flake);
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
requestAnimationFrame(snow);
|
||||
};
|
||||
|
||||
function reset(flake) {
|
||||
flake.x = Math.floor(Math.random() * canvas.width);
|
||||
flake.y = 0;
|
||||
flake.size = (Math.random() * 3) + 2;
|
||||
flake.speed = (Math.random() * 1) + 0.5;
|
||||
flake.velY = flake.speed;
|
||||
flake.velX = 0;
|
||||
flake.opacity = (Math.random() * 0.5) + 0.3;
|
||||
}
|
||||
|
||||
function init() {
|
||||
for (var i = 0; i < flakeCount; i++) {
|
||||
var x = Math.floor(Math.random() * canvas.width),
|
||||
y = Math.floor(Math.random() * canvas.height),
|
||||
size = (Math.random() * 3) + 2,
|
||||
speed = (Math.random() * 1) + 0.5,
|
||||
opacity = (Math.random() * 0.5) + 0.3;
|
||||
|
||||
flakes.push({
|
||||
speed: speed,
|
||||
velY: speed,
|
||||
velX: 0,
|
||||
x: x,
|
||||
y: y,
|
||||
size: size,
|
||||
stepSize: (Math.random()) / 30,
|
||||
step: 0,
|
||||
opacity: opacity
|
||||
});
|
||||
}
|
||||
|
||||
snow();
|
||||
};
|
||||
|
||||
canvas.addEventListener("mousemove", function (e) {
|
||||
mX = e.clientX,
|
||||
mY = e.clientY
|
||||
});
|
||||
|
||||
window.addEventListener("resize", function () {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
})
|
||||
|
||||
init();
|
||||
}
|
||||
14
Moonlight/wwwroot/assets/js/theme.js
Normal file
14
Moonlight/wwwroot/assets/js/theme.js
Normal file
@@ -0,0 +1,14 @@
|
||||
if (document.documentElement) {
|
||||
const defaultThemeMode = "dark";
|
||||
const name = document.body.getAttribute("data-kt-name");
|
||||
let themeMode = localStorage.getItem("kt_" + (name !== null ? name + "_" : "") + "theme_mode_value");
|
||||
|
||||
if (themeMode === null) {
|
||||
if (defaultThemeMode === "system") {
|
||||
themeMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
} else {
|
||||
themeMode = defaultThemeMode;
|
||||
}
|
||||
}
|
||||
document.documentElement.setAttribute("data-theme", themeMode);
|
||||
}
|
||||
19
Moonlight/wwwroot/assets/js/toastUtils.js
Normal file
19
Moonlight/wwwroot/assets/js/toastUtils.js
Normal file
@@ -0,0 +1,19 @@
|
||||
window.showInfoToast = function (msg)
|
||||
{
|
||||
toastr['info'](msg);
|
||||
}
|
||||
|
||||
window.showErrorToast = function (msg)
|
||||
{
|
||||
toastr['error'](msg);
|
||||
}
|
||||
|
||||
window.showSuccessToast = function (msg)
|
||||
{
|
||||
toastr['success'](msg);
|
||||
}
|
||||
|
||||
window.showWarningToast = function (msg)
|
||||
{
|
||||
toastr['warning'](msg);
|
||||
}
|
||||
42
Moonlight/wwwroot/assets/js/utils.js
Normal file
42
Moonlight/wwwroot/assets/js/utils.js
Normal file
@@ -0,0 +1,42 @@
|
||||
window.scrollToElement = function (id)
|
||||
{
|
||||
let e = document.getElementById(id);
|
||||
e.scrollTop = e.scrollHeight;
|
||||
};
|
||||
|
||||
window.showModal = function (name)
|
||||
{
|
||||
$('#' + name).modal('show');
|
||||
}
|
||||
|
||||
window.hideModal = function (name)
|
||||
{
|
||||
$('#' + name).modal('hide');
|
||||
}
|
||||
|
||||
window.attachFileUploadWebkit = function (id)
|
||||
{
|
||||
document.getElementById(id).addEventListener("change", function(e) {
|
||||
var files = [];
|
||||
|
||||
Array.from(e.target.files).forEach(file => {
|
||||
files.push(file.webkitRelativePath);
|
||||
});
|
||||
|
||||
window.webkitStorage = files;
|
||||
});
|
||||
};
|
||||
|
||||
window.getWebkitStorage = function ()
|
||||
{
|
||||
return window.webkitStorage;
|
||||
};
|
||||
|
||||
window.triggerResizeEvent = function ()
|
||||
{
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
}
|
||||
|
||||
window.showNotification = function (title, text, img) {
|
||||
let notification = new Notification(title, { body: text, icon: img });
|
||||
}
|
||||
17949
Moonlight/wwwroot/assets/js/widgets.bundle.js
Normal file
17949
Moonlight/wwwroot/assets/js/widgets.bundle.js
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user