diff --git a/SessionCompanion/SessionCompanion.Database/Migrations/20201228114303_Class name fix.Designer.cs b/SessionCompanion/SessionCompanion.Database/Migrations/20201228114303_Class name fix.Designer.cs new file mode 100644 index 0000000..7bbd955 --- /dev/null +++ b/SessionCompanion/SessionCompanion.Database/Migrations/20201228114303_Class name fix.Designer.cs @@ -0,0 +1,838 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using SessionCompanion.Database; + +namespace SessionCompanion.Database.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20201228114303_Class name fix")] + partial class Classnamefix + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityColumns() + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.0"); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Alignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.HasKey("Id"); + + b.ToTable("Alignments"); + + b.HasData( + new + { + Id = 1 + }, + new + { + Id = 2 + }, + new + { + Id = 3 + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Background", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.HasKey("Id"); + + b.ToTable("Backgrounds"); + + b.HasData( + new + { + Id = 1 + }, + new + { + Id = 2 + }, + new + { + Id = 3 + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Biography", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("AlignmentId") + .HasColumnType("int"); + + b.Property("BackgroundId") + .HasColumnType("int"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("ClassId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("RaceId") + .HasColumnType("int"); + + b.Property("Sex") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AlignmentId"); + + b.HasIndex("BackgroundId"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.HasIndex("ClassId"); + + b.HasIndex("RaceId"); + + b.ToTable("Biographies"); + + b.HasData( + new + { + Id = 1, + AlignmentId = 1, + BackgroundId = 1, + CharacterId = 1, + ClassId = 1, + Name = "Bob", + RaceId = 1, + Sex = "Male" + }, + new + { + Id = 2, + AlignmentId = 2, + BackgroundId = 2, + CharacterId = 2, + ClassId = 2, + Name = "Queen Daenerys Stormborn of the House Targaryen, the First of Her Name, Queen of the Andals, the Rhoynar and the First Men, Lady of the Seven Kingdoms and Protector of the Realm, Lady of Dragonstone, Queen of Meereen, Khaleesi of the Great Grass Sea, the Unburnt, Breaker of Chains and Mother of Dragons.", + RaceId = 2, + Sex = "Female" + }, + new + { + Id = 3, + AlignmentId = 3, + BackgroundId = 3, + CharacterId = 3, + ClassId = 3, + Name = "Gandalf the White", + RaceId = 3, + Sex = "Both" + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Character", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Characters"); + + b.HasData( + new + { + Id = 1, + UserId = 1 + }, + new + { + Id = 2, + UserId = 2 + }, + new + { + Id = 3, + UserId = 3 + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Charisma", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("CanDeception") + .HasColumnType("bit"); + + b.Property("CanIntimidation") + .HasColumnType("bit"); + + b.Property("CanPerformance") + .HasColumnType("bit"); + + b.Property("CanPersuasion") + .HasColumnType("bit"); + + b.Property("CanSaveThrows") + .HasColumnType("bit"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("Deception") + .HasColumnType("int"); + + b.Property("Intimidation") + .HasColumnType("int"); + + b.Property("Modification") + .HasColumnType("int"); + + b.Property("Performance") + .HasColumnType("int"); + + b.Property("Persuasion") + .HasColumnType("int"); + + b.Property("SavingThrows") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.ToTable("Charismas"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Class", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Classes"); + + b.HasData( + new + { + Id = 1, + Name = "Fighter" + }, + new + { + Id = 2, + Name = "Paladin" + }, + new + { + Id = 3, + Name = "Cleric" + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Constitution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("CanSaveThrows") + .HasColumnType("bit"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("Modification") + .HasColumnType("int"); + + b.Property("SavingThrows") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.ToTable("Constitutions"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Dexterity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("Acrobatics") + .HasColumnType("int"); + + b.Property("CanAcrobatics") + .HasColumnType("bit"); + + b.Property("CanSaveThrows") + .HasColumnType("bit"); + + b.Property("CanSleightOfHand") + .HasColumnType("bit"); + + b.Property("CanStealth") + .HasColumnType("bit"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("Modification") + .HasColumnType("int"); + + b.Property("SavingThrows") + .HasColumnType("int"); + + b.Property("SleightOfHand") + .HasColumnType("int"); + + b.Property("Stealth") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.ToTable("Dexterities"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Intelligence", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("Arcana") + .HasColumnType("int"); + + b.Property("CanArcana") + .HasColumnType("bit"); + + b.Property("CanHistory") + .HasColumnType("bit"); + + b.Property("CanInvestigation") + .HasColumnType("bit"); + + b.Property("CanNature") + .HasColumnType("bit"); + + b.Property("CanReligion") + .HasColumnType("bit"); + + b.Property("CanSaveThrows") + .HasColumnType("bit"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("History") + .HasColumnType("int"); + + b.Property("Investigation") + .HasColumnType("int"); + + b.Property("Modification") + .HasColumnType("int"); + + b.Property("Nature") + .HasColumnType("int"); + + b.Property("Religion") + .HasColumnType("int"); + + b.Property("SavingThrows") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.ToTable("Intelligences"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Race", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Races"); + + b.HasData( + new + { + Id = 1, + Name = "Human" + }, + new + { + Id = 2, + Name = "Dwarf" + }, + new + { + Id = 3, + Name = "Elf" + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Statistics", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("ArmorClass") + .HasColumnType("int"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("CurrentHealthPoints") + .HasColumnType("int"); + + b.Property("ExperiencePoints") + .HasColumnType("int"); + + b.Property("HealthPoints") + .HasColumnType("int"); + + b.Property("Initiative") + .HasColumnType("int"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Proficiency") + .HasColumnType("int"); + + b.Property("Speed") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.ToTable("Statistics"); + + b.HasData( + new + { + Id = 1, + ArmorClass = 9, + CharacterId = 1, + CurrentHealthPoints = 18, + ExperiencePoints = 2, + HealthPoints = 20, + Initiative = 12, + Level = 1, + Proficiency = 1, + Speed = 5 + }, + new + { + Id = 2, + ArmorClass = 12, + CharacterId = 2, + CurrentHealthPoints = 26, + ExperiencePoints = 0, + HealthPoints = 26, + Initiative = 7, + Level = 1, + Proficiency = 1, + Speed = 10 + }, + new + { + Id = 3, + ArmorClass = 2, + CharacterId = 3, + CurrentHealthPoints = 7, + ExperiencePoints = 24, + HealthPoints = 7, + Initiative = 18, + Level = 1, + Proficiency = 2, + Speed = 15 + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Strength", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("Athletics") + .HasColumnType("int"); + + b.Property("CanAthletics") + .HasColumnType("bit"); + + b.Property("CanSaveThrows") + .HasColumnType("bit"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("Modification") + .HasColumnType("int"); + + b.Property("SavingThrows") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.ToTable("Strengths"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("Password") + .HasColumnType("nvarchar(max)"); + + b.Property("Username") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + + b.HasData( + new + { + Id = 1, + Password = "123", + Username = "Morwiec" + }, + new + { + Id = 2, + Password = "123", + Username = "Cichoklepiec" + }, + new + { + Id = 3, + Password = "123", + Username = "Ruletka" + }); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Wisdom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("AnimalHandling") + .HasColumnType("int"); + + b.Property("CanAnimalHandling") + .HasColumnType("bit"); + + b.Property("CanInsight") + .HasColumnType("bit"); + + b.Property("CanMedicine") + .HasColumnType("bit"); + + b.Property("CanPerception") + .HasColumnType("bit"); + + b.Property("CanSaveThrows") + .HasColumnType("bit"); + + b.Property("CanSurvival") + .HasColumnType("bit"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("Insight") + .HasColumnType("int"); + + b.Property("Medicine") + .HasColumnType("int"); + + b.Property("Modification") + .HasColumnType("int"); + + b.Property("Perception") + .HasColumnType("int"); + + b.Property("SavingThrows") + .HasColumnType("int"); + + b.Property("Survival") + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId") + .IsUnique(); + + b.ToTable("Wisdoms"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Biography", b => + { + b.HasOne("SessionCompanion.Database.Tables.Alignment", "Alignment") + .WithMany("Biography") + .HasForeignKey("AlignmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SessionCompanion.Database.Tables.Background", "Background") + .WithMany("Biography") + .HasForeignKey("BackgroundId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Biography") + .HasForeignKey("SessionCompanion.Database.Tables.Biography", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SessionCompanion.Database.Tables.Class", "Class") + .WithMany("Biography") + .HasForeignKey("ClassId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("SessionCompanion.Database.Tables.Race", "Race") + .WithMany("Biography") + .HasForeignKey("RaceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Alignment"); + + b.Navigation("Background"); + + b.Navigation("Character"); + + b.Navigation("Class"); + + b.Navigation("Race"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Character", b => + { + b.HasOne("SessionCompanion.Database.Tables.User", "User") + .WithMany("Character") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Charisma", b => + { + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Charisma") + .HasForeignKey("SessionCompanion.Database.Tables.Charisma", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Constitution", b => + { + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Constitution") + .HasForeignKey("SessionCompanion.Database.Tables.Constitution", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Dexterity", b => + { + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Dexterity") + .HasForeignKey("SessionCompanion.Database.Tables.Dexterity", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Intelligence", b => + { + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Intelligence") + .HasForeignKey("SessionCompanion.Database.Tables.Intelligence", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Statistics", b => + { + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Statistics") + .HasForeignKey("SessionCompanion.Database.Tables.Statistics", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Strength", b => + { + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Strength") + .HasForeignKey("SessionCompanion.Database.Tables.Strength", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Wisdom", b => + { + b.HasOne("SessionCompanion.Database.Tables.Character", "Character") + .WithOne("Wisdom") + .HasForeignKey("SessionCompanion.Database.Tables.Wisdom", "CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Alignment", b => + { + b.Navigation("Biography"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Background", b => + { + b.Navigation("Biography"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Character", b => + { + b.Navigation("Biography"); + + b.Navigation("Charisma"); + + b.Navigation("Constitution"); + + b.Navigation("Dexterity"); + + b.Navigation("Intelligence"); + + b.Navigation("Statistics"); + + b.Navigation("Strength"); + + b.Navigation("Wisdom"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Class", b => + { + b.Navigation("Biography"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.Race", b => + { + b.Navigation("Biography"); + }); + + modelBuilder.Entity("SessionCompanion.Database.Tables.User", b => + { + b.Navigation("Character"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/SessionCompanion/SessionCompanion.Database/Migrations/20201228114303_Class name fix.cs b/SessionCompanion/SessionCompanion.Database/Migrations/20201228114303_Class name fix.cs new file mode 100644 index 0000000..c0633fa --- /dev/null +++ b/SessionCompanion/SessionCompanion.Database/Migrations/20201228114303_Class name fix.cs @@ -0,0 +1,55 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace SessionCompanion.Database.Migrations +{ + public partial class Classnamefix : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "Classes", + keyColumn: "Id", + keyValue: 1, + column: "Name", + value: "Fighter"); + + migrationBuilder.UpdateData( + table: "Classes", + keyColumn: "Id", + keyValue: 2, + column: "Name", + value: "Paladin"); + + migrationBuilder.UpdateData( + table: "Classes", + keyColumn: "Id", + keyValue: 3, + column: "Name", + value: "Cleric"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.UpdateData( + table: "Classes", + keyColumn: "Id", + keyValue: 1, + column: "Name", + value: "Warrior"); + + migrationBuilder.UpdateData( + table: "Classes", + keyColumn: "Id", + keyValue: 2, + column: "Name", + value: "Knight"); + + migrationBuilder.UpdateData( + table: "Classes", + keyColumn: "Id", + keyValue: 3, + column: "Name", + value: "Priest"); + } + } +} diff --git a/SessionCompanion/SessionCompanion.Database/Migrations/ApplicationDbContextModelSnapshot.cs b/SessionCompanion/SessionCompanion.Database/Migrations/ApplicationDbContextModelSnapshot.cs index 7898310..e4915a1 100644 --- a/SessionCompanion/SessionCompanion.Database/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/SessionCompanion/SessionCompanion.Database/Migrations/ApplicationDbContextModelSnapshot.cs @@ -255,17 +255,17 @@ namespace SessionCompanion.Database.Migrations new { Id = 1, - Name = "Warrior" + Name = "Fighter" }, new { Id = 2, - Name = "Knight" + Name = "Paladin" }, new { Id = 3, - Name = "Priest" + Name = "Cleric" }); }); diff --git a/SessionCompanion/SessionCompanion.Database/SeedData.cs b/SessionCompanion/SessionCompanion.Database/SeedData.cs index 81a9f5e..38fda48 100644 --- a/SessionCompanion/SessionCompanion.Database/SeedData.cs +++ b/SessionCompanion/SessionCompanion.Database/SeedData.cs @@ -66,17 +66,17 @@ namespace SessionCompanion.Database new Class { Id = 1, - Name = "Warrior" + Name = "Fighter" }, new Class { Id = 2, - Name = "Knight" + Name = "Paladin" }, new Class { Id = 3, - Name = "Priest" + Name = "Cleric" } }; return classes; diff --git a/SessionCompanion/SessionCompanion.Services/Profiles/CharacterProfile.cs b/SessionCompanion/SessionCompanion.Services/Profiles/CharacterProfile.cs index 7f1417b..0262a5f 100644 --- a/SessionCompanion/SessionCompanion.Services/Profiles/CharacterProfile.cs +++ b/SessionCompanion/SessionCompanion.Services/Profiles/CharacterProfile.cs @@ -23,7 +23,8 @@ namespace SessionCompanion.Services.Profiles CreateMap() .ForMember(vm => vm.Name, conf => conf.MapFrom(charact => charact.Biography.Name)) .ForMember(vm => vm.Level, conf => conf.MapFrom(charact => charact.Statistics.Level)) - .ForMember(vm => vm.CurrentHealthPoints, conf => conf.MapFrom(charact => charact.Statistics.CurrentHealthPoints)).ReverseMap(); + .ForMember(vm => vm.CurrentHealthPoints, conf => conf.MapFrom(charact => charact.Statistics.CurrentHealthPoints)) + .ForMember(vm => vm.Class, conf => conf.MapFrom(charact => charact.Biography.Class.Name)).ReverseMap(); } } } diff --git a/SessionCompanion/SessionCompanion.Services/Services/CharacterService.cs b/SessionCompanion/SessionCompanion.Services/Services/CharacterService.cs index a336d42..a07f53c 100644 --- a/SessionCompanion/SessionCompanion.Services/Services/CharacterService.cs +++ b/SessionCompanion/SessionCompanion.Services/Services/CharacterService.cs @@ -46,6 +46,7 @@ namespace SessionCompanion.Services.Services { var characters = await Repository.Get(c => charactersId.Contains(c.Id)) .Include(x => x.Biography) + .ThenInclude(x => x.Class) .Include(x => x.Statistics).ToListAsync(); var result = Mapper.Map>(characters); return result; diff --git a/SessionCompanion/SessionCompanion.ViewModels/CharacterViewModels/CharacterBasicStatsViewModel.cs b/SessionCompanion/SessionCompanion.ViewModels/CharacterViewModels/CharacterBasicStatsViewModel.cs index 525419f..adbfafd 100644 --- a/SessionCompanion/SessionCompanion.ViewModels/CharacterViewModels/CharacterBasicStatsViewModel.cs +++ b/SessionCompanion/SessionCompanion.ViewModels/CharacterViewModels/CharacterBasicStatsViewModel.cs @@ -21,5 +21,10 @@ /// Aktualna ilość życia postaci /// public int CurrentHealthPoints { get; set; } + + /// + /// Klasa postaci + /// + public string Class { get; set; } } } diff --git a/SessionCompanion/SessionCompanion.ViewModels/SessionCompanion.ViewModels.xml b/SessionCompanion/SessionCompanion.ViewModels/SessionCompanion.ViewModels.xml index 0f4d1b1..0a8cd0b 100644 --- a/SessionCompanion/SessionCompanion.ViewModels/SessionCompanion.ViewModels.xml +++ b/SessionCompanion/SessionCompanion.ViewModels/SessionCompanion.ViewModels.xml @@ -100,6 +100,11 @@ Aktualna ilość życia postaci + + + Klasa postaci + + Identyfikator postaci diff --git a/SessionCompanion/SessionCompanion/ClientApp/.prettierrc b/SessionCompanion/SessionCompanion/ClientApp/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/package-lock.json b/SessionCompanion/SessionCompanion/ClientApp/package-lock.json index e784a87..d012404 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/package-lock.json +++ b/SessionCompanion/SessionCompanion/ClientApp/package-lock.json @@ -9747,6 +9747,12 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -12040,6 +12046,12 @@ } } }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, "tsutils": { "version": "2.29.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", diff --git a/SessionCompanion/SessionCompanion/ClientApp/package.json b/SessionCompanion/SessionCompanion/ClientApp/package.json index 8d97cb5..5e89112 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/package.json +++ b/SessionCompanion/SessionCompanion/ClientApp/package.json @@ -53,6 +53,7 @@ "karma-coverage-istanbul-reporter": "~2.1.0", "karma-jasmine": "~2.0.1", "karma-jasmine-html-reporter": "^1.4.2", + "prettier": "2.2.1", "typescript": "3.5.3" }, "optionalDependencies": { diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.component.ts index b7b309e..96d886d 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.component.ts @@ -1,9 +1,17 @@ -import { Component } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; +import {SessionCompanionIconsRegistry} from './shared/sc-icons/session-companion-icons-registry.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) -export class AppComponent { +export class AppComponent implements OnInit{ title = 'Session Companion'; + + constructor(private iconService: SessionCompanionIconsRegistry) { + } + + ngOnInit() { + this.iconService.registerIcons(); + } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts index 6bed2fc..29d4a9b 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/app.module.ts @@ -23,9 +23,9 @@ import { import {UserService} from '../services/user.service'; import { StoreModule } from '@ngrx/store'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; -import { reducers} from './reducers'; -import {AppReducer} from './store/reducers/app.reducer'; import {environment} from '../environments/environment'; +import {reducers} from './store/models/app-state.model'; +import {CharacterService} from '../services/character.service'; @NgModule({ declarations: [ @@ -54,13 +54,14 @@ BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), MatSidenavModule, MatToolbarModule, MatListModule, - StoreModule.forRoot({appState: AppReducer}), + StoreModule.forRoot(reducers), StoreDevtoolsModule.instrument({ logOnly: environment.production }) ], providers: [ - UserService + UserService, + CharacterService ], bootstrap: [AppComponent] }) diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.html index 6b72c96..34918b5 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.html @@ -1,56 +1,96 @@ -
- - -
- -
- - - - folder - Link 1 - - - folder - Link 2 - - - folder - Link 3 - - -
- - - SessionCompanion - - - -
- - -
- - - - folder - Link 1 - - - folder - Link 2 - - - folder - Link 3 - - -
-
+
+ + +
+ +
+ + + + folder + Link 1 + + + folder + Link 2 + + + folder + Link 3 + + +
+ + + SessionCompanion + + + +
+ + +
+ + + + + {{ + loggedCharacter.name.length > 12 + ? (loggedCharacter.name | slice: 0:12) + '..' + : loggedCharacter.name + }} + + +
+
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts index 1b303b8..d93a20e 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/game-master-dashboard/game-master-dashboard.component.ts @@ -1,20 +1,37 @@ -import {Component, OnInit} from '@angular/core'; -import {animateText, onSideNavChange} from '../../shared/animations/sidenav-animations'; -import {GMSignalRService} from '../../shared/signalR-service/gm-signalR.service'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { + animateText, + onSideNavChange, +} from '../../shared/animations/sidenav-animations'; +import { GMSignalRService } from '../../shared/signalR-service/gm-signalR.service'; +import { CharacterService } from '../../../services/character.service'; +import { Subscription } from 'rxjs'; +import { ErrorResponse } from '../../../types/ErrorResponse'; +import { HttpErrorResponse } from '@angular/common/http'; +import { LoggedCharactersViewModel } from '../../../types/viewmodels/character-viewmodels/LoggedCharactersViewModel'; +import { first } from 'rxjs/operators'; @Component({ selector: 'app-game-master-dashboard', templateUrl: './game-master-dashboard.component.html', styleUrls: ['./game-master-dashboard.component.css'], - animations: [onSideNavChange, animateText] + animations: [onSideNavChange, animateText], }) -export class GameMasterDashboardComponent implements OnInit { +export class GameMasterDashboardComponent implements OnInit, OnDestroy { + allSubscriptions = new Subscription(); leftSidenavExpanded = false; leftSidenavTextExpanded = false; rightSidenavExpanded = false; rightSidenavTextExpanded = false; - constructor(private signalRService: GMSignalRService) {} + loggedCharacters: LoggedCharactersViewModel[]; + + constructor( + private signalRService: GMSignalRService, + private characterService: CharacterService + ) { + this.SubscribeToEvents(); + } ngOnInit() { this.signalRService.Login(); @@ -36,4 +53,36 @@ export class GameMasterDashboardComponent implements OnInit { break; } } + + UpdateCharactersList(): void { + this.characterService + .getLoggedCharacters() + .pipe(first()) + .subscribe( + (success) => { + this.loggedCharacters = success; + }, + (error: ErrorResponse | HttpErrorResponse) => { + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + console.error(error.message); + } + ); + } + + private SubscribeToEvents(): void { + this.signalRService.message.subscribe((message: string) => { + if ( + message === 'New player connected' || + message === 'Player disconnected' + ) { + this.UpdateCharactersList(); + } + }); + } + + ngOnDestroy() { + this.allSubscriptions.unsubscribe(); + } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html index c9837d9..9f07043 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.html @@ -1,6 +1,6 @@
- arrow_back + arrow_back
Create an Account
@@ -11,7 +11,7 @@ type="text" required name="username"> - + Username is required person @@ -26,7 +26,7 @@ type="password" name="password"/> lock - + Password is required @@ -40,10 +40,10 @@ type="password" name="confirmPassword"/> lock - + Confirm your password - + Please make sure your passwords match diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.ts index 5532c93..f3ebc93 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/registration/registration.component.ts @@ -6,7 +6,6 @@ import {Subscription} from 'rxjs'; import {ErrorResponse} from '../../../types/ErrorResponse'; import {UserRegisterViewModel} from '../../../types/viewmodels/user-viewmodels/UserRegisterViewModel'; import {HttpErrorResponse} from '@angular/common/http'; -import {type} from 'os'; @Component({ selector: 'app-registration', @@ -36,27 +35,33 @@ export class RegistrationComponent implements OnDestroy { } Register() { - const userRegisterModel = new class implements UserRegisterViewModel { - password: string; - username: string; - }; + if (this.signUpFormGroup.valid) { + const userRegisterModel = new class implements UserRegisterViewModel { + password: string; + username: string; + }; - userRegisterModel.username = this.signUpFormGroup.get('newAccount').value['username']; - userRegisterModel.password = this.signUpFormGroup.get('newAccount').value['password']; + userRegisterModel.username = this.signUpFormGroup.get('newAccount').value['username']; + userRegisterModel.password = this.signUpFormGroup.get('newAccount').value['password']; - this.allSubscriptions.add( - this.userService.registerUser(userRegisterModel).subscribe( - () => { - this.router.navigate(['login']); - }, - (error: ErrorResponse | HttpErrorResponse) => { - if (error instanceof HttpErrorResponse) { - error = error.error as ErrorResponse; + this.allSubscriptions.add( + this.userService.registerUser(userRegisterModel).subscribe( + () => { + this.router.navigate(['login']); + }, + (error: ErrorResponse | HttpErrorResponse) => { + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + this.apiError = true; + this.apiErrorMessage = error.message; } - this.apiError = true; - this.apiErrorMessage = error.message; - } - )); + )); + } else { + this.signUpFormGroup.get('newAccount').get('username').markAsTouched(); + this.signUpFormGroup.get('newAccount').get('password').markAsTouched(); + this.signUpFormGroup.get('newAccount').get('confirmPassword').markAsTouched(); + } } ngOnDestroy() { diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css index ccf116c..41aa481 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.css @@ -47,10 +47,6 @@ input { font-size: 20px; } -.align-to-right { - text-align: right; -} - @media (max-width: 400px) { .container { margin-left: 0%; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html index 178319d..5eae2cc 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.html @@ -1,21 +1,15 @@
- arrow_back + arrow_back
Select character
- + - Oweja - arrow_forward + + account_circle +
{{character.name}}
+ arrow_forward +
{{character.className}} level: {{character.level}}
+
- - James - arrow_forward - - - Legolas - arrow_forward - - -
- +
diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts index 2409f57..bb796df 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-character/select-character.component.ts @@ -1,30 +1,49 @@ -import { Component } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import { Router } from '@angular/router'; +import {first} from 'rxjs/operators'; +import {ClearUserId} from '../../store/actions/app.actions'; +import {ErrorResponse} from '../../../types/ErrorResponse'; +import {HttpErrorResponse} from '@angular/common/http'; +import {Store} from '@ngrx/store'; +import {AppState} from '../../store/models/app-state.model'; +import {CharacterService} from '../../../services/character.service'; +import {CharacterForLoginViewModel} from '../../../types/viewmodels/character-viewmodels/CharacterForLoginViewModel'; +import {AddCharacterId} from '../../store/actions/player.action'; @Component({ selector: 'app-select-character', templateUrl: './select-character.component.html', styleUrls: ['./select-character.component.css'] }) -export class SelectCharacterComponent { - isExpanded = false; +export class SelectCharacterComponent implements OnInit { + charactersList: CharacterForLoginViewModel[]; - collapse() { - this.isExpanded = false; + constructor(private router: Router, private store: Store, private characterService: CharacterService) {} + + ngOnInit() { + this.getUserCharactersList(); } - toggle() { - this.isExpanded = !this.isExpanded; + getUserCharactersList() { + this.store.select(s => s.appStore.userId).pipe(first()).subscribe((userId) => { + this.characterService.getUserCharactersList(userId).pipe(first()).subscribe((charactersList) => { + this.charactersList = charactersList; + }, (error: ErrorResponse | HttpErrorResponse) => { + if (error instanceof HttpErrorResponse) { + error = error.error as ErrorResponse; + } + console.error(error.message); + } ); + }); } - constructor(private router: Router) {} - - onCharacterClick(){ - this.router.navigate(['player']) + onCharacterClick(characterId: number) { + this.store.dispatch(new AddCharacterId({characterId})); + this.router.navigate(['player']); } - onArrowBackClick(){ - this.router.navigate(['login']) + onArrowBackClick() { + this.store.dispatch(new ClearUserId()); + this.router.navigate(['login']); } } - diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.ts index 12bb627..1565301 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/select-role/select-role.component.ts @@ -12,7 +12,8 @@ import {AddRole} from '../../store/actions/app.actions'; export class SelectRoleComponent { isExpanded = false; - constructor(private router: Router, private store: Store<{ role: string }>) {} + constructor(private router: Router, private store: Store<{ role: string }>) { + } collapse() { this.isExpanded = false; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html index 5b673af..6eede7b 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.html @@ -1,6 +1,6 @@
- arrow_back + arrow_back
Sign In
@@ -12,7 +12,7 @@ type="text" required name="username"> - + Username is required person @@ -28,7 +28,7 @@ type="password" name="password"/> lock - + Password is required diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.ts index 16ac96e..1bf5263 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/components/sign-in/sign-in.component.ts @@ -6,9 +6,10 @@ import {ErrorResponse} from '../../../types/ErrorResponse'; import {Observable, Subscription} from 'rxjs'; import {HttpErrorResponse} from '@angular/common/http'; import {AppStoreModel} from '../../store/models/app-store.model'; -import { Store } from '@ngrx/store'; +import {select, Store} from '@ngrx/store'; import {AddUserId} from '../../store/actions/app.actions'; -import { AppState } from 'src/app/store/models/app-state.model'; +import {AppState} from 'src/app/store/models/app-state.model'; +import {first} from "rxjs/operators"; @Component({ selector: 'app-sign-in', @@ -38,12 +39,12 @@ export class SignInComponent implements OnDestroy, OnInit { }); ngOnInit() { - this.role$ = this.store.select(s => s.appState); + this.role$ = this.store.select(s => s.appStore); } onLoginButtonClick() { let role = ''; - this.store.select(s => s.appState.role).subscribe((v)=>{ + this.store.select(s => s.appStore.role).pipe(first()).subscribe((v) => { role = v; }); this.allSubscriptions.add( @@ -52,7 +53,6 @@ export class SignInComponent implements OnDestroy, OnInit { this.signInFormGroup.get('signIn').value['password']).subscribe( (success) => { this.store.dispatch(new AddUserId({userId: success})); - //TODO zmienić na jedna linie if (role === 'player') { this.router.navigate(['select-character']); } else { @@ -69,13 +69,12 @@ export class SignInComponent implements OnDestroy, OnInit { )); } - onRegisterButtonClick(){ - this.router.navigate(['register']) - //TODO connect with backend + onRegisterButtonClick() { + this.router.navigate(['register']); } - onArrowBackClick(){ - this.router.navigate(['']) + onArrowBackClick() { + this.router.navigate(['']); } collapse() { diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/reducers/index.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/reducers/index.ts deleted file mode 100644 index 4f57bb0..0000000 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/reducers/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - ActionReducer, - ActionReducerMap, - createFeatureSelector, - createSelector, - MetaReducer -} from '@ngrx/store'; -import { environment } from '../../environments/environment'; - -export interface State { - -} - -export const reducers: ActionReducerMap = { - -}; - - -export const metaReducers: MetaReducer[] = !environment.production ? [] : []; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/sc-icons/how-to.RMD b/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/sc-icons/how-to.RMD new file mode 100644 index 0000000..b0d9081 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/sc-icons/how-to.RMD @@ -0,0 +1,4 @@ +Moduł został już dodany i wstrzyknięty do roota apki. + +Aby dodać nową ikonkę, plik svg wstawiamy do folderu assets/icons/svg-icons. +Oraz dodajym kolejnego enuma w pliku sc-icon.model.ts diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/sc-icons/session-companion-icons-registry.service.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/sc-icons/session-companion-icons-registry.service.ts new file mode 100644 index 0000000..6d48cad --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/sc-icons/session-companion-icons-registry.service.ts @@ -0,0 +1,22 @@ +import {Injectable} from '@angular/core'; +import {scIcon} from '../../../assets/icons/sc-icon.model'; +import {MatIconRegistry} from '@angular/material'; +import {DomSanitizer} from '@angular/platform-browser'; + +@Injectable({ + providedIn: 'root' +}) +export class SessionCompanionIconsRegistry { + constructor(private registry: MatIconRegistry, private sanitizer: DomSanitizer) { + } + + public registerIcons(): void { + this.loadIcons(Object.values(scIcon), '../assets/icons/svg-icons'); + } + + private loadIcons(iconKeys: string[], iconUrl: string): void { + iconKeys.forEach((icon: string) => { + this.registry.addSvgIcon(icon, this.sanitizer.bypassSecurityTrustResourceUrl(`${iconUrl}/${icon}.svg`)); + }); + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/signalR-service/gm-signalR.service.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/signalR-service/gm-signalR.service.ts index 4ca94db..08cf425 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/signalR-service/gm-signalR.service.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/shared/signalR-service/gm-signalR.service.ts @@ -1,12 +1,15 @@ import { Inject, Injectable } from '@angular/core'; import { SignalRService } from './base/signalR.service'; +import {Subject} from 'rxjs'; @Injectable({ providedIn: 'root' }) export class GMSignalRService { signalR: SignalRService; + message: Subject; constructor(@Inject('BASE_URL') baseUrl: string) { this.signalR = new SignalRService(baseUrl); + this.message = new Subject(); this.registerOnServerEvents(); } @@ -17,10 +20,15 @@ export class GMSignalRService { if (this.signalR.connectionEstablished$.getValue() === true) { this.signalR.hubConnection.send('GameMasterLogin'); } - }); + }).unsubscribe(); } private registerOnServerEvents(): void { - + this.signalR.hubConnection.on('Welcome', (message: string) => { + this.message.next('New player connected'); + }); + this.signalR.hubConnection.on('GoodBye', (message: string) => { + this.message.next('Player disconnected'); + }); } } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/app.actions.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/app.actions.ts index 4b2b34b..362b983 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/app.actions.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/app.actions.ts @@ -1,9 +1,9 @@ -import {AppStoreModel} from '../models/app-store.model'; -import { Action } from '@ngrx/store'; +import {Action} from '@ngrx/store'; export enum AppActionTypes { ADD_USER_ID = '[APP] Add user id', - ADD_ROLE = '[APP] Add role' + ADD_ROLE = '[APP] Add role', + CLEAR_USER_ID = '[APP] Clear user id' } export class AddUserId implements Action { @@ -20,4 +20,13 @@ export class AddRole implements Action { } } -export type AppAction = AddUserId | AddRole; +export class ClearUserId implements Action { + readonly type = AppActionTypes.CLEAR_USER_ID; + + constructor() { + } +} + + + +export type AppAction = AddUserId | AddRole | ClearUserId; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/player.action.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/player.action.ts new file mode 100644 index 0000000..45c74d8 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/actions/player.action.ts @@ -0,0 +1,15 @@ +import {Action} from "@ngrx/store"; + +export enum PlayerActionTypes { + ADD_CHARACTER_ID= '[PLAYER] Add character id' +} + +export class AddCharacterId implements Action { + readonly type = PlayerActionTypes.ADD_CHARACTER_ID; + + constructor(public payload: {characterId: number}) { + + } +} + +export type PlayerAction = AddCharacterId; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/models/app-state.model.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/models/app-state.model.ts index 30226ba..fe999ff 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/models/app-state.model.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/models/app-state.model.ts @@ -1,5 +1,15 @@ import {AppStoreModel} from './app-store.model'; +import {ActionReducerMap} from '@ngrx/store'; +import {AppReducer} from '../reducers/app.reducer'; +import {PlayerStoreModel} from './player-store.model'; +import {PlayerReducer} from '../reducers/player.reducer'; export interface AppState { - appState: AppStoreModel; + appStore: AppStoreModel; + playerStore: PlayerStoreModel; } + +export const reducers: ActionReducerMap = { + appStore: AppReducer, + playerStore: PlayerReducer, +}; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/models/player-store.model.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/models/player-store.model.ts new file mode 100644 index 0000000..8cc606f --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/models/player-store.model.ts @@ -0,0 +1,3 @@ +export interface PlayerStoreModel { + characterId: number; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/app.reducer.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/app.reducer.ts index 777c63a..d86c636 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/app.reducer.ts +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/app.reducer.ts @@ -12,6 +12,8 @@ export function AppReducer(state: AppStoreModel = initialState, action: AppActio return {...state, userId: action.payload.userId}; case AppActionTypes.ADD_ROLE: return {...state, role: action.payload.role}; + case AppActionTypes.CLEAR_USER_ID: + return {...state, userId: null}; default: return state; } diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/player.reducer.ts b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/player.reducer.ts new file mode 100644 index 0000000..3077834 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/app/store/reducers/player.reducer.ts @@ -0,0 +1,15 @@ +import {PlayerStoreModel} from '../models/player-store.model'; +import {PlayerAction, PlayerActionTypes} from '../actions/player.action'; + +const initialState: PlayerStoreModel = { + characterId: null +}; + +export function PlayerReducer(state: PlayerStoreModel = initialState, action: PlayerAction) { + switch (action.type) { + case PlayerActionTypes.ADD_CHARACTER_ID: + return {...state, characterId: action.payload.characterId}; + default: + return state; + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/sc-icon.model.ts b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/sc-icon.model.ts new file mode 100644 index 0000000..e3537d1 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/sc-icon.model.ts @@ -0,0 +1,14 @@ +export enum scIcon { + Barbarian = 'barbarian', + Bard = 'bard', + Cleric = 'cleric', + Druid = 'druid', + Fighter = 'fighter', + Monk = 'monk', + Paladin = 'paladin', + Ranger = 'ranger', + rogue = 'rogue', + Sorcerer = 'sorcerer', + Warlock = 'warlock', + Wizard = 'wizard' +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/barbarian.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/barbarian.svg new file mode 100644 index 0000000..ea18fd3 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/barbarian.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/bard.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/bard.svg new file mode 100644 index 0000000..1e139d8 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/bard.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/cleric.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/cleric.svg new file mode 100644 index 0000000..f7a6586 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/cleric.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/druid.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/druid.svg new file mode 100644 index 0000000..8290333b --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/druid.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/fighter.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/fighter.svg new file mode 100644 index 0000000..0f55a43 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/fighter.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/monk.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/monk.svg new file mode 100644 index 0000000..dccf6ac --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/monk.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/paladin.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/paladin.svg new file mode 100644 index 0000000..615bc8f --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/paladin.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/ranger.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/ranger.svg new file mode 100644 index 0000000..8defce6 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/ranger.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/rogue.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/rogue.svg new file mode 100644 index 0000000..a5ebf42 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/rogue.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/sorcerer.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/sorcerer.svg new file mode 100644 index 0000000..6fa42fb --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/sorcerer.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/warlock.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/warlock.svg new file mode 100644 index 0000000..d84762e --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/warlock.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/wizard.svg b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/wizard.svg new file mode 100644 index 0000000..1df2853 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/assets/icons/svg-icons/wizard.svg @@ -0,0 +1 @@ + diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts b/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts new file mode 100644 index 0000000..c390a44 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/services/character.service.ts @@ -0,0 +1,44 @@ +import {Inject, Injectable} from '@angular/core'; +import {HttpClient, HttpParams} from '@angular/common/http'; +import {Observable, of, throwError} from 'rxjs'; +import {ErrorResponse} from '../types/ErrorResponse'; +import {Either} from '../types/Either'; +import {CharacterForLoginViewModel} from '../types/viewmodels/character-viewmodels/CharacterForLoginViewModel'; +import {switchMap, retry} from 'rxjs/operators'; +import {LoggedCharactersViewModel} from '../types/viewmodels/character-viewmodels/LoggedCharactersViewModel'; + +Injectable({ + providedIn: 'root' +}) +export class CharacterService { + private baseUrl = 'api/character/'; + constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) { + this.baseUrl = baseUrl + this.baseUrl; + } + + getLoggedCharacters(): Observable { + return this.http.get>(this.baseUrl + 'loggedCharacters').pipe( + switchMap(response => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }), + retry(3) + ); + } + + getUserCharactersList(userId: number): Observable { + const params = new HttpParams().set('userId', userId.toString()) + return this.http.get>(this.baseUrl + 'userCharactersList', {params}).pipe( + switchMap(response => { + if (response.isLeft) { + return of(response.left); + } else { + return throwError(response.right); + } + }) + ); + } +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/styles.css b/SessionCompanion/SessionCompanion/ClientApp/src/styles.css index bd973fd..311e04a 100644 --- a/SessionCompanion/SessionCompanion/ClientApp/src/styles.css +++ b/SessionCompanion/SessionCompanion/ClientApp/src/styles.css @@ -73,6 +73,10 @@ mat-divider { border-top-color: #e9cca7 !important; } +.arrow-select { + cursor: pointer; +} + html, body { height: 100%; diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterForLoginViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterForLoginViewModel.ts new file mode 100644 index 0000000..fa9c0d8 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/CharacterForLoginViewModel.ts @@ -0,0 +1,7 @@ +export interface CharacterForLoginViewModel { + id: number; + userId: number; + name: string; + className: string; + level: number; +} diff --git a/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/LoggedCharactersViewModel.ts b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/LoggedCharactersViewModel.ts new file mode 100644 index 0000000..36ea974 --- /dev/null +++ b/SessionCompanion/SessionCompanion/ClientApp/src/types/viewmodels/character-viewmodels/LoggedCharactersViewModel.ts @@ -0,0 +1,7 @@ +export interface LoggedCharactersViewModel { + id: number; + name: string; + level: number; + currentHealthPoints: number; + class: string; +}