Skip to content

Commit

Permalink
replaced upvotes with 5-star rating
Browse files Browse the repository at this point in the history
  • Loading branch information
fgsfds committed Jun 20, 2024
1 parent 52006e9 commit b24af26
Show file tree
Hide file tree
Showing 38 changed files with 890 additions and 325 deletions.
14 changes: 9 additions & 5 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="AddSealed" Version="0.6.0" />
<PackageVersion Include="Avalonia" Version="11.0.10" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
<PackageVersion Include="Avalonia.Desktop" Version="11.0.10" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.0.10" />
<PackageVersion Include="Avalonia" Version="11.0.11" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.11" />
<PackageVersion Include="Avalonia.Desktop" Version="11.0.11" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.0.11" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.6" />
<PackageVersion Include="Avalonia.Fonts.Inter" Version="11.0.6" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageVersion Include="Markdown.Avalonia" Version="11.0.2" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.6">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageVersion>
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.6" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="8.0.6" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
Expand All @@ -21,7 +25,7 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageVersion Include="xunit" Version="2.8.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.1" />
<PackageVersion Include="AWSSDK.S3" Version="3.7.309.4" />
<PackageVersion Include="AWSSDK.S3" Version="3.7.309.5" />
<PackageVersion Include="ConfigureAwaitAnalyzer" Version="1.0.3" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageVersion Include="Microsoft.AspNetCore.SpaProxy" Version="8.0.6" />
Expand Down
14 changes: 12 additions & 2 deletions Web.Server/Controllers/AddonsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,21 @@ public AddonsController(AddonsProvider addonsProvider)


[HttpGet("scores")]
public Dictionary<string, int> GetScores() => _addonsProvider.GetScores();
[Obsolete]
public Dictionary<string, int> GetScores() => [];


[HttpPut("scores/change")]
public int ChangeScore([FromBody] Tuple<string, sbyte> message) => _addonsProvider.ChangeScore(message.Item1, message.Item2);
[Obsolete]
public int ChangeScore([FromBody] Tuple<string, sbyte> message) => 0;


[HttpGet("rating")]
public Dictionary<string, decimal> GetRating() => _addonsProvider.GetRating();


[HttpPut("rating/change")]
public decimal ChangeRating([FromBody] Tuple<string, sbyte, bool> message) => _addonsProvider.ChangeRating(message.Item1, message.Item2, message.Item3);


[HttpPut("installs/add")]
Expand Down
9 changes: 5 additions & 4 deletions Web.Server/Database/DatabaseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public sealed class DatabaseContext : DbContext
public DbSet<AddonsDbEntity> Addons { get; set; }
public DbSet<VersionsDbEntity> Versions { get; set; }
public DbSet<InstallsDbEntity> Installs { get; set; }
public DbSet<ScoresDbEntity> Scores { get; set; }
public DbSet<RatingsDbEntity> Rating { get; set; }
public DbSet<ReportsDbEntity> Reports { get; set; }
public DbSet<DependenciesDbEntity> Dependencies { get; set; }

Expand Down Expand Up @@ -164,13 +164,14 @@ private bool FillDb()
//Scores
foreach (var addon in Addons.AsNoTracking().ToList())
{
ScoresDbEntity score = new()
RatingsDbEntity score = new()
{
AddonId = addon.Id,
Score = 0
RatingSum = 0,
RatingTotal = 0
};

Scores.Add(score);
Rating.Add(score);
}

this.SaveChanges();
Expand Down
30 changes: 30 additions & 0 deletions Web.Server/DbEntities/RatingsDbEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Web.Server.DbEntities
{
[Table(name: "ratings", Schema = "main")]
public sealed class RatingsDbEntity
{
[Key]
[ForeignKey(nameof(AddonsTable))]
[Column("addon_id")]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public required string AddonId { get; set; }

[Column("rating_sum")]
public required decimal RatingSum { get; set; }

[Column("rating_total")]
public required decimal RatingTotal { get; set; }

[Column("rating")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DefaultValue("CASE rating_total WHEN 0 THEN 0 ELSE (rating_sum / rating_total) END")]
public decimal Rating { get; }


public AddonsDbEntity AddonsTable { get; set; }
}
}
21 changes: 0 additions & 21 deletions Web.Server/DbEntities/ScoresDbEntity.cs

This file was deleted.

43 changes: 17 additions & 26 deletions Web.Server/Providers/AddonsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal List<DownloadableAddonEntity> GetAddons(GameEnum gameEnum)
var versions = dbContext.Versions.AsNoTracking().Where(x => addons.Keys.Contains(x.AddonId)).ToDictionary(static x => x.Id);
var dependencies = dbContext.Dependencies.AsNoTracking().Where(x => versions.Keys.Contains(x.AddonVersionId)).ToLookup(static x => x.AddonVersionId);
var installs = dbContext.Installs.AsNoTracking().ToDictionary(static x => x.AddonId, static y => y.Installs);
var scores = dbContext.Scores.AsNoTracking().ToDictionary(static x => x.AddonId, static y => y.Score);
var ratings = dbContext.Rating.AsNoTracking().ToDictionary(static x => x.AddonId, static y => y.Rating);

List<DownloadableAddonEntity> result = new(versions.Count);

Expand All @@ -68,7 +68,7 @@ internal List<DownloadableAddonEntity> GetAddons(GameEnum gameEnum)
}

var hasInstalls = installs.TryGetValue(addon.Id, out var installsNumber);
var hasScore = scores.TryGetValue(addon.Id, out var scoreNumber);
var hasRating = ratings.TryGetValue(addon.Id, out var ratingNumber);

DownloadableAddonEntity newDownloadable = new()
{
Expand All @@ -84,7 +84,8 @@ internal List<DownloadableAddonEntity> GetAddons(GameEnum gameEnum)
Author = version.Value.Author,
Dependencies = depsResult,
Installs = hasInstalls ? installsNumber : 0,
Score = hasScore ? scoreNumber : 0,
Score = 0,

Check warning on line 87 in Web.Server/Providers/AddonsProvider.cs

View workflow job for this annotation

GitHub Actions / Build_and_Test_Linux

'DownloadableAddonEntity.Score' is obsolete
Rating = hasRating ? ratingNumber : 0,
UpdateDate = version.Value.UpdateDate
};

Expand Down Expand Up @@ -125,32 +126,21 @@ internal int IncreaseNumberOfInstalls(string addonId)
return newInstalls;
}

internal int ChangeScore(string addonId, sbyte increment)
internal decimal ChangeRating(string addonId, sbyte rating, bool isNew)
{
using var dbContext = _dbContextFactory.Get();
var fix = dbContext.Scores.Find(addonId);
var existingRating = dbContext.Rating.Find(addonId) ?? throw new Exception($"Rating for {addonId} is not found");

int newScore;
existingRating.RatingSum += rating;

if (fix is null)
if (isNew)
{
ScoresDbEntity newScoreEntity = new()
{
AddonId = addonId,
Score = increment
};

dbContext.Scores.Add(newScoreEntity);
newScore = increment;
}
else
{
fix.Score += increment;
newScore = fix.Score;
existingRating.RatingTotal++;
}

dbContext.SaveChanges();
return newScore;

return existingRating.Rating;
}

internal void AddReport(string addonId, string text)
Expand All @@ -167,10 +157,10 @@ internal void AddReport(string addonId, string text)
dbContext.SaveChanges();
}

internal Dictionary<string, int> GetScores()
internal Dictionary<string, decimal> GetRating()
{
using var dbContext = _dbContextFactory.Get();
return dbContext.Scores.ToDictionary(static x => x.AddonId, static y => y.Score);
return dbContext.Rating.ToDictionary(static x => x.AddonId, static y => y.Rating);
}

internal bool AddAddonToDatabase(AddonsJsonEntity addon)
Expand Down Expand Up @@ -245,14 +235,15 @@ internal bool AddAddonToDatabase(AddonsJsonEntity addon)
}


var existingScore = dbContext.Scores.Find(addon.Id);
var existingScore = dbContext.Rating.Find(addon.Id);

if (existingScore is null)
{
dbContext.Scores.Add(new()
dbContext.Rating.Add(new()
{
AddonId = addon.Id,
Score = 0
RatingSum = 0,
RatingTotal = 0
});

dbContext.SaveChanges();
Expand Down
3 changes: 2 additions & 1 deletion src/Avalonia/Core/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ public override void OnFrameworkInitializationCompleted()
var gamesProvider = BindingsManager.Provider.GetRequiredService<GamesProvider>();
var vmFactory = BindingsManager.Provider.GetRequiredService<ViewModelsFactory>();
var portsProvider = BindingsManager.Provider.GetRequiredService<PortsProvider>();
var configProvider = BindingsManager.Provider.GetRequiredService<IConfigProvider>();

desktop.MainWindow = new MainWindow(vm, gamesProvider, vmFactory, portsProvider);
desktop.MainWindow = new MainWindow(vm, gamesProvider, vmFactory, portsProvider, configProvider);

desktop.Exit += OnAppExit;
}
Expand Down
6 changes: 4 additions & 2 deletions src/Avalonia/Core/Controls/CampaignsControl.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using Avalonia.Media;
using BuildLauncher.Helpers;
using BuildLauncher.ViewModels;
using ClientCommon.Config;
using Common.Enums;
using Common.Enums.Addons;
using Common.Helpers;
using Common.Interfaces;
using CommunityToolkit.Mvvm.Input;
Expand All @@ -26,7 +26,7 @@ public CampaignsControl()
/// <summary>
/// Initialize control
/// </summary>
public void InitializeControl(PortsProvider portsProvider)
public void InitializeControl(PortsProvider portsProvider, IConfigProvider configProvider)
{
DataContext.ThrowIfNotType<CampaignsViewModel>(out var viewModel);

Expand All @@ -36,6 +36,8 @@ public void InitializeControl(PortsProvider portsProvider)
CampaignsList.SelectionChanged += OnCampaignsListSelectionChanged;
BottomPanel.DataContext = viewModel;

RightPanel.InitializeControl(configProvider);

AddPortsButtons();

AddContextMenuButtons();
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia/Core/Controls/DownloadsControl.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<DataGridTextColumn Header="Type" Binding="{Binding AddonType}" FontWeight="Bold" />
<DataGridTextColumn Header="Version" Binding="{Binding Version}" />
<DataGridTextColumn Header="Size" Binding="{Binding FileSizeString}" />
<DataGridTextColumn Header="Score" Binding="{Binding Score}" />
<DataGridTextColumn Header="Rating" Binding="{Binding Rating}" />
<DataGridTextColumn Header="Downloads" Binding="{Binding Installs}" />
<DataGridTextColumn Header="Updated" Binding="{Binding UpdateDateString}" SortMemberPath="UpdateDate" />
<DataGridTextColumn Header="Status" Binding="{Binding Status}" FontWeight="Bold" />
Expand Down
5 changes: 4 additions & 1 deletion src/Avalonia/Core/Controls/MapsControl.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Avalonia.Media;
using BuildLauncher.Helpers;
using BuildLauncher.ViewModels;
using ClientCommon.Config;
using Common.Enums;
using Common.Enums.Skills;
using Common.Helpers;
Expand All @@ -27,7 +28,7 @@ public MapsControl()
/// <summary>
/// Initialize control
/// </summary>
public void InitializeControl(PortsProvider portsProvider)
public void InitializeControl(PortsProvider portsProvider, IConfigProvider configProvider)
{
DataContext.ThrowIfNotType<MapsViewModel>(out var viewModel);

Expand All @@ -37,6 +38,8 @@ public void InitializeControl(PortsProvider portsProvider)
MapsList.SelectionChanged += OnMapsListSelectionChanged;
BottomPanel.DataContext = viewModel;

RightPanel.InitializeControl(configProvider);

CreateSkillsFlyout();

AddPortsButtons();
Expand Down
5 changes: 4 additions & 1 deletion src/Avalonia/Core/Controls/ModsControl.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Avalonia.Controls;
using BuildLauncher.ViewModels;
using ClientCommon.Config;
using Common.Helpers;
using CommunityToolkit.Mvvm.Input;

Expand All @@ -15,10 +16,12 @@ public ModsControl()
/// <summary>
/// Initialize control
/// </summary>
public void InitializeControl()
public void InitializeControl(IConfigProvider configProvider)
{
DataContext.ThrowIfNotType<ModsViewModel>(out var viewModel);

RightPanel.InitializeControl(configProvider);

AddContextMenuButtons(viewModel);
}

Expand Down
26 changes: 19 additions & 7 deletions src/Avalonia/Core/Controls/RightPanelControl.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,29 @@
Margin="0,0,0,5"
VerticalAlignment="Center"
HorizontalAlignment="Center"
IsVisible="{Binding SelectedAddonScore, Converter={x:Static ObjectConverters.IsNotNull}}">
IsVisible="{Binding SelectedAddonRating, Converter={x:Static ObjectConverters.IsNotNull}}">

<TextBlock Margin="3" VerticalAlignment="Center">Score:</TextBlock>
<TextBlock Margin="3" VerticalAlignment="Center">Rating:</TextBlock>

<Button IsVisible="{Binding IsSelectedAddonUpvoted}" Background="{DynamicResource SystemAccentColor}" Margin="3" Command="{Binding UpvoteCommand}">👍</Button>
<Button IsVisible="{Binding !IsSelectedAddonUpvoted}" Margin="3" Command="{Binding UpvoteCommand}">👍</Button>
<TextBlock Name="Rating" Margin="3" Text="{Binding SelectedAddonRating}" VerticalAlignment="Center"></TextBlock>

<TextBlock Margin="3" Text="{Binding SelectedAddonScore}" VerticalAlignment="Center"></TextBlock>
<StackPanel VerticalAlignment="Center" Orientation="Horizontal" Margin="0,0,0,2">

<Button IsVisible="{Binding IsSelectedAddonDownvoted}" Background="{DynamicResource SystemAccentColor}" Margin="3" Command="{Binding DownvoteCommand}">👎</Button>
<Button IsVisible="{Binding !IsSelectedAddonDownvoted}" Margin="3" Command="{Binding DownvoteCommand}">👎</Button>
<StackPanel.Styles>
<Style Selector="Button:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{Binding $parent[Button].Foreground} "/>
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</StackPanel.Styles>

<Button Command="{Binding ChangeRatingCommand}" CommandParameter="1" Name="Star1" Padding="0" FontSize="25" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="{Binding Bounds.Height, ElementName=Star1}" PointerEntered="Button_PointerEntered1" PointerExited="Button_PointerExited" Background="Transparent">☆</Button>
<Button Command="{Binding ChangeRatingCommand}" CommandParameter="2" Name="Star2" Padding="0" FontSize="25" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="{Binding Bounds.Height, ElementName=Star1}" PointerEntered="Button_PointerEntered2" PointerExited="Button_PointerExited" Background="Transparent">☆</Button>
<Button Command="{Binding ChangeRatingCommand}" CommandParameter="3" Name="Star3" Padding="0" FontSize="25" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="{Binding Bounds.Height, ElementName=Star1}" PointerEntered="Button_PointerEntered3" PointerExited="Button_PointerExited" Background="Transparent">☆</Button>
<Button Command="{Binding ChangeRatingCommand}" CommandParameter="4" Name="Star4" Padding="0" FontSize="25" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="{Binding Bounds.Height, ElementName=Star1}" PointerEntered="Button_PointerEntered4" PointerExited="Button_PointerExited" Background="Transparent">☆</Button>
<Button Command="{Binding ChangeRatingCommand}" CommandParameter="5" Name="Star5" Padding="0" FontSize="25" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="{Binding Bounds.Height, ElementName=Star1}" PointerEntered="Button_PointerEntered5" PointerExited="Button_PointerExited" Background="Transparent">☆</Button>

</StackPanel>

</StackPanel>

Expand Down
Loading

0 comments on commit b24af26

Please sign in to comment.