forked from adam/discord-bot-shtik
Compare commits
5 Commits
e7b70468ae
...
d060e92ed9
Author | SHA1 | Date | |
---|---|---|---|
d060e92ed9 | |||
77fc26e1ed | |||
edc86af538 | |||
39781397c3 | |||
e89c109970 |
@ -28,7 +28,7 @@ public class DefinitionSnarkGaslight : Behavior
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.Channel.SendMessage("that's not what gaslight means. Did you mean \"say something that (you believe) is wrong\"?");
|
||||
await message.Channel.SendMessage("that's not what gaslight means. Did you mean \"deceive\"?");
|
||||
return true;
|
||||
}
|
||||
}
|
@ -54,3 +54,30 @@ public class Joke : Behavior
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public class LaughAtOwnJoke : Behavior
|
||||
{
|
||||
public override string Name => "Laugh at own jokes";
|
||||
|
||||
public override string Trigger => "1 in 8";
|
||||
|
||||
public override string Description => Name;
|
||||
private string _punchline{get;set;}
|
||||
|
||||
public LaughAtOwnJoke(string punchline)
|
||||
{
|
||||
_punchline = punchline;
|
||||
}
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
Console.WriteLine($"{message.Content} == {_punchline}");
|
||||
return message.Content == _punchline
|
||||
&& Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id);
|
||||
}
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.React("\U0001F60E"); //smiling face with sunglasses
|
||||
Behaver.Behaviors.Remove(this);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
namespace vassago.Behavior;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using vassago.Models;
|
||||
|
||||
|
||||
public class LaughAtOwnJoke : Behavior
|
||||
{
|
||||
public override string Name => "Laugh at own jokes";
|
||||
|
||||
public override string Trigger => "1 in 8";
|
||||
|
||||
public override string Description => Name;
|
||||
private string _punchline{get;set;}
|
||||
|
||||
public LaughAtOwnJoke(string punchline)
|
||||
{
|
||||
_punchline = punchline;
|
||||
}
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
Console.WriteLine($"{message.Content} == {_punchline}");
|
||||
return message.Content == _punchline
|
||||
&& Behaver.Instance.Selves.Any(acc => acc.Id == message.Author.Id);
|
||||
}
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.React("\U0001F60E"); //smiling face with sunglasses
|
||||
Behaver.Behaviors.Remove(this);
|
||||
return true;
|
||||
}
|
||||
}
|
115
Behavior/LinkMe.cs
Normal file
115
Behavior/LinkMe.cs
Normal file
@ -0,0 +1,115 @@
|
||||
namespace vassago.Behavior;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using vassago.Models;
|
||||
using QRCoder;
|
||||
|
||||
[StaticPlz]
|
||||
public class LinkMeInitiate : Behavior
|
||||
{
|
||||
public override string Name => "LinkMe";
|
||||
|
||||
public override string Trigger => "!linktome";
|
||||
|
||||
public override string Description => "from your primary, tell the bot to add your secondary";
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
var pw = Guid.NewGuid().ToString();
|
||||
var lc = new LinkClose(pw, message.Author);
|
||||
Behaver.Behaviors.Add(lc);
|
||||
|
||||
await message.Channel.SendMessage($"on your secondary, send me this: !iam {pw}");
|
||||
|
||||
Thread.Sleep(TimeSpan.FromMinutes(5));
|
||||
Behaver.Behaviors.Remove(lc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class LinkClose : Behavior
|
||||
{
|
||||
public override string Name => "LinkMeFinish";
|
||||
|
||||
public override string Trigger => "!iam";
|
||||
|
||||
public override string Description => "the second half of LinkMe - this is confirmation that you are the other one";
|
||||
|
||||
private ChattingContext _db;
|
||||
private string _pw;
|
||||
private Account _primary;
|
||||
|
||||
public LinkClose(string pw, Account primary)
|
||||
{
|
||||
_db = new ChattingContext();
|
||||
_pw = pw;
|
||||
_primary = primary;
|
||||
}
|
||||
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
return message.Content == $"!iam {_pw}";
|
||||
}
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
var secondary = message.Author.IsUser;
|
||||
if(_primary.IsUser.Id == secondary.Id)
|
||||
{
|
||||
await message.Channel.SendMessage("i know :)");
|
||||
return true;
|
||||
}
|
||||
if(message.Author.IsBot != _primary.IsBot)
|
||||
{
|
||||
await message.Channel.SendMessage("the fleshbags deceive you, brother. No worries, their feeble minds play weak games :)");
|
||||
return true;
|
||||
}
|
||||
|
||||
Console.WriteLine($"{secondary.Id} is being consumed into {_primary.IsUser.Id}");
|
||||
_primary.IsUser.Accounts.AddRange(secondary.Accounts);
|
||||
foreach(var a in secondary.Accounts)
|
||||
{
|
||||
a.IsUser = _primary.IsUser;
|
||||
}
|
||||
secondary.Accounts.Clear();
|
||||
Console.WriteLine("accounts transferred");
|
||||
try
|
||||
{
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
message.Channel.SendMessage("error in first save");
|
||||
Console.WriteLine("fucks sake if I don't catch Exception it *mysteriously vanishes*");
|
||||
Console.Error.WriteLine(e);
|
||||
return false;
|
||||
}
|
||||
Console.WriteLine("saved");
|
||||
|
||||
|
||||
_db.Users.Remove(secondary);
|
||||
Console.WriteLine("old account cleaned up");
|
||||
try
|
||||
{
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
message.Channel.SendMessage("error in second save");
|
||||
Console.WriteLine("fucks sake if I don't catch Exception it *mysteriously vanishes*");
|
||||
Console.Error.WriteLine(e);
|
||||
return false;
|
||||
}
|
||||
Console.WriteLine("saved, again, separately");
|
||||
|
||||
await message.Channel.SendMessage("done :)");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -15,10 +15,6 @@ public class TwitchSummon : Behavior
|
||||
//I think given the bot's (hopeful) ability to play nice with others - anyone can summon it anywhere
|
||||
//HOWEVER, if not-the-broadcaster summons it, 1) all channel permissions to strict and 2) auto-disconnect on stream end
|
||||
//i don't know if the twitch *chat* interface has knowledge of if the stream ends. maybe auto-disconnect after like 2 hours?
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
|
@ -22,6 +22,12 @@ public class UsersController : Controller
|
||||
View(await _db.Users.Include(u => u.Accounts).ToListAsync()) :
|
||||
Problem("Entity set '_db.Users' is null.");
|
||||
}
|
||||
public async Task<IActionResult> Details(Guid id)
|
||||
{
|
||||
return _db.Users != null ?
|
||||
View(await _db.Users.Include(u => u.Accounts).FirstAsync(u => u.Id == id)) :
|
||||
Problem("Entity set '_db.Users' is null.");
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
public IActionResult Error()
|
||||
|
349
Migrations/20231130204741_Feature Permissions.Designer.cs
generated
Normal file
349
Migrations/20231130204741_Feature Permissions.Designer.cs
generated
Normal file
@ -0,0 +1,349 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using vassago.Models;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace vassago.Migrations
|
||||
{
|
||||
[DbContext(typeof(ChattingContext))]
|
||||
[Migration("20231130204741_Feature Permissions")]
|
||||
partial class FeaturePermissions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.5")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Account", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("DisplayName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("FeaturePermissionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsBot")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("IsUserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Protocol")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("SeenInChannelId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FeaturePermissionId");
|
||||
|
||||
b.HasIndex("IsUserId");
|
||||
|
||||
b.HasIndex("SeenInChannelId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Attachment", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<byte[]>("Content")
|
||||
.HasColumnType("bytea");
|
||||
|
||||
b.Property<string>("ContentType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal?>("ExternalId")
|
||||
.HasColumnType("numeric(20,0)");
|
||||
|
||||
b.Property<string>("Filename")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("MessageId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Size")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Source")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MessageId");
|
||||
|
||||
b.ToTable("Attachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("DisplayName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("FeaturePermissionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsDM")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("ParentChannelId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int?>("PermissionsId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Protocol")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FeaturePermissionId");
|
||||
|
||||
b.HasIndex("ParentChannelId");
|
||||
|
||||
b.HasIndex("PermissionsId");
|
||||
|
||||
b.ToTable("Channels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.ChannelPermissions", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("LewdnessFilterLevel")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool?>("LinksAllowed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal?>("MaxAttachmentBytes")
|
||||
.HasColumnType("numeric(20,0)");
|
||||
|
||||
b.Property<long?>("MaxTextChars")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int?>("MeannessFilterLevel")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool?>("ReactionsPossible")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ChannelPermissions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("Inheritable")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("InternalName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("InternalTag")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("FeaturePermissions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("ActedOn")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("AuthorId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("ChannelId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("MentionsMe")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Protocol")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTimeOffset>("Timestamp")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AuthorId");
|
||||
|
||||
b.HasIndex("ChannelId");
|
||||
|
||||
b.ToTable("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("FeaturePermissionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FeaturePermissionId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Account", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.FeaturePermission", null)
|
||||
.WithMany("RestrictedToAccounts")
|
||||
.HasForeignKey("FeaturePermissionId");
|
||||
|
||||
b.HasOne("vassago.Models.User", "IsUser")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("IsUserId");
|
||||
|
||||
b.HasOne("vassago.Models.Channel", "SeenInChannel")
|
||||
.WithMany("Users")
|
||||
.HasForeignKey("SeenInChannelId");
|
||||
|
||||
b.Navigation("IsUser");
|
||||
|
||||
b.Navigation("SeenInChannel");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Attachment", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.Message", "Message")
|
||||
.WithMany("Attachments")
|
||||
.HasForeignKey("MessageId");
|
||||
|
||||
b.Navigation("Message");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.FeaturePermission", null)
|
||||
.WithMany("RestrictedToChannels")
|
||||
.HasForeignKey("FeaturePermissionId");
|
||||
|
||||
b.HasOne("vassago.Models.Channel", "ParentChannel")
|
||||
.WithMany("SubChannels")
|
||||
.HasForeignKey("ParentChannelId");
|
||||
|
||||
b.HasOne("vassago.Models.ChannelPermissions", "Permissions")
|
||||
.WithMany()
|
||||
.HasForeignKey("PermissionsId");
|
||||
|
||||
b.Navigation("ParentChannel");
|
||||
|
||||
b.Navigation("Permissions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.Account", "Author")
|
||||
.WithMany()
|
||||
.HasForeignKey("AuthorId");
|
||||
|
||||
b.HasOne("vassago.Models.Channel", "Channel")
|
||||
.WithMany("Messages")
|
||||
.HasForeignKey("ChannelId");
|
||||
|
||||
b.Navigation("Author");
|
||||
|
||||
b.Navigation("Channel");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.User", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.FeaturePermission", null)
|
||||
.WithMany("RestrictedToUsers")
|
||||
.HasForeignKey("FeaturePermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||
{
|
||||
b.Navigation("Messages");
|
||||
|
||||
b.Navigation("SubChannels");
|
||||
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
|
||||
{
|
||||
b.Navigation("RestrictedToAccounts");
|
||||
|
||||
b.Navigation("RestrictedToChannels");
|
||||
|
||||
b.Navigation("RestrictedToUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||
{
|
||||
b.Navigation("Attachments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.User", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
211
Migrations/20231130204741_Feature Permissions.cs
Normal file
211
Migrations/20231130204741_Feature Permissions.cs
Normal file
@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace vassago.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class FeaturePermissions : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Channels_PermissionSettings_PermissionsId",
|
||||
table: "Channels");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PermissionSettings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PermissionTags",
|
||||
table: "Users");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "PermissionTags",
|
||||
table: "Accounts");
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FeaturePermissionId",
|
||||
table: "Users",
|
||||
type: "uuid",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FeaturePermissionId",
|
||||
table: "Channels",
|
||||
type: "uuid",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<Guid>(
|
||||
name: "FeaturePermissionId",
|
||||
table: "Accounts",
|
||||
type: "uuid",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ChannelPermissions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
MaxAttachmentBytes = table.Column<decimal>(type: "numeric(20,0)", nullable: true),
|
||||
MaxTextChars = table.Column<long>(type: "bigint", nullable: true),
|
||||
LinksAllowed = table.Column<bool>(type: "boolean", nullable: true),
|
||||
ReactionsPossible = table.Column<bool>(type: "boolean", nullable: true),
|
||||
LewdnessFilterLevel = table.Column<int>(type: "integer", nullable: true),
|
||||
MeannessFilterLevel = table.Column<int>(type: "integer", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ChannelPermissions", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "FeaturePermissions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
InternalName = table.Column<string>(type: "text", nullable: true),
|
||||
InternalTag = table.Column<int>(type: "integer", nullable: true),
|
||||
Inheritable = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_FeaturePermissions", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Users_FeaturePermissionId",
|
||||
table: "Users",
|
||||
column: "FeaturePermissionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Channels_FeaturePermissionId",
|
||||
table: "Channels",
|
||||
column: "FeaturePermissionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Accounts_FeaturePermissionId",
|
||||
table: "Accounts",
|
||||
column: "FeaturePermissionId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Accounts_FeaturePermissions_FeaturePermissionId",
|
||||
table: "Accounts",
|
||||
column: "FeaturePermissionId",
|
||||
principalTable: "FeaturePermissions",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Channels_ChannelPermissions_PermissionsId",
|
||||
table: "Channels",
|
||||
column: "PermissionsId",
|
||||
principalTable: "ChannelPermissions",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Channels_FeaturePermissions_FeaturePermissionId",
|
||||
table: "Channels",
|
||||
column: "FeaturePermissionId",
|
||||
principalTable: "FeaturePermissions",
|
||||
principalColumn: "Id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Users_FeaturePermissions_FeaturePermissionId",
|
||||
table: "Users",
|
||||
column: "FeaturePermissionId",
|
||||
principalTable: "FeaturePermissions",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Accounts_FeaturePermissions_FeaturePermissionId",
|
||||
table: "Accounts");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Channels_ChannelPermissions_PermissionsId",
|
||||
table: "Channels");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Channels_FeaturePermissions_FeaturePermissionId",
|
||||
table: "Channels");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Users_FeaturePermissions_FeaturePermissionId",
|
||||
table: "Users");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ChannelPermissions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "FeaturePermissions");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Users_FeaturePermissionId",
|
||||
table: "Users");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Channels_FeaturePermissionId",
|
||||
table: "Channels");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Accounts_FeaturePermissionId",
|
||||
table: "Accounts");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FeaturePermissionId",
|
||||
table: "Users");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FeaturePermissionId",
|
||||
table: "Channels");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "FeaturePermissionId",
|
||||
table: "Accounts");
|
||||
|
||||
migrationBuilder.AddColumn<int[]>(
|
||||
name: "PermissionTags",
|
||||
table: "Users",
|
||||
type: "integer[]",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int[]>(
|
||||
name: "PermissionTags",
|
||||
table: "Accounts",
|
||||
type: "integer[]",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PermissionSettings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
LewdnessFilterLevel = table.Column<int>(type: "integer", nullable: true),
|
||||
LinksAllowed = table.Column<bool>(type: "boolean", nullable: true),
|
||||
MaxAttachmentBytes = table.Column<decimal>(type: "numeric(20,0)", nullable: true),
|
||||
MaxTextChars = table.Column<long>(type: "bigint", nullable: true),
|
||||
MeannessFilterLevel = table.Column<int>(type: "integer", nullable: true),
|
||||
ReactionsPossible = table.Column<bool>(type: "boolean", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PermissionSettings", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_Channels_PermissionSettings_PermissionsId",
|
||||
table: "Channels",
|
||||
column: "PermissionsId",
|
||||
principalTable: "PermissionSettings",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
}
|
||||
}
|
@ -34,15 +34,15 @@ namespace vassago.Migrations
|
||||
b.Property<string>("ExternalId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("FeaturePermissionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsBot")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("IsUserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int[]>("PermissionTags")
|
||||
.HasColumnType("integer[]");
|
||||
|
||||
b.Property<string>("Protocol")
|
||||
.HasColumnType("text");
|
||||
|
||||
@ -54,6 +54,8 @@ namespace vassago.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FeaturePermissionId");
|
||||
|
||||
b.HasIndex("IsUserId");
|
||||
|
||||
b.HasIndex("SeenInChannelId");
|
||||
@ -110,6 +112,9 @@ namespace vassago.Migrations
|
||||
b.Property<string>("ExternalId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("FeaturePermissionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsDM")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
@ -124,6 +129,8 @@ namespace vassago.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FeaturePermissionId");
|
||||
|
||||
b.HasIndex("ParentChannelId");
|
||||
|
||||
b.HasIndex("PermissionsId");
|
||||
@ -131,6 +138,57 @@ namespace vassago.Migrations
|
||||
b.ToTable("Channels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.ChannelPermissions", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("LewdnessFilterLevel")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool?>("LinksAllowed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal?>("MaxAttachmentBytes")
|
||||
.HasColumnType("numeric(20,0)");
|
||||
|
||||
b.Property<long?>("MaxTextChars")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int?>("MeannessFilterLevel")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool?>("ReactionsPossible")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ChannelPermissions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("Inheritable")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("InternalName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("InternalTag")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("FeaturePermissions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@ -170,53 +228,28 @@ namespace vassago.Migrations
|
||||
b.ToTable("Messages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.PermissionSettings", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("LewdnessFilterLevel")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool?>("LinksAllowed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<decimal?>("MaxAttachmentBytes")
|
||||
.HasColumnType("numeric(20,0)");
|
||||
|
||||
b.Property<long?>("MaxTextChars")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int?>("MeannessFilterLevel")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool?>("ReactionsPossible")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PermissionSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int[]>("PermissionTags")
|
||||
.HasColumnType("integer[]");
|
||||
b.Property<Guid?>("FeaturePermissionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("FeaturePermissionId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Account", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.FeaturePermission", null)
|
||||
.WithMany("RestrictedToAccounts")
|
||||
.HasForeignKey("FeaturePermissionId");
|
||||
|
||||
b.HasOne("vassago.Models.User", "IsUser")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("IsUserId");
|
||||
@ -241,11 +274,15 @@ namespace vassago.Migrations
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.FeaturePermission", null)
|
||||
.WithMany("RestrictedToChannels")
|
||||
.HasForeignKey("FeaturePermissionId");
|
||||
|
||||
b.HasOne("vassago.Models.Channel", "ParentChannel")
|
||||
.WithMany("SubChannels")
|
||||
.HasForeignKey("ParentChannelId");
|
||||
|
||||
b.HasOne("vassago.Models.PermissionSettings", "Permissions")
|
||||
b.HasOne("vassago.Models.ChannelPermissions", "Permissions")
|
||||
.WithMany()
|
||||
.HasForeignKey("PermissionsId");
|
||||
|
||||
@ -269,6 +306,13 @@ namespace vassago.Migrations
|
||||
b.Navigation("Channel");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.User", b =>
|
||||
{
|
||||
b.HasOne("vassago.Models.FeaturePermission", null)
|
||||
.WithMany("RestrictedToUsers")
|
||||
.HasForeignKey("FeaturePermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Channel", b =>
|
||||
{
|
||||
b.Navigation("Messages");
|
||||
@ -278,6 +322,15 @@ namespace vassago.Migrations
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.FeaturePermission", b =>
|
||||
{
|
||||
b.Navigation("RestrictedToAccounts");
|
||||
|
||||
b.Navigation("RestrictedToChannels");
|
||||
|
||||
b.Navigation("RestrictedToUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("vassago.Models.Message", b =>
|
||||
{
|
||||
b.Navigation("Attachments");
|
||||
|
@ -13,7 +13,6 @@ public class ChannelPermissions
|
||||
public bool? ReactionsPossible { get; set; }
|
||||
public Enumerations.LewdnessFilterLevel? LewdnessFilterLevel { get; set; }
|
||||
public Enumerations.MeannessFilterLevel? MeannessFilterLevel { get; set; }
|
||||
public Enumerations.VerbosityFilterLevel? VerbosityFilterLevel { get; set; }
|
||||
|
||||
internal DefinitePermissionSettings Definite()
|
||||
{
|
||||
@ -24,7 +23,6 @@ public class ChannelPermissions
|
||||
LinksAllowed = this.LinksAllowed ?? false,
|
||||
LewdnessFilterLevel = this.LewdnessFilterLevel ?? Enumerations.LewdnessFilterLevel.G,
|
||||
MeannessFilterLevel = this.MeannessFilterLevel ?? Enumerations.MeannessFilterLevel.Strict,
|
||||
VerbosityFilterLevel = this.VerbosityFilterLevel ?? Enumerations.VerbosityFilterLevel.Pithy,
|
||||
ReactionsPossible = this.ReactionsPossible ?? false
|
||||
};
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ public class ChattingContext : DbContext
|
||||
public DbSet<Channel> Channels { get; set; }
|
||||
//public DbSet<Emoji> Emoji {get;set;}
|
||||
public DbSet<Message> Messages { get; set; }
|
||||
public DbSet<ChannelPermissions> PermissionSettings{get;set;}
|
||||
public DbSet<ChannelPermissions> ChannelPermissions{get;set;}
|
||||
public DbSet<FeaturePermission> FeaturePermissions{get;set;}
|
||||
public DbSet<Account> Accounts { get; set; }
|
||||
public DbSet<User> Users { get; set; }
|
||||
|
||||
|
@ -26,15 +26,6 @@ public static class Enumerations
|
||||
[Description("387.44m mi of printed circuits")]
|
||||
Unrestricted
|
||||
}
|
||||
public enum VerbosityFilterLevel
|
||||
{
|
||||
[Description("stfu")]
|
||||
Quiet,
|
||||
[Description("pithy")]
|
||||
Pithy,
|
||||
[Description("you want text i'll GIVE you text")]
|
||||
Unrestricted
|
||||
}
|
||||
|
||||
public static string GetDescription<T>(this T enumerationValue)
|
||||
where T : struct
|
||||
|
@ -300,28 +300,23 @@ public class DiscordInterface
|
||||
}
|
||||
internal Account UpsertAccount(IUser user, Guid inChannel)
|
||||
{
|
||||
var hadToAdd = false;
|
||||
var acc = _db.Accounts.FirstOrDefault(ui => ui.ExternalId == user.Id.ToString() && ui.SeenInChannel.Id == inChannel);
|
||||
if (acc == null)
|
||||
{
|
||||
acc = new Account();
|
||||
_db.Accounts.Add(acc);
|
||||
hadToAdd = true;
|
||||
}
|
||||
acc.Username = user.Username;
|
||||
acc.ExternalId = user.Id.ToString();
|
||||
acc.IsBot = user.IsBot || user.IsWebhook;
|
||||
acc.Protocol = PROTOCOL;
|
||||
|
||||
if(hadToAdd)
|
||||
{
|
||||
acc.IsUser = _db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
|
||||
if(acc.IsUser == null)
|
||||
{
|
||||
acc.IsUser = new User() { Accounts = new List<Account>() { acc } };
|
||||
_db.Users.Add(acc.IsUser);
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
|
@ -15,12 +15,13 @@ namespace vassago.TwitchInterface;
|
||||
|
||||
public class TwitchInterface
|
||||
{
|
||||
internal const string PROTOCOL = "Twitch";
|
||||
internal const string PROTOCOL = "twitch";
|
||||
private bool eventsSignedUp = false;
|
||||
private ChattingContext _db;
|
||||
private static SemaphoreSlim twitchChannelSetup = new SemaphoreSlim(1, 1);
|
||||
private Channel protocolAsChannel;
|
||||
TwitchClient client;
|
||||
TwitchAPI api;
|
||||
|
||||
public TwitchInterface()
|
||||
{
|
||||
@ -83,10 +84,23 @@ public class TwitchInterface
|
||||
client.OnWhisperReceived += Client_OnWhisperReceivedAsync;
|
||||
client.OnConnected += Client_OnConnected;
|
||||
|
||||
Console.WriteLine("twitch client connecting...");
|
||||
Console.WriteLine("twitch client 1 connecting...");
|
||||
client.Connect();
|
||||
Console.WriteLine("twitch client connected");
|
||||
Console.WriteLine("twitch client 1 connected");
|
||||
|
||||
// Console.WriteLine("twitch API client connecting...");
|
||||
// api = new TwitchAPI();
|
||||
// Console.WriteLine("can I just use the same creds as the other client?");
|
||||
// api.Settings.ClientId = tc.username;
|
||||
// api.Settings.AccessToken = tc.oauth;
|
||||
// try{
|
||||
// var neckbreads = await api.Helix.Moderation.GetModeratorsAsync("silvermeddlists");
|
||||
// Console.WriteLine($"{neckbreads?.Data?.Count()} shabby beards that need to be given up on");
|
||||
// }
|
||||
// catch(Exception e){
|
||||
// Console.Error.WriteLine(e);
|
||||
// }
|
||||
// Console.WriteLine("k.");
|
||||
}
|
||||
|
||||
private async void Client_OnWhisperReceivedAsync(object sender, OnWhisperReceivedArgs e)
|
||||
@ -148,28 +162,23 @@ public class TwitchInterface
|
||||
|
||||
private Account UpsertAccount(string username, Guid inChannel)
|
||||
{
|
||||
var hadToAdd = false;
|
||||
var acc = _db.Accounts.FirstOrDefault(ui => ui.ExternalId == username && ui.SeenInChannel.Id == inChannel);
|
||||
if (acc == null)
|
||||
{
|
||||
acc = new Account();
|
||||
_db.Accounts.Add(acc);
|
||||
hadToAdd = true;
|
||||
}
|
||||
acc.Username = username;
|
||||
acc.ExternalId = username;
|
||||
//acc.IsBot =
|
||||
acc.Protocol = PROTOCOL;
|
||||
|
||||
if (hadToAdd)
|
||||
{
|
||||
acc.IsUser = _db.Users.FirstOrDefault(u => u.Accounts.Any(a => a.ExternalId == acc.ExternalId && a.Protocol == acc.Protocol));
|
||||
if (acc.IsUser == null)
|
||||
{
|
||||
acc.IsUser = new vassago.Models.User() { Accounts = new List<Account>() { acc } };
|
||||
_db.Users.Add(acc.IsUser);
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
@ -191,7 +200,6 @@ public class TwitchInterface
|
||||
c.SendMessage = (t) => { return Task.Run(() => { client.SendMessage(channelName, t); }); };
|
||||
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
|
||||
return c;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private Channel UpsertDMChannel(string whisperWith)
|
||||
{
|
||||
@ -208,10 +216,20 @@ public class TwitchInterface
|
||||
c.Protocol = PROTOCOL;
|
||||
c.ParentChannel = protocolAsChannel;
|
||||
c.SubChannels = c.SubChannels ?? new List<Channel>();
|
||||
c.SendMessage = (t) => { return Task.Run(() => { client.SendWhisper(whisperWith, t); }); };
|
||||
c.SendMessage = (t) => { return Task.Run(() => {
|
||||
try
|
||||
{
|
||||
|
||||
client.SendWhisper(whisperWith, t);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.Error.WriteLine(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
|
||||
return c;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Message UpsertMessage(ChatMessage chatMessage)
|
||||
@ -261,7 +279,7 @@ public class TwitchInterface
|
||||
public string AttemptJoin(string channelTarget)
|
||||
{
|
||||
client.JoinChannel(channelTarget);
|
||||
return "o7";
|
||||
return $"attempt join {channelTarget} - o7";
|
||||
}
|
||||
|
||||
internal void AttemptLeave(string channelTarget)
|
||||
|
21
Views/Users/Details.cshtml
Normal file
21
Views/Users/Details.cshtml
Normal file
@ -0,0 +1,21 @@
|
||||
@model User
|
||||
@{
|
||||
ViewData["Title"] = "User details";
|
||||
}
|
||||
|
||||
User @Model.DisplayName<br />
|
||||
|
||||
<div class="permissions">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="accounts">
|
||||
@foreach (var acc in Model.Accounts)
|
||||
{
|
||||
<div class="account @acc.Protocol">
|
||||
<div class="protocol-icon"> </div>
|
||||
@Html.DisplayFor(acc => acc.DisplayName)
|
||||
<a asp-controller="Accounts" asp-action="Details" asp-route-id="@acc.Id">Details</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
@ -30,9 +30,7 @@
|
||||
@Html.DisplayFor(modelItem => item.Accounts.Count)x
|
||||
</td>
|
||||
<td>
|
||||
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
|
||||
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
|
||||
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
|
||||
<a asp-action="Details" asp-route-id="@item.Id">Details</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
@ -20,3 +20,15 @@ html {
|
||||
body {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
.account .protocol-icon{
|
||||
display:inline-block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-size: 32px;
|
||||
}
|
||||
.account.discord .protocol-icon{
|
||||
background-image: url("../imgs/discord_logo1600.png");
|
||||
}
|
||||
.account.twitch .protocol-icon{
|
||||
background-image: url("../imgs/twitch.png");
|
||||
}
|
BIN
wwwroot/imgs/discord_logo1600.png
Normal file
BIN
wwwroot/imgs/discord_logo1600.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
wwwroot/imgs/twitch.png
Normal file
BIN
wwwroot/imgs/twitch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
Loading…
Reference in New Issue
Block a user