School Commit Init
@@ -0,0 +1,14 @@
|
||||
<?xml version = "1.0" encoding = "UTF-8" ?>
|
||||
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:TechTitans"
|
||||
x:Class="TechTitans.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
|
||||
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace TechTitans
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
MainPage = new AppShell();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<Shell
|
||||
x:Class="TechTitans.AppShell"
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:TechTitans"
|
||||
Shell.FlyoutBehavior="Disabled"
|
||||
Title="TechTitans">
|
||||
|
||||
<ShellContent
|
||||
Title="Home"
|
||||
ContentTemplate="{DataTemplate local:Views.MainPage}"
|
||||
Route="MainPage" />
|
||||
|
||||
</Shell>
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace TechTitans
|
||||
{
|
||||
public partial class AppShell : Shell
|
||||
{
|
||||
public AppShell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace TechTitans.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// 1. Has listened to a lot of songs
|
||||
/// 2. Has listened to a lot of new genres
|
||||
/// 3. Has not listened to very few songs
|
||||
/// 4. None of the above
|
||||
/// </summary>
|
||||
public enum ListenerPersonality
|
||||
{
|
||||
Melophile,
|
||||
Explorer,
|
||||
Casual,
|
||||
Vanilla,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace TechTitans.Enums
|
||||
{
|
||||
public enum PlaybackEventType
|
||||
{
|
||||
like = 1,
|
||||
start_play = 2,
|
||||
end_play = 3,
|
||||
dislike = 4,
|
||||
skip = 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TechTitans.Repositories;
|
||||
using System.Reflection;
|
||||
using CommunityToolkit.Maui;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
public static class MauiProgram
|
||||
{
|
||||
public static IConfiguration Configuration { get; private set; }
|
||||
public static MauiApp CreateMauiApp()
|
||||
{
|
||||
var builder = MauiApp.CreateBuilder();
|
||||
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
|
||||
builder
|
||||
.UseMauiApp<App>()
|
||||
.UseMauiCommunityToolkit()
|
||||
.ConfigureFonts(fonts =>
|
||||
{
|
||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
||||
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
|
||||
});
|
||||
|
||||
#if DEBUG
|
||||
builder.Logging.AddDebug();
|
||||
#endif
|
||||
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("TechTitans.appsettings.json");
|
||||
builder.Configuration.AddJsonStream(stream).Build();
|
||||
var app = builder.Build();
|
||||
Configuration = app.Services.GetService<IConfiguration>();
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("AdDistributionData")]
|
||||
public class AdDistributionData
|
||||
{
|
||||
[Key]
|
||||
[Column("song_id")]
|
||||
public int Song_Id { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("ad_campaign")]
|
||||
public int Ad_Campaign { get; set; }
|
||||
|
||||
[Column("genre")]
|
||||
public string Genre { get; set; }
|
||||
|
||||
[Column("language")]
|
||||
public string Language { get; set; }
|
||||
|
||||
[Column("month")]
|
||||
public int Month { get; set; }
|
||||
|
||||
[Column("year")]
|
||||
public int Year { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("AuthorDetails")]
|
||||
public class AuthorDetails
|
||||
{
|
||||
[Key]
|
||||
[Column("artist_id")]
|
||||
public int Artist_Id { get; set; } = 0;
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; } = "DefaultName";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
public class FullDetailsOnSong {
|
||||
public int TotalMinutesListened { get; set; }
|
||||
public int TotalPlays { get; set; }
|
||||
public int TotalLikes { get; set; }
|
||||
public int TotalDislikes { get; set; }
|
||||
public int TotalSkips { get; set; }
|
||||
public FullDetailsOnSong() {
|
||||
TotalMinutesListened = 0;
|
||||
TotalPlays = 0;
|
||||
TotalLikes = 0;
|
||||
TotalDislikes = 0;
|
||||
TotalSkips = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
internal class MostPlayedArtistInfo
|
||||
{
|
||||
[Column("artist_id")]
|
||||
public int Artist_Id { get; set; }
|
||||
|
||||
[Column("start_listen_events")]
|
||||
public int Start_Listen_Events { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table ("SongBasicDetails")]
|
||||
public class SongBasicDetails
|
||||
{
|
||||
[Key]
|
||||
[Column("song_id")]
|
||||
public int Song_Id { get; set; } = 0;
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; } = "DefaultName";
|
||||
|
||||
[Column("genre")]
|
||||
public string Genre { get; set; } = "DefaultGenre";
|
||||
|
||||
[Column("subgenre")]
|
||||
public string Subgenre { get; set; } = "DefaultSubgenre";
|
||||
|
||||
[Column("artist_id")]
|
||||
public int Artist_Id { get; set; } = 0;
|
||||
|
||||
[Column("language")]
|
||||
public string Language { get; set; } = "DefaultLanguage";
|
||||
|
||||
[Column("country")]
|
||||
public string Country { get; set; } = "DefaultCountry";
|
||||
|
||||
[Column("album")]
|
||||
public string Album { get; set; } = "DefaultAlbum";
|
||||
|
||||
[Column("image")]
|
||||
public string Image { get; set; } = "song_img_default.png";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
public class SongBasicInfo
|
||||
{
|
||||
public int SongId { get; set; } = 0;
|
||||
public string Name { get; set; } = "DefaultName";
|
||||
public string Genre { get; set; } = "DefaultGenre";
|
||||
public string Subgenre { get; set; } = "DefaultSubgenre";
|
||||
public string Artist { get; set; } = "DefaultArtist";
|
||||
public IList<string> Features { get; set; } = new List<string>();
|
||||
public string Language { get; set; } = "DefaultLanguage";
|
||||
public string Country { get; set; } = "DefaultCountry";
|
||||
public string Album { get; set; } = "DefaultAlbum";
|
||||
public string Image { get; set; } = "song_img_default.png";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("SongFeatures")]
|
||||
public class SongFeatures
|
||||
{
|
||||
[Key]
|
||||
[Column("song_id")]
|
||||
public int Song_Id { get; set; }
|
||||
[Key]
|
||||
[Column("artist_id")]
|
||||
public int Artist_Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("SongRecommendationDetails")]
|
||||
public class SongRecommendationDetails
|
||||
{
|
||||
[Key]
|
||||
[Column("song_id")]
|
||||
public int Song_Id { get; set; } = 0;
|
||||
|
||||
[Column("likes")]
|
||||
public int Likes { get; set; } = 0;
|
||||
|
||||
[Column("dislikes")]
|
||||
public int Dislikes { get; set; } = 0;
|
||||
|
||||
[Column("minutes_listened")]
|
||||
public int Minutes_Listened { get; set; } = 0;
|
||||
|
||||
[Column("number_of_plays")]
|
||||
public int Number_Of_Plays { get; set; } = 0;
|
||||
|
||||
[Key]
|
||||
[Column("month")]
|
||||
public int Month { get; set; } = 0;
|
||||
|
||||
[Key]
|
||||
[Column("year")]
|
||||
public int Year { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("Test")]
|
||||
public class Test
|
||||
{
|
||||
[Key]
|
||||
[Column("Id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("Name")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("Trends")]
|
||||
public class Trends
|
||||
{
|
||||
[Key]
|
||||
[Column("genre")]
|
||||
public string Genre { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("language")]
|
||||
public string Language { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("country")]
|
||||
public string Country { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("song_id")]
|
||||
public int Song_Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("UserDemographicsDetails")]
|
||||
public class UserDemographicsDetails
|
||||
{
|
||||
[Key]
|
||||
[Column("user_id")]
|
||||
public int User_Id { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("gender")]
|
||||
public int Gender { get; set; }
|
||||
|
||||
[Column("date_of_birth")]
|
||||
public DateTime Date_Of_fBirth { get; set; }
|
||||
|
||||
[Column("country")]
|
||||
public string Country { get; set; }
|
||||
|
||||
[Column("language")]
|
||||
public string Language { get; set; }
|
||||
|
||||
[Column("race")]
|
||||
public string Race { get; set; }
|
||||
|
||||
[Column("premium_user")]
|
||||
public bool Premium_User { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Enums;
|
||||
|
||||
namespace TechTitans.Models
|
||||
{
|
||||
[Table("UserPlaybackBehaviour")]
|
||||
public class UserPlaybackBehaviour
|
||||
{
|
||||
[Key]
|
||||
[Column("user_id")]
|
||||
public int User_Id { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("song_id")]
|
||||
public int Song_Id { get; set; }
|
||||
|
||||
[Column("event_type")]
|
||||
public PlaybackEventType Event_Type { get; set; }
|
||||
|
||||
[Key]
|
||||
[Column("timestamp")]
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
||||
@@ -0,0 +1,11 @@
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
|
||||
public class MainActivity : MauiAppCompatActivity
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Android.App;
|
||||
using Android.Runtime;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
[Application]
|
||||
public class MainApplication : MauiApplication
|
||||
{
|
||||
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
|
||||
: base(handle, ownership)
|
||||
{
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#512BD4</color>
|
||||
<color name="colorPrimaryDark">#2B0B98</color>
|
||||
<color name="colorAccent">#2B0B98</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,10 @@
|
||||
using Foundation;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
|
||||
<dict>
|
||||
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- The Mac App Store requires you specify if the app uses encryption. -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
|
||||
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
|
||||
<!-- Please indicate <true/> or <false/> here. -->
|
||||
|
||||
<!-- Specify the category for your app here. -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
|
||||
<!-- <key>LSApplicationCategoryType</key> -->
|
||||
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,16 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Microsoft.Maui;
|
||||
using Microsoft.Maui.Hosting;
|
||||
using System;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
internal class Program : MauiApplication
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var app = new Program();
|
||||
app.Run(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="maui-application-id-placeholder" version="0.0.0" api-version="8" xmlns="http://tizen.org/ns/packages">
|
||||
<profile name="common" />
|
||||
<ui-application appid="maui-application-id-placeholder" exec="TechTitans.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
|
||||
<label>maui-application-title-placeholder</label>
|
||||
<icon>maui-appicon-placeholder</icon>
|
||||
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
|
||||
</ui-application>
|
||||
<shortcut-list />
|
||||
<privileges>
|
||||
<privilege>http://tizen.org/privilege/internet</privilege>
|
||||
</privileges>
|
||||
<dependencies />
|
||||
<provides-appdefined-privileges />
|
||||
</manifest>
|
||||
@@ -0,0 +1,8 @@
|
||||
<maui:MauiWinUIApplication
|
||||
x:Class="TechTitans.WinUI.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:maui="using:Microsoft.Maui"
|
||||
xmlns:local="using:TechTitans.WinUI">
|
||||
|
||||
</maui:MauiWinUIApplication>
|
||||
@@ -0,0 +1,25 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace TechTitans.WinUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
public partial class App : MauiWinUIApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
IgnorableNamespaces="uap rescap">
|
||||
|
||||
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="FAC290BF-77C6-481F-91A5-8737B04E06C7" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>$placeholder$</DisplayName>
|
||||
<PublisherDisplayName>User Name</PublisherDisplayName>
|
||||
<Logo>$placeholder$.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
|
||||
<uap:VisualElements
|
||||
DisplayName="$placeholder$"
|
||||
Description="$placeholder$"
|
||||
Square150x150Logo="$placeholder$.png"
|
||||
Square44x44Logo="$placeholder$.png"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Square71x71Logo="$placeholder$.png" Wide310x150Logo="$placeholder$.png" Square310x310Logo="$placeholder$.png" />
|
||||
<uap:SplashScreen Image="$placeholder$.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
</Capabilities>
|
||||
|
||||
</Package>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="TechTitans.WinUI.app"/>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<!-- The combination of below two tags have the following effect:
|
||||
1) Per-Monitor for >= Windows 10 Anniversary Update
|
||||
2) System < Windows 10 Anniversary Update
|
||||
-->
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
@@ -0,0 +1,10 @@
|
||||
using Foundation;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,16 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace TechTitans
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Windows Machine": {
|
||||
"commandName": "MsixPackage",
|
||||
"nativeDebugging": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Repositories
|
||||
{
|
||||
public interface IRepository<T>
|
||||
{
|
||||
T GetById(int id);
|
||||
IEnumerable<T> GetAll();
|
||||
bool Add(T entity);
|
||||
bool Update(T entity);
|
||||
bool Delete(T entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
using static Dapper.SqlMapper;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace TechTitans.Repositories
|
||||
{
|
||||
public class Repository<T> : IRepository<T> where T : class
|
||||
{
|
||||
public IDbConnection _connection;
|
||||
private readonly IConfiguration _configuration = MauiProgram.Configuration;
|
||||
|
||||
public Repository()
|
||||
{
|
||||
|
||||
_connection = new Microsoft.Data.SqlClient.SqlConnection(_configuration.GetConnectionString("TechTitansDev"));
|
||||
}
|
||||
|
||||
public bool Add(T entity)
|
||||
{
|
||||
int rowsEffected = 0;
|
||||
try
|
||||
{
|
||||
string tableName = GetTableName();
|
||||
string columns = GetColumns(excludeKey: true);
|
||||
string properties = GetPropertyNames(excludeKey: true);
|
||||
string query = $"INSERT INTO {tableName} ({columns}) VALUES ({properties})";
|
||||
|
||||
rowsEffected = _connection.Execute(query, entity);
|
||||
}
|
||||
catch (Exception ex) { }
|
||||
|
||||
return rowsEffected > 0 ? true : false;
|
||||
}
|
||||
|
||||
public bool Delete(T entity)
|
||||
{
|
||||
int rowsEffected = 0;
|
||||
try
|
||||
{
|
||||
string tableName = GetTableName();
|
||||
string keyColumn = GetKeyColumnName();
|
||||
string keyProperty = GetKeyPropertyName();
|
||||
string query = $"DELETE FROM {tableName} WHERE {keyColumn} = @{keyProperty}";
|
||||
|
||||
rowsEffected = _connection.Execute(query, entity);
|
||||
}
|
||||
catch (Exception ex) { }
|
||||
|
||||
return rowsEffected > 0 ? true : false;
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetAll()
|
||||
{
|
||||
IEnumerable<T> result = null;
|
||||
try
|
||||
{
|
||||
string tableName = GetTableName();
|
||||
string query = $"SELECT * FROM {tableName}";
|
||||
|
||||
result = _connection.Query<T>(query);
|
||||
}
|
||||
catch (Exception ex) { }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public T GetById(int Id)
|
||||
{
|
||||
IEnumerable<T> result = null;
|
||||
try
|
||||
{
|
||||
string tableName = GetTableName();
|
||||
string keyColumn = GetKeyColumnName();
|
||||
string query = $"SELECT * FROM {tableName} WHERE {keyColumn} = '{Id}'";
|
||||
|
||||
result = _connection.Query<T>(query);
|
||||
}
|
||||
catch (Exception ex) { }
|
||||
|
||||
return result.FirstOrDefault();
|
||||
}
|
||||
|
||||
public bool Update(T entity)
|
||||
{
|
||||
int rowsEffected = 0;
|
||||
try
|
||||
{
|
||||
string tableName = GetTableName();
|
||||
string keyColumn = GetKeyColumnName();
|
||||
string keyProperty = GetKeyPropertyName();
|
||||
|
||||
StringBuilder query = new StringBuilder();
|
||||
query.Append($"UPDATE {tableName} SET ");
|
||||
|
||||
foreach (var property in GetProperties(true))
|
||||
{
|
||||
var columnAttr = property.GetCustomAttribute<ColumnAttribute>();
|
||||
|
||||
string propertyName = property.Name;
|
||||
string columnName = columnAttr.Name;
|
||||
|
||||
query.Append($"{columnName} = @{propertyName},");
|
||||
}
|
||||
|
||||
query.Remove(query.Length - 1, 1);
|
||||
|
||||
query.Append($" WHERE {keyColumn} = @{keyProperty}");
|
||||
|
||||
rowsEffected = _connection.Execute(query.ToString(), entity);
|
||||
}
|
||||
catch (Exception ex) { }
|
||||
|
||||
return rowsEffected > 0 ? true : false;
|
||||
}
|
||||
|
||||
private string GetTableName()
|
||||
{
|
||||
string tableName = "";
|
||||
var type = typeof(T);
|
||||
var tableAttr = type.GetCustomAttribute<TableAttribute>();
|
||||
if (tableAttr != null)
|
||||
{
|
||||
tableName = tableAttr.Name;
|
||||
return tableName;
|
||||
}
|
||||
|
||||
return type.Name + "s";
|
||||
}
|
||||
|
||||
public static string GetKeyColumnName()
|
||||
{
|
||||
PropertyInfo[] properties = typeof(T).GetProperties();
|
||||
|
||||
foreach (PropertyInfo property in properties)
|
||||
{
|
||||
object[] keyAttributes = property.GetCustomAttributes(typeof(KeyAttribute), true);
|
||||
|
||||
if (keyAttributes != null && keyAttributes.Length > 0)
|
||||
{
|
||||
object[] columnAttributes = property.GetCustomAttributes(typeof(ColumnAttribute), true);
|
||||
|
||||
if (columnAttributes != null && columnAttributes.Length > 0)
|
||||
{
|
||||
ColumnAttribute columnAttribute = (ColumnAttribute)columnAttributes[0];
|
||||
return columnAttribute.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return property.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private string GetColumns(bool excludeKey = false)
|
||||
{
|
||||
var type = typeof(T);
|
||||
var columns = string.Join(", ", type.GetProperties()
|
||||
.Where(p => !excludeKey || !p.IsDefined(typeof(KeyAttribute)))
|
||||
.Select(p =>
|
||||
{
|
||||
var columnAttr = p.GetCustomAttribute<ColumnAttribute>();
|
||||
return columnAttr != null ? columnAttr.Name : p.Name;
|
||||
}));
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
protected string GetPropertyNames(bool excludeKey = false)
|
||||
{
|
||||
var properties = typeof(T).GetProperties()
|
||||
.Where(p => !excludeKey || p.GetCustomAttribute<KeyAttribute>() == null);
|
||||
|
||||
var values = string.Join(", ", properties.Select(p =>
|
||||
{
|
||||
return $"@{p.Name}";
|
||||
}));
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
protected IEnumerable<PropertyInfo> GetProperties(bool excludeKey = false)
|
||||
{
|
||||
var properties = typeof(T).GetProperties()
|
||||
.Where(p => !excludeKey || p.GetCustomAttribute<KeyAttribute>() == null);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
protected string GetKeyPropertyName()
|
||||
{
|
||||
var properties = typeof(T).GetProperties()
|
||||
.Where(p => p.GetCustomAttribute<KeyAttribute>() != null);
|
||||
|
||||
if (properties.Any())
|
||||
{
|
||||
return properties.FirstOrDefault().Name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using Dapper;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Models;
|
||||
|
||||
namespace TechTitans.Repositories
|
||||
{
|
||||
internal class SongBasicDetailsRepository : Repository<SongBasicDetails>
|
||||
{
|
||||
public SongBasicInfo SongBasicDetailsToSongBasicInfo(SongBasicDetails songBasicDetails)
|
||||
{
|
||||
var artistId = songBasicDetails.Artist_Id;
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT name FROM AuthorDetails WHERE artist_id = @artistId");
|
||||
var artistName = _connection.Query<string>(cmd.ToString(), new { artistId }).FirstOrDefault();
|
||||
return new SongBasicInfo
|
||||
{
|
||||
SongId = songBasicDetails.Song_Id,
|
||||
Name = songBasicDetails.Name,
|
||||
Genre = songBasicDetails.Genre,
|
||||
Subgenre = songBasicDetails.Subgenre,
|
||||
Artist = artistName,
|
||||
Language = songBasicDetails.Language,
|
||||
Country = songBasicDetails.Country,
|
||||
Album = songBasicDetails.Album,
|
||||
Image = songBasicDetails.Image
|
||||
};
|
||||
}
|
||||
|
||||
public SongBasicDetails GetSongBasicDetails(int songId)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM SongBasicDetails WHERE song_id = @songId");
|
||||
return _connection.Query<SongBasicDetails>(cmd.ToString(), new { songId }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<SongBasicDetails> GetTop5MostListenedSongs(int userId)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM SongBasicDetails WHERE song_id IN (SELECT TOP 5 song_id FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 GROUP BY song_id ORDER BY COUNT(song_id) DESC);");
|
||||
return _connection.Query<SongBasicDetails>(cmd.ToString(), new { userId }).ToList();
|
||||
}
|
||||
|
||||
public Tuple<SongBasicDetails, decimal> GetMostPlayedSongPercentile(int userId)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM SongBasicDetails WHERE song_id IN (SELECT TOP 1 song_id FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE()) GROUP BY song_id ORDER BY COUNT(song_id) DESC);");
|
||||
var mostPlayedSong = _connection.Query<SongBasicDetails>(cmd.ToString(), new { userId }).FirstOrDefault();
|
||||
cmd.Clear();
|
||||
cmd.Append("SELECT COUNT(*) FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE());");
|
||||
var totalSongs = _connection.Query<int>(cmd.ToString(), new { userId }).FirstOrDefault();
|
||||
cmd.Clear();
|
||||
cmd.Append("SELECT COUNT(*) FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE()) AND song_id IN (SELECT TOP 1 song_id FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE()) GROUP BY song_id ORDER BY COUNT(song_id) DESC);");
|
||||
var mostListenedSongCount = _connection.Query<int>(cmd.ToString(), new { userId }).FirstOrDefault();
|
||||
return new Tuple<SongBasicDetails, decimal>(mostPlayedSong, (decimal)mostListenedSongCount / totalSongs);
|
||||
}
|
||||
|
||||
public Tuple<string, decimal> GetMostPlayedArtistPercentile(int userId)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT TOP 1 sd.artist_id as Artist_Id, COUNT(*) AS Start_Listen_Events FROM UserPlaybackBehaviour ub JOIN SongBasicDetails sd ON ub.song_id = sd.song_id WHERE ub.user_id = @userId AND ub.event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE()) GROUP BY sd.artist_id ORDER BY COUNT(*) DESC;");
|
||||
var response = _connection.Query<MostPlayedArtistInfo>(cmd.ToString(), new { userId }).FirstOrDefault();
|
||||
cmd.Clear();
|
||||
cmd.Append("SELECT name FROM AuthorDetails WHERE artist_id = @artist_Id");
|
||||
var mostPlayedArtist = _connection.Query<string>(cmd.ToString(), new { response.Artist_Id }).FirstOrDefault();
|
||||
cmd.Clear();
|
||||
cmd.Append("SELECT COUNT(*) FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE());");
|
||||
var totalSongs = _connection.Query<int>(cmd.ToString(), new { userId }).FirstOrDefault();
|
||||
cmd.Clear();
|
||||
return new Tuple<string, decimal>(mostPlayedArtist, (decimal)response.Start_Listen_Events / totalSongs);
|
||||
}
|
||||
|
||||
public List<string> GetTop5Genres(int userId)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT TOP 5 sb.genre FROM UserPlaybackBehaviour ub JOIN SongBasicDetails sb ON ub.song_id = sb.song_id WHERE ub.user_id = @userId AND ub.event_type = 2 AND YEAR(ub.timestamp) = YEAR(GETDATE()) GROUP BY sb.genre ORDER BY COUNT(*) DESC;");
|
||||
return _connection.Query<string>(cmd.ToString(), new { userId }).ToList();
|
||||
}
|
||||
|
||||
public List<string> NewGenresDiscovered(int userId)
|
||||
{
|
||||
//new genres where first song was played for the first time in the current year
|
||||
//var cmd = new StringBuilder();
|
||||
//cmd.Append("SELECT genre FROM SongBasicDetails WHERE song_id IN (SELECT song_id FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 1 AND YEAR(timestamp) = YEAR(GETDATE()) GROUP BY song_id HAVING COUNT(song_id) = 1);");
|
||||
|
||||
//select all genres that have been played in current year but not in previous year
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT DISTINCT genre FROM SongBasicDetails WHERE song_id IN (SELECT song_id FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE()) GROUP BY song_id) AND genre NOT IN (SELECT genre FROM SongBasicDetails WHERE song_id IN (SELECT song_id FROM UserPlaybackBehaviour WHERE user_id = @userId AND event_type = 2 AND YEAR(timestamp) = YEAR(GETDATE()) - 1 GROUP BY song_id));");
|
||||
return _connection.Query<string>(cmd.ToString(), new { userId }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using Dapper;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Models;
|
||||
|
||||
namespace TechTitans.Repositories
|
||||
{
|
||||
public class TestRepository : Repository<Test>
|
||||
{
|
||||
public Test TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM Test");
|
||||
return _connection.Query<Test>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestDemographicDetails : Repository<UserDemographicsDetails>
|
||||
{
|
||||
public UserDemographicsDetails TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM UserDemographicsDetails");
|
||||
return _connection.Query<UserDemographicsDetails>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestAuthorDetails : Repository<AuthorDetails>
|
||||
{
|
||||
public AuthorDetails TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM AuthorDetails");
|
||||
// return _connection.Query<Test>(cmd.ToString()).FirstOrDefault();
|
||||
return _connection.Query<AuthorDetails>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestAdDistributionData : Repository<AdDistributionData>
|
||||
{
|
||||
public AdDistributionData TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM AdDistributionData");
|
||||
return _connection.Query<AdDistributionData>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestSongBasicDetails : Repository<SongBasicDetails>
|
||||
{
|
||||
public SongBasicDetails TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM SongBasicDetails");
|
||||
return _connection.Query<SongBasicDetails>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestUserPlaybackBehaviour : Repository<UserPlaybackBehaviour>
|
||||
{
|
||||
public UserPlaybackBehaviour TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM UserPlaybackBehaviour");
|
||||
return _connection.Query<UserPlaybackBehaviour>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestSongRecommendationDetails : Repository<SongRecommendationDetails>
|
||||
{
|
||||
public SongRecommendationDetails TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM SongRecommendationDetails");
|
||||
return _connection.Query<SongRecommendationDetails>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestSongFeatures : Repository<SongFeatures>
|
||||
{
|
||||
public SongFeatures TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM SongFeatures");
|
||||
return _connection.Query<SongFeatures>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class TestTrends : Repository<Trends>
|
||||
{
|
||||
public Trends TestMethod()
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM Trends");
|
||||
return _connection.Query<Trends>(cmd.ToString()).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Dapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Models;
|
||||
|
||||
namespace TechTitans.Repositories
|
||||
{
|
||||
internal class UserPlaybackBehaviourRepository : Repository<UserPlaybackBehaviour>
|
||||
{
|
||||
public UserPlaybackBehaviour GetUserPlaybackBehaviour(int userId, int songId, DateTime timestamp)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM UserPlaybackBehaviour WHERE user_id = @userId AND song_id = @songId AND timestamp = @timestamp");
|
||||
return _connection.Query<UserPlaybackBehaviour>(cmd.ToString(), new { userId, songId, timestamp }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public List<UserPlaybackBehaviour> GetUserPlaybackBehaviour(int userId, int songId)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT * FROM UserPlaybackBehaviour WHERE user_id = @userId AND song_id = @songId");
|
||||
return _connection.Query<UserPlaybackBehaviour>(cmd.ToString(), new { userId, songId }).ToList();
|
||||
}
|
||||
|
||||
public List<UserPlaybackBehaviour> GetUserPlaybackBehaviour(int userId)
|
||||
{
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT user_id as User_Id, song_id as Song_Id, event_type as Event_Type, timestamp as Timestamp FROM UserPlaybackBehaviour WHERE user_id = @userId");
|
||||
return _connection.Query<UserPlaybackBehaviour>(cmd.ToString(), new { userId }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Repositories;
|
||||
using TechTitans.Models;
|
||||
using Dapper;
|
||||
|
||||
namespace TechTitans.Repositories
|
||||
{
|
||||
internal class UserRepository : Repository<SongBasicDetails>
|
||||
{
|
||||
public SongBasicInfo SongBasicDetailsToSongBasicInfo(SongBasicDetails songBasicDetails)
|
||||
{
|
||||
var artistId = songBasicDetails.Artist_Id;
|
||||
var cmd = new StringBuilder();
|
||||
cmd.Append("SELECT name FROM AuthorDetails WHERE artist_id = @artistId");
|
||||
var artistName = _connection.Query<string>(cmd.ToString(), new { artistId }).FirstOrDefault();
|
||||
return new SongBasicInfo
|
||||
{
|
||||
SongId = songBasicDetails.Song_Id,
|
||||
Name = songBasicDetails.Name,
|
||||
Genre = songBasicDetails.Genre,
|
||||
Subgenre = songBasicDetails.Subgenre,
|
||||
Artist = artistName,
|
||||
Language = songBasicDetails.Language,
|
||||
Country = songBasicDetails.Country,
|
||||
Album = songBasicDetails.Album,
|
||||
Image = songBasicDetails.Image
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="456" height="456" fill="#512BD4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 228 B |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 643 KiB |
|
After Width: | Height: | Size: 935 KiB |
|
After Width: | Height: | Size: 396 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="7.5 7.5 50 62.5" enable-background="new 7.5 7.5 50 50" xml:space="preserve"><path fill="#AA0000" d="M32.5,20.083c-13.418,0-24.334,10.916-24.334,24.334c0,0.276,0.224,0.5,0.5,0.5h47.668c0.276,0,0.5-0.224,0.5-0.5 C56.834,30.999,45.918,20.083,32.5,20.083z"/></svg>
|
||||
|
After Width: | Height: | Size: 383 B |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,15 @@
|
||||
Any raw assets you want to be deployed with your application can be placed in
|
||||
this directory (and child directories). Deployment of the asset to your application
|
||||
is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
|
||||
|
||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
|
||||
These files will be deployed with you package and will be accessible using Essentials:
|
||||
|
||||
async Task LoadMauiAsset()
|
||||
{
|
||||
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
|
||||
using var reader = new StreamReader(stream);
|
||||
|
||||
var contents = reader.ReadToEnd();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z" style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xaml-comp compile="true" ?>
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
|
||||
|
||||
<!-- Note: For Android please see also Platforms\Android\Resources\values\colors.xml -->
|
||||
|
||||
<Color x:Key="Primary">#512BD4</Color>
|
||||
<Color x:Key="PrimaryDark">#ac99ea</Color>
|
||||
<Color x:Key="PrimaryDarkText">#242424</Color>
|
||||
<Color x:Key="Secondary">#DFD8F7</Color>
|
||||
<Color x:Key="SecondaryDarkText">#9880e5</Color>
|
||||
<Color x:Key="Tertiary">#2B0B98</Color>
|
||||
|
||||
<Color x:Key="White">White</Color>
|
||||
<Color x:Key="Black">Black</Color>
|
||||
<Color x:Key="Magenta">#D600AA</Color>
|
||||
<Color x:Key="MidnightBlue">#190649</Color>
|
||||
<Color x:Key="OffBlack">#1f1f1f</Color>
|
||||
|
||||
<Color x:Key="Gray100">#E1E1E1</Color>
|
||||
<Color x:Key="Gray200">#C8C8C8</Color>
|
||||
<Color x:Key="Gray300">#ACACAC</Color>
|
||||
<Color x:Key="Gray400">#919191</Color>
|
||||
<Color x:Key="Gray500">#6E6E6E</Color>
|
||||
<Color x:Key="Gray600">#404040</Color>
|
||||
<Color x:Key="Gray900">#212121</Color>
|
||||
<Color x:Key="Gray950">#141414</Color>
|
||||
|
||||
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}"/>
|
||||
<SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource Secondary}"/>
|
||||
<SolidColorBrush x:Key="TertiaryBrush" Color="{StaticResource Tertiary}"/>
|
||||
<SolidColorBrush x:Key="WhiteBrush" Color="{StaticResource White}"/>
|
||||
<SolidColorBrush x:Key="BlackBrush" Color="{StaticResource Black}"/>
|
||||
|
||||
<SolidColorBrush x:Key="Gray100Brush" Color="{StaticResource Gray100}"/>
|
||||
<SolidColorBrush x:Key="Gray200Brush" Color="{StaticResource Gray200}"/>
|
||||
<SolidColorBrush x:Key="Gray300Brush" Color="{StaticResource Gray300}"/>
|
||||
<SolidColorBrush x:Key="Gray400Brush" Color="{StaticResource Gray400}"/>
|
||||
<SolidColorBrush x:Key="Gray500Brush" Color="{StaticResource Gray500}"/>
|
||||
<SolidColorBrush x:Key="Gray600Brush" Color="{StaticResource Gray600}"/>
|
||||
<SolidColorBrush x:Key="Gray900Brush" Color="{StaticResource Gray900}"/>
|
||||
<SolidColorBrush x:Key="Gray950Brush" Color="{StaticResource Gray950}"/>
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,453 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xaml-comp compile="true" ?>
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
|
||||
|
||||
<Style TargetType="ActivityIndicator">
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="IndicatorView">
|
||||
<Setter Property="IndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}"/>
|
||||
<Setter Property="SelectedIndicatorColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray100}}"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Stroke" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="StrokeShape" Value="Rectangle"/>
|
||||
<Setter Property="StrokeThickness" Value="1"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="BoxView">
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource PrimaryDarkText}}" />
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="BorderWidth" Value="0"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="14,10"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="DatePicker">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Editor">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Entry">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Frame">
|
||||
<Setter Property="HasShadow" Value="False" />
|
||||
<Setter Property="BorderColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="CornerRadius" Value="8" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ImageButton">
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
<Setter Property="BorderColor" Value="Transparent"/>
|
||||
<Setter Property="BorderWidth" Value="0"/>
|
||||
<Setter Property="CornerRadius" Value="0"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Span">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label" x:Key="Headline">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontSize" Value="32" />
|
||||
<Setter Property="HorizontalOptions" Value="Center" />
|
||||
<Setter Property="HorizontalTextAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label" x:Key="SubHeadline">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontSize" Value="24" />
|
||||
<Setter Property="HorizontalOptions" Value="Center" />
|
||||
<Setter Property="HorizontalTextAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ListView">
|
||||
<Setter Property="SeparatorColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="RefreshControlColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Picker">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="TitleColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ProgressBar">
|
||||
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="ProgressColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="RadioButton">
|
||||
<Setter Property="BackgroundColor" Value="Transparent"/>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="RefreshView">
|
||||
<Setter Property="RefreshColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SearchBar">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="CancelButtonColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SearchHandler">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Shadow">
|
||||
<Setter Property="Radius" Value="15" />
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
<Setter Property="Brush" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Offset" Value="10,10" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Slider">
|
||||
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="MinimumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
|
||||
<Setter Property="MaximumTrackColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}"/>
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SwipeItem">
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Switch">
|
||||
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="ThumbColor" Value="{StaticResource White}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="On">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="OnColor" Value="{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Off">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="ThumbColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TimePicker">
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent"/>
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="MinimumHeightRequest" Value="44"/>
|
||||
<Setter Property="MinimumWidthRequest" Value="44"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Page" ApplyToDerivedTypes="True">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Shell" ApplyToDerivedTypes="True">
|
||||
<Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
<Setter Property="Shell.ForegroundColor" Value="{OnPlatform WinUI={StaticResource Primary}, Default={StaticResource White}}" />
|
||||
<Setter Property="Shell.TitleColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
|
||||
<Setter Property="Shell.DisabledColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="Shell.UnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="Shell.NavBarHasShadow" Value="False" />
|
||||
<Setter Property="Shell.TabBarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
<Setter Property="Shell.TabBarForegroundColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Shell.TabBarTitleColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Shell.TabBarUnselectedColor" Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="NavigationPage">
|
||||
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
|
||||
<Setter Property="IconColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TabbedPage">
|
||||
<Setter Property="BarBackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="BarTextColor" Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="UnselectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="SelectedTabColor" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="TabNavButton" TargetType="Button">
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="TextColor" Value="White" />
|
||||
<Setter Property="FontSize" Value="18" />
|
||||
<Setter Property="CornerRadius" Value="3"/>
|
||||
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="ButtonStates">
|
||||
<VisualState x:Name="Pressed">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="BackgroundColor" Value="LightGray" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Normal">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,40 @@
|
||||
-- connect to the database SongBasicDetails
|
||||
insert into AuthorDetails values(1, 'Dumiyei')
|
||||
insert into AuthorDetails values(2, 'Dobu')
|
||||
insert into AuthorDetails values(3, 'Danilica')
|
||||
insert into AuthorDetails values(4, 'Iediy')
|
||||
insert into AuthorDetails values(5, 'Dyanana')
|
||||
insert into AuthorDetails values(6, 'Boghidy')
|
||||
insert into AuthorDetails values(7, 'MaineKraft boy')
|
||||
insert into AuthorDetails values(8, 'Tudie')
|
||||
|
||||
insert into UserDemographicsDetails values (1, 'Dumi', 'male', '2002-01-01', 'Romania', 'english', 'motherfucker', 1)
|
||||
insert into UserDemographicsDetails values (2, 'Andy', 'other', '2003-03-21', 'Nigeria', 'french', 'niggher', 0)
|
||||
|
||||
insert into SongBasicDetails VALUES
|
||||
(1, 'American Boy', 'hip-hop', 'chicago', 7, 'english', 'USA', '-', 'http://plm.com');
|
||||
|
||||
insert into Trends VALUES
|
||||
('hip-hop', 'english', 'USA', 1)
|
||||
|
||||
insert into AdDistributionData VALUES
|
||||
(1, 1, 'hip-hop', 'english', 10, 2023)
|
||||
|
||||
insert into UserPlaybackBehaviour VALUES
|
||||
(1, 1, 1, '2023-12-12 7:25:45')
|
||||
|
||||
insert into SongRecommendationDetails VALUES
|
||||
(1, 15, 4, 1503, 23, 10, 2023)
|
||||
|
||||
insert into SongFeatures values
|
||||
(1, 2)
|
||||
select * from UserPlaybackBehaviour
|
||||
|
||||
--UserDemographicsDetails
|
||||
--AuthorDetails
|
||||
--SongBasicDetails
|
||||
--Trends
|
||||
--AdDistributionData
|
||||
--UserPlaybackBehaviour
|
||||
--SongRecommendationDetails
|
||||
--SongFeatures
|
||||
@@ -0,0 +1,172 @@
|
||||
using TechTitans.Models;
|
||||
using TechTitans.Repositories;
|
||||
|
||||
namespace TechTitans.Services
|
||||
{
|
||||
public class ArtistSongDashboardController
|
||||
{
|
||||
private Repository<SongBasicDetails> SongRepo = new Repository<SongBasicDetails>();
|
||||
private Repository<SongFeatures> FeatureRepo = new Repository<SongFeatures>();
|
||||
private Repository<SongRecommendationDetails> SongRecommendationRepo = new Repository<SongRecommendationDetails>();
|
||||
private Repository<AuthorDetails> ArtistRepo = new Repository<AuthorDetails>();
|
||||
|
||||
|
||||
//converts song details to song info
|
||||
public SongBasicInfo songBasicDetailsToInfo(SongBasicDetails song)
|
||||
{
|
||||
SongBasicInfo songInfo = new SongBasicInfo();
|
||||
songInfo.SongId = song.Song_Id;
|
||||
songInfo.Name = song.Name;
|
||||
songInfo.Genre = song.Genre;
|
||||
songInfo.Subgenre = song.Subgenre;
|
||||
songInfo.Language = song.Language;
|
||||
songInfo.Country = song.Country;
|
||||
songInfo.Album = song.Album;
|
||||
songInfo.Image = song.Image;
|
||||
foreach (AuthorDetails artist in ArtistRepo.GetAll())
|
||||
{
|
||||
if (artist.Artist_Id == song.Artist_Id)
|
||||
{
|
||||
songInfo.Artist = artist.Name;
|
||||
}
|
||||
}
|
||||
foreach (SongFeatures feature in FeatureRepo.GetAll())
|
||||
{
|
||||
if (feature.Song_Id == song.Song_Id)
|
||||
{
|
||||
songInfo.Features.Add(feature.ToString());
|
||||
}
|
||||
}
|
||||
return songInfo;
|
||||
}
|
||||
|
||||
|
||||
//get all artist's publish song (returns List<Entity>)
|
||||
public List<SongBasicInfo> getAllArtistSongs(int artistId)
|
||||
{
|
||||
List<SongBasicInfo> artistSongs = new List<SongBasicInfo>();
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll())
|
||||
{
|
||||
if (song.Artist_Id == artistId)
|
||||
{
|
||||
SongBasicInfo songInfo = songBasicDetailsToInfo(song);
|
||||
artistSongs.Add(songInfo);
|
||||
}
|
||||
}
|
||||
return artistSongs;
|
||||
}
|
||||
|
||||
//search by string in titles (returns list of songs, case insensitive)
|
||||
|
||||
public List<SongBasicInfo> searchByTitle(string title)
|
||||
{
|
||||
List<SongBasicInfo> songs = new List<SongBasicInfo>();
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll())
|
||||
{
|
||||
if (song.Name.ToLower().Trim().Contains(title.ToLower()))
|
||||
{
|
||||
SongBasicInfo songInfo = songBasicDetailsToInfo(song);
|
||||
songs.Add(songInfo);
|
||||
}
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
|
||||
|
||||
//gets song info by song id
|
||||
public SongBasicInfo getSongInfo(int songId)
|
||||
{
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll())
|
||||
{
|
||||
if (song.Song_Id == songId)
|
||||
{
|
||||
SongBasicInfo songInfo = songBasicDetailsToInfo(song);
|
||||
return songInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//gets song recommendation details by song id
|
||||
public SongRecommendationDetails getSongDetails(int songId)
|
||||
{
|
||||
foreach (SongRecommendationDetails songDetails in SongRecommendationRepo.GetAll())
|
||||
{
|
||||
if (songDetails.Song_Id == songId)
|
||||
{
|
||||
return songDetails;
|
||||
}
|
||||
}
|
||||
|
||||
return new SongRecommendationDetails();
|
||||
|
||||
}
|
||||
|
||||
//gets artist info by song id
|
||||
public AuthorDetails getArtistInfo(int SongId)
|
||||
{
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll())
|
||||
{
|
||||
if (song.Song_Id == SongId)
|
||||
{
|
||||
foreach (AuthorDetails artist in ArtistRepo.GetAll())
|
||||
{
|
||||
if (artist.Artist_Id == song.Artist_Id)
|
||||
{
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AuthorDetails getMostPublishedAuthor()
|
||||
{
|
||||
Dictionary<int, int> artistCount = new Dictionary<int, int>();
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll())
|
||||
{
|
||||
if (artistCount.ContainsKey(song.Artist_Id))
|
||||
{
|
||||
artistCount[song.Artist_Id]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
artistCount.Add(song.Artist_Id, 1);
|
||||
}
|
||||
}
|
||||
int max = 0;
|
||||
int artistId = 0;
|
||||
foreach (KeyValuePair<int, int> entry in artistCount)
|
||||
{
|
||||
if (entry.Value > max)
|
||||
{
|
||||
max = entry.Value;
|
||||
artistId = entry.Key;
|
||||
}
|
||||
}
|
||||
foreach (AuthorDetails artist in ArtistRepo.GetAll())
|
||||
{
|
||||
if (artist.Artist_Id == artistId)
|
||||
{
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public List<SongBasicInfo> getSongsForMainPage()
|
||||
{
|
||||
List<SongBasicInfo> songs = new List<SongBasicInfo>();
|
||||
int artistId = getMostPublishedAuthor().Artist_Id;
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll())
|
||||
{
|
||||
if (song.Artist_Id == artistId)
|
||||
{
|
||||
SongBasicInfo songInfo = songBasicDetailsToInfo(song);
|
||||
songs.Add(songInfo);
|
||||
}
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
//using System.Windows.Forms;
|
||||
using TechTitans.Models;
|
||||
using TechTitans.Repositories;
|
||||
using TechTitans.Enums;
|
||||
|
||||
namespace TechTitans.Services
|
||||
{
|
||||
internal class FullDetailsOnSongController
|
||||
{
|
||||
//private readonly Repository<SongBasicDetails> SongRepo = new();
|
||||
//private readonly Repository<SongRecommendationDetails> SongRecommendationRepo = new();
|
||||
private readonly Repository<UserPlaybackBehaviour> UserPlaybackBehaviourRepo = new();
|
||||
private readonly Repository<AdDistributionData> AdDistributionDataRepo = new();
|
||||
public FullDetailsOnSong GetFullDetailsOnSong(int songId) {
|
||||
FullDetailsOnSong currentSongDetails = new();
|
||||
DateTime start = new();
|
||||
bool found = false;
|
||||
foreach (UserPlaybackBehaviour action in UserPlaybackBehaviourRepo.GetAll()) {
|
||||
|
||||
if (action.Song_Id == songId) {
|
||||
found = true;
|
||||
// string message;
|
||||
// message = action.Event_Type.ToString() + " " + action.Timestamp.ToString() + " " + action.Song_Id.ToString() + " " + action.User_Id.ToString() + "\n";
|
||||
// MessageBox.Show(message);
|
||||
|
||||
switch (action.Event_Type) {
|
||||
case PlaybackEventType.start_play:
|
||||
start = action.Timestamp;
|
||||
break;
|
||||
case PlaybackEventType.end_play:
|
||||
int minutes = (action.Timestamp - start).Minutes;
|
||||
currentSongDetails.TotalMinutesListened += minutes;
|
||||
currentSongDetails.TotalPlays++;
|
||||
break;
|
||||
case PlaybackEventType.like:
|
||||
currentSongDetails.TotalLikes++;
|
||||
break;
|
||||
case PlaybackEventType.dislike:
|
||||
currentSongDetails.TotalDislikes++;
|
||||
break;
|
||||
case PlaybackEventType.skip:
|
||||
currentSongDetails.TotalSkips++;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// MessageBox.Show(currentSongDetails.TotalMinutesListened.ToString());
|
||||
if (!found) {
|
||||
// MessageBox.Show("Song not found");
|
||||
return null;
|
||||
}
|
||||
return currentSongDetails;
|
||||
}
|
||||
public FullDetailsOnSong GetCurrentMonthDetails(int songId) {
|
||||
FullDetailsOnSong currentSongDetails = new();
|
||||
foreach (UserPlaybackBehaviour action in UserPlaybackBehaviourRepo.GetAll()) {
|
||||
if (action.Song_Id == songId && action.Timestamp.Month == DateTime.Now.Month && action.Timestamp.Year == DateTime.Now.Year) {
|
||||
switch (action.Event_Type) {
|
||||
case PlaybackEventType.start_play:
|
||||
break;
|
||||
case PlaybackEventType.end_play:
|
||||
int minutes = (action.Timestamp - DateTime.Now).Minutes;
|
||||
currentSongDetails.TotalMinutesListened += minutes;
|
||||
currentSongDetails.TotalPlays++;
|
||||
break;
|
||||
case PlaybackEventType.like:
|
||||
currentSongDetails.TotalLikes++;
|
||||
break;
|
||||
case PlaybackEventType.dislike:
|
||||
currentSongDetails.TotalDislikes++;
|
||||
break;
|
||||
case PlaybackEventType.skip:
|
||||
currentSongDetails.TotalSkips++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return currentSongDetails;
|
||||
}
|
||||
public AdDistributionData GetActiveAd(int songId) {
|
||||
foreach (AdDistributionData ad in AdDistributionDataRepo.GetAll()) {
|
||||
if (ad.Song_Id == songId && ad.Month == DateTime.Now.Month && ad.Year == DateTime.Now.Year) {
|
||||
return ad;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Repositories;
|
||||
using TechTitans.Models;
|
||||
using Dapper;
|
||||
using TechTitans.ViewModels;
|
||||
using TechTitans.Enums;
|
||||
|
||||
namespace TechTitans.Services
|
||||
{
|
||||
internal class RecapService
|
||||
{
|
||||
SongBasicDetailsRepository songBasicDetailsRepository = new SongBasicDetailsRepository();
|
||||
UserPlaybackBehaviourRepository userPlaybackBehaviourRepository = new UserPlaybackBehaviourRepository();
|
||||
|
||||
public List<SongBasicInfo> Top5MostListenedSongs(int userId)
|
||||
{
|
||||
var top5Songs = songBasicDetailsRepository.GetTop5MostListenedSongs(userId);
|
||||
List<SongBasicInfo> top5SongsInfo = new List<SongBasicInfo>();
|
||||
foreach (var song in top5Songs)
|
||||
{
|
||||
top5SongsInfo.Add(songBasicDetailsRepository.SongBasicDetailsToSongBasicInfo(song));
|
||||
}
|
||||
return top5SongsInfo;
|
||||
}
|
||||
|
||||
public Tuple<SongBasicInfo, decimal> MostPlayedSongPercentile(int userId)
|
||||
{
|
||||
var mostPlayedSong = songBasicDetailsRepository.GetMostPlayedSongPercentile(userId);
|
||||
return new Tuple<SongBasicInfo, decimal>(songBasicDetailsRepository.SongBasicDetailsToSongBasicInfo(mostPlayedSong.Item1), mostPlayedSong.Item2);
|
||||
}
|
||||
|
||||
public Tuple<string, decimal> MostPlayedArtistPercentile(int userId)
|
||||
{
|
||||
return songBasicDetailsRepository.GetMostPlayedArtistPercentile(userId);
|
||||
}
|
||||
|
||||
public int MinutesListened(int userId)
|
||||
{
|
||||
//get list of all userplaybackbehaviour for a userid sorted ascending by timestamp and go over them calculating the difference between the timestamps and summing them up
|
||||
var userEvents = userPlaybackBehaviourRepository.GetUserPlaybackBehaviour(userId);
|
||||
int minutesListened = 0;
|
||||
//for every start and end event pair, calculate the difference in minutes and add it to the total
|
||||
for (int i = 0; i < userEvents.Count; i++)
|
||||
{
|
||||
if (userEvents[i].Event_Type == PlaybackEventType.start_play)
|
||||
{
|
||||
for (int j = i + 1; j < userEvents.Count; j++)
|
||||
{
|
||||
if (userEvents[j].Event_Type == PlaybackEventType.end_play)
|
||||
{
|
||||
minutesListened += (int)(userEvents[j].Timestamp - userEvents[i].Timestamp).TotalMinutes;
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return minutesListened;
|
||||
}
|
||||
|
||||
public List<string> Top5Genres(int userId)
|
||||
{
|
||||
return this.songBasicDetailsRepository.GetTop5Genres(userId);
|
||||
}
|
||||
|
||||
public List<string> NewGenresDiscovered(int userId)
|
||||
{
|
||||
return this.songBasicDetailsRepository.NewGenresDiscovered(userId);
|
||||
}
|
||||
|
||||
public ListenerPersonality ListenerPersonality(int userId)
|
||||
{
|
||||
var userEvents = userPlaybackBehaviourRepository.GetUserPlaybackBehaviour(userId);
|
||||
int playCount = 0;
|
||||
for(int i = 0; i < userEvents.Count; i++)
|
||||
{
|
||||
if ((userEvents[i].Event_Type == PlaybackEventType.start_play) && (userEvents[i].Timestamp.Year == DateTime.Now.Year))
|
||||
{
|
||||
playCount++;
|
||||
}
|
||||
}
|
||||
if(playCount > 100)
|
||||
{
|
||||
return Enums.ListenerPersonality.Melophile;
|
||||
}
|
||||
var newGenres = NewGenresDiscovered(userId);
|
||||
if(newGenres.Count > 3)
|
||||
{
|
||||
return Enums.ListenerPersonality.Explorer;
|
||||
}
|
||||
if(playCount < 10)
|
||||
{
|
||||
return Enums.ListenerPersonality.Casual;
|
||||
}
|
||||
return Enums.ListenerPersonality.Vanilla;
|
||||
}
|
||||
|
||||
public EndOfYearRecapViewModel GenerateEndOfYearRecap(int userId)
|
||||
{
|
||||
var recap = new EndOfYearRecapViewModel();
|
||||
recap.Top5MostListenedSongs = Top5MostListenedSongs(userId);
|
||||
recap.MostPlayedSongPercentile = MostPlayedSongPercentile(userId);
|
||||
recap.MostPlayedArtistPercentile = MostPlayedArtistPercentile(userId);
|
||||
recap.MinutesListened = MinutesListened(userId);
|
||||
recap.Top5Genres = Top5Genres(userId);
|
||||
recap.NewGenresDiscovered = NewGenresDiscovered(userId);
|
||||
recap.ListenerPersonality = ListenerPersonality(userId);
|
||||
return recap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Models;
|
||||
using TechTitans.Repositories;
|
||||
namespace TechTitans.Services
|
||||
{
|
||||
public class TopGenresController
|
||||
{
|
||||
private Repository<SongBasicDetails> SongRepo = new Repository<SongBasicDetails>();
|
||||
private Repository<SongRecommendationDetails> SongRecommendationRepo= new Repository<SongRecommendationDetails>();
|
||||
|
||||
public void getTop3Genres(int month,int year,Label genre1,Label minutes1,Label percentage1 , Label genre2, Label minutes2,Label percentage2, Label genre3 ,Label minutes3, Label percentage3) {
|
||||
int totalMinutes = 0;
|
||||
Dictionary<String, int> genreCount = new Dictionary<String, int>();
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll()) {
|
||||
foreach (SongRecommendationDetails songDetails in SongRecommendationRepo.GetAll())
|
||||
{
|
||||
if (songDetails.Song_Id == song.Song_Id && songDetails.Month == month && songDetails.Year == year)
|
||||
{
|
||||
totalMinutes += songDetails.Minutes_Listened;
|
||||
if (genreCount.ContainsKey(song.Genre))
|
||||
{
|
||||
genreCount[song.Genre] += songDetails.Minutes_Listened;
|
||||
}
|
||||
else
|
||||
{
|
||||
genreCount.Add(song.Genre, songDetails.Minutes_Listened);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sortedDict = from entry in genreCount orderby entry.Value descending select entry;
|
||||
int count = 0;
|
||||
foreach (KeyValuePair<String, int> entry in sortedDict)
|
||||
{
|
||||
switch(count)
|
||||
{
|
||||
case 0:
|
||||
genre1.Text = entry.Key;
|
||||
minutes1.Text = entry.Value.ToString();
|
||||
percentage1.Text = ((entry.Value / totalMinutes) * 100).ToString();
|
||||
break;
|
||||
case 1:
|
||||
genre2.Text = entry.Key;
|
||||
minutes2.Text = entry.Value.ToString();
|
||||
percentage2.Text = ((entry.Value / totalMinutes) * 100).ToString();
|
||||
break;
|
||||
case 2:
|
||||
genre3.Text = entry.Key;
|
||||
minutes3.Text = entry.Value.ToString();
|
||||
percentage3.Text = ((entry.Value / totalMinutes) * 100).ToString();
|
||||
break;
|
||||
}
|
||||
if(count ==2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
public void top3SubGenres(int month, int year, Label genre1, Label minutes1, Label percentage1, Label genre2, Label minutes2, Label percentage2, Label genre3, Label minutes3, Label percentage3) {
|
||||
Dictionary<String, int> subgenreCount = new Dictionary<String, int>();
|
||||
int totalMinutes = 0;
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll())
|
||||
{
|
||||
foreach (SongRecommendationDetails songDetails in SongRecommendationRepo.GetAll())
|
||||
{
|
||||
|
||||
if (songDetails.Song_Id == song.Song_Id && songDetails.Month == month && songDetails.Year == year)
|
||||
{
|
||||
totalMinutes += songDetails.Minutes_Listened;
|
||||
if (subgenreCount.ContainsKey(song.Subgenre))
|
||||
{
|
||||
subgenreCount[song.Subgenre] += songDetails.Minutes_Listened;
|
||||
}
|
||||
else
|
||||
{
|
||||
subgenreCount.Add(song.Subgenre, songDetails.Minutes_Listened);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sortedDict = from entry in subgenreCount orderby entry.Value descending select entry;
|
||||
int count = 0;
|
||||
foreach (KeyValuePair<String, int> entry in sortedDict)
|
||||
{
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
genre1.Text = entry.Key;
|
||||
minutes1.Text = entry.Value.ToString();
|
||||
percentage1.Text = ((entry.Value / totalMinutes) * 100).ToString();
|
||||
break;
|
||||
case 1:
|
||||
genre2.Text = entry.Key;
|
||||
minutes2.Text = entry.Value.ToString();
|
||||
percentage2.Text = ((entry.Value / totalMinutes) * 100).ToString();
|
||||
break;
|
||||
case 2:
|
||||
genre3.Text = entry.Key;
|
||||
minutes3.Text = entry.Value.ToString();
|
||||
percentage3.Text = ((entry.Value / totalMinutes) * 100).ToString();
|
||||
break;
|
||||
}
|
||||
if (count == 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TechTitans.Models;
|
||||
using TechTitans.Repositories;
|
||||
namespace TechTitans.Services
|
||||
{
|
||||
internal class UserService
|
||||
{
|
||||
private UserRepository SongRepo= new UserRepository();
|
||||
|
||||
public List<SongBasicInfo> get_recently_played() {
|
||||
List<SongBasicInfo> list_song=new List<SongBasicInfo>();
|
||||
foreach (SongBasicDetails song in SongRepo.GetAll()){
|
||||
SongBasicInfo song_info = SongRepo.SongBasicDetailsToSongBasicInfo(song);
|
||||
list_song.Add(song_info);
|
||||
}
|
||||
return list_song.Take(6).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0-android;net8.0-maccatalyst;net8.0-ios</TargetFrameworks>
|
||||
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
|
||||
|
||||
<!-- Note for MacCatalyst:
|
||||
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
|
||||
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
|
||||
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
|
||||
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
|
||||
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
|
||||
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>TechTitans</RootNamespace>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<!-- Display name -->
|
||||
<ApplicationTitle>TechTitans</ApplicationTitle>
|
||||
|
||||
<!-- App Identifier -->
|
||||
<ApplicationId>com.companyname.techtitans</ApplicationId>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
|
||||
<Configurations>Debug;Release;Android Emulator</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- App Icon -->
|
||||
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
|
||||
|
||||
<!-- Splash Screen -->
|
||||
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
|
||||
|
||||
<!-- Images -->
|
||||
<MauiImage Include="Resources\Images\*" />
|
||||
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
|
||||
|
||||
<!-- Custom Fonts -->
|
||||
<MauiFont Include="Resources\Fonts\*" />
|
||||
|
||||
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
|
||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="appsettings.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Maui" Version="8.0.1" />
|
||||
<PackageReference Include="Dapper" Version="2.1.35" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="8.0.14" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.14" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.7" />
|
||||
<PackageReference Include="SkiaSharp.Views.Maui.Controls" Version="2.88.7" />
|
||||
<PackageReference Include="SkiaSharp.Views.Maui.Core" Version="2.88.7" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Views\AnalystDashboard.xaml.cs">
|
||||
<DependentUpon>AnalystDashboard.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<MauiXaml Update="Views\AnalystPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\ArtistPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\Artist\ArtistSongDashboard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\BackHomeButton.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\FirstScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\ListenerPersonalityScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\MinutesListenedScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\MostListenedGenresScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\MostPlayedArtistScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\MostPlayedSongScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\NewGenresScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\EndOfYearRecap\Top5SongsScreen.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\SongItem.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\User\SearchButton.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\User\UserSongDashboard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\EndOfYearRecap.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\MainPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\Components\Piechart.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\AnalystDashboard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\SearchPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
<MauiXaml Update="Views\UserPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</MauiXaml>
|
||||
</ItemGroup>
|
||||
|
||||
<ProjectExtensions><VisualStudio><UserProperties XamarinHotReloadDebuggerTimeoutExceptionTechTitansHideInfoBar="True" /></VisualStudio></ProjectExtensions>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.002.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TechTitans", "TechTitans.csproj", "{6923E125-F765-4039-A8BB-1A445E8AE258}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6923E125-F765-4039-A8BB-1A445E8AE258}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6923E125-F765-4039-A8BB-1A445E8AE258}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6923E125-F765-4039-A8BB-1A445E8AE258}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6923E125-F765-4039-A8BB-1A445E8AE258}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C4D38F63-6A7E-48AF-BCD4-DD367B8A6BF8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.ComponentModel;
|
||||
using TechTitans.Enums;
|
||||
using TechTitans.Models;
|
||||
|
||||
namespace TechTitans.ViewModels
|
||||
{
|
||||
class ArtistSongDashboardViewModel
|
||||
{
|
||||
public SongBasicInfo SongInfo { get; set; }
|
||||
public AuthorDetails ArtistInfo { get; set; }
|
||||
public SongRecommendationDetails SongDetails { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
using System.ComponentModel;
|
||||
using TechTitans.Enums;
|
||||
using TechTitans.Models;
|
||||
|
||||
namespace TechTitans.ViewModels
|
||||
{
|
||||
public class EndOfYearRecapViewModel
|
||||
{
|
||||
public List<SongBasicInfo> Top5MostListenedSongs { get; set; }
|
||||
public Tuple<SongBasicInfo, decimal> MostPlayedSongPercentile { get; set; }
|
||||
public Tuple<string, decimal> MostPlayedArtistPercentile { get; set; }
|
||||
public int MinutesListened { get; set; }
|
||||
public List<string> Top5Genres { get; set; }
|
||||
public List<string> NewGenresDiscovered { get; set; }
|
||||
public ListenerPersonality ListenerPersonality { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.AnalystDashboard"
|
||||
Title="AnalystDashboard">
|
||||
<VerticalStackLayout>
|
||||
<Label
|
||||
Text="Dashboard"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Center" />
|
||||
<VerticalStackLayout Spacing="15" Padding="10, 0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Grid.Column="0" Text="Total Minutes Listened" />
|
||||
<Label Grid.Column="1" Text="Total Plays" />
|
||||
<Label Grid.Column="2" Text="Total Likes" />
|
||||
<Label Grid.Column="3" Text="Total Dislikes" />
|
||||
<Label Grid.Column="4" Text="Total Skips" />
|
||||
</Grid>
|
||||
<Grid x:Name="Dashboard">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Grid.Column="0" Text="{Binding TotalMinutesListened}" />
|
||||
<Label Grid.Column="1" Text="{Binding TotalPlays}" />
|
||||
<Label Grid.Column="2" Text="{Binding TotalLikes}" />
|
||||
<Label Grid.Column="3" Text="{Binding TotalDislikes}" />
|
||||
<Label Grid.Column="4" Text="{Binding TotalSkips}" />
|
||||
</Grid>
|
||||
</VerticalStackLayout>
|
||||
</VerticalStackLayout>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,16 @@
|
||||
using TechTitans.Models;
|
||||
using TechTitans.Services;
|
||||
//using System.IO;
|
||||
namespace TechTitans.Views;
|
||||
|
||||
public partial class AnalystDashboard : ContentPage
|
||||
{
|
||||
public AnalystDashboard()
|
||||
{
|
||||
InitializeComponent();
|
||||
FullDetailsOnSongController fullDetailsOnSongController = new FullDetailsOnSongController();
|
||||
FullDetailsOnSong FullDetails = fullDetailsOnSongController.GetFullDetailsOnSong(201);
|
||||
FullDetailsOnSong CurrentMonth = fullDetailsOnSongController.GetCurrentMonthDetails(201);
|
||||
this.BindingContext = CurrentMonth;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--import pt Components namesapace ca sa putem refolosi componente (this some DRY shit)
|
||||
asta e syntaxa: xmlns:controls="clr-namespace:TechTitans.Views.Components"-->
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:custom="clr-namespace:TechTitans.Views.Components"
|
||||
x:Class="TechTitans.Views.AnalystPage"
|
||||
Title="AnalystPage">
|
||||
<VerticalStackLayout Margin="15,0">
|
||||
<StackLayout Orientation="Horizontal">
|
||||
<StackLayout Padding="10">
|
||||
<Picker Title="Select Month:" x:Name="MonthPicker" SelectedIndex="0" >
|
||||
<Picker.ItemsSource>
|
||||
<x:Array Type="{x:Type x:Int32}">
|
||||
<x:Int32>1</x:Int32>
|
||||
<x:Int32>2</x:Int32>
|
||||
<x:Int32>3</x:Int32>
|
||||
<x:Int32>4</x:Int32>
|
||||
<x:Int32>5</x:Int32>
|
||||
<x:Int32>6</x:Int32>
|
||||
<x:Int32>7</x:Int32>
|
||||
<x:Int32>8</x:Int32>
|
||||
<x:Int32>9</x:Int32>
|
||||
<x:Int32>10</x:Int32>
|
||||
<x:Int32>11</x:Int32>
|
||||
<x:Int32>12</x:Int32>
|
||||
</x:Array>
|
||||
</Picker.ItemsSource>
|
||||
</Picker>
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout Padding="10">
|
||||
<Picker Title="Select Year:" x:Name="YearPicker" SelectedIndex="0" >
|
||||
<Picker.ItemsSource>
|
||||
<x:Array Type="{x:Type x:Int32}">
|
||||
<x:Int32>2020</x:Int32>
|
||||
<x:Int32>2021</x:Int32>
|
||||
<x:Int32>2022</x:Int32>
|
||||
<x:Int32>2023</x:Int32>
|
||||
<x:Int32>2024</x:Int32>
|
||||
<x:Int32>2025</x:Int32>
|
||||
<x:Int32>2026</x:Int32>
|
||||
<x:Int32>2027</x:Int32>
|
||||
<x:Int32>2028</x:Int32>
|
||||
<x:Int32>2029</x:Int32>
|
||||
<x:Int32>2030</x:Int32>
|
||||
</x:Array>
|
||||
</Picker.ItemsSource>
|
||||
</Picker>
|
||||
</StackLayout>
|
||||
<Button Text="Show Top 3s" Clicked="OnShowTop3Clicked" HeightRequest="40" HorizontalOptions="CenterAndExpand"/>
|
||||
</StackLayout>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<StackLayout Orientation="Vertical" Spacing="20">
|
||||
<!-- First row -->
|
||||
<StackLayout x:Name="Top3Genres">
|
||||
<Label Text="Top 3 Genres" FontSize="30"/>
|
||||
<HorizontalStackLayout Spacing="20">
|
||||
<VerticalStackLayout>
|
||||
<Label Text="Genre" FontSize="20"/>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<Label x:Name="Genre1Name" HorizontalOptions="Center" />
|
||||
<Label x:Name="Genre2Name" HorizontalOptions="Center" />
|
||||
<Label x:Name="Genre3Name" HorizontalOptions="Center" />
|
||||
</VerticalStackLayout>
|
||||
<VerticalStackLayout>
|
||||
<Label Text="Total Listens" FontSize="20"/>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<Label x:Name="Genre1Minutes" HorizontalOptions="Center"/>
|
||||
<Label x:Name="Genre2Minutes" HorizontalOptions="Center"/>
|
||||
<Label x:Name="Genre3Minutes" HorizontalOptions="Center"/>
|
||||
</VerticalStackLayout>
|
||||
<VerticalStackLayout>
|
||||
<Label Text="Percentage" FontSize="20"/>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<Label x:Name="Percentage1" HorizontalOptions="Center"/>
|
||||
<Label x:Name="Percentage2" HorizontalOptions="Center"/>
|
||||
<Label x:Name="Percentage3" HorizontalOptions="Center"/>
|
||||
</VerticalStackLayout>
|
||||
</HorizontalStackLayout>
|
||||
</StackLayout>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<StackLayout>
|
||||
<Label Text="Top 3 Subgenres" FontSize="30"/>
|
||||
<HorizontalStackLayout Spacing="20">
|
||||
<VerticalStackLayout>
|
||||
<Label Text="Genre" FontSize="20"/>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<Label x:Name="Subgenre1Name" />
|
||||
<Label x:Name="Subgenre2Name" />
|
||||
<Label x:Name="Subgenre3Name" />
|
||||
</VerticalStackLayout>
|
||||
<VerticalStackLayout>
|
||||
<Label Text="Total Listens" FontSize="20"/>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<Label x:Name="Subgenre1Minutes" />
|
||||
<Label x:Name="Subgenre2Minutes" />
|
||||
<Label x:Name="Subgenre3Minutes" />
|
||||
</VerticalStackLayout>
|
||||
<VerticalStackLayout>
|
||||
<Label Text="Percentage" FontSize="20"/>
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="0, 5" />
|
||||
<Label x:Name="Subgenre1Percentage"/>
|
||||
<Label x:Name="Subgenre2Percentage"/>
|
||||
<Label x:Name="Subgenre3Percentage"/>
|
||||
</VerticalStackLayout>
|
||||
</HorizontalStackLayout>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</VerticalStackLayout>
|
||||
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,58 @@
|
||||
using TechTitans.Models;
|
||||
using TechTitans.Services;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace TechTitans.Views;
|
||||
|
||||
public partial class AnalystPage : ContentPage
|
||||
{
|
||||
|
||||
private TopGenresController topGenresController;
|
||||
private Dictionary<String, int> genreCount = new Dictionary<String, int>();
|
||||
private Dictionary<String, int> subgenreCount = new Dictionary<String, int>();
|
||||
public AnalystPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
topGenresController = new TopGenresController();
|
||||
|
||||
}
|
||||
|
||||
public void ClearText()
|
||||
{
|
||||
Genre1Name.Text = "";
|
||||
Genre1Minutes.Text = "";
|
||||
Genre2Name.Text = "";
|
||||
Genre2Minutes.Text = "";
|
||||
Genre3Name.Text = "";
|
||||
Genre3Minutes.Text = "";
|
||||
}
|
||||
|
||||
private void OnShowTop3Clicked(object sender, EventArgs e)
|
||||
{
|
||||
ClearText();
|
||||
int monthInt = 0;
|
||||
int yearInt = 0;
|
||||
var month = MonthPicker.SelectedItem;
|
||||
var year = YearPicker.SelectedItem;
|
||||
if (month != null && year != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// make them ints
|
||||
monthInt = Convert.ToInt32(month);
|
||||
yearInt = Convert.ToInt32(year);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
topGenresController.getTop3Genres(monthInt, yearInt,Genre1Name,Genre1Minutes,Percentage1,Genre2Name,Genre2Name,Percentage2,Genre3Name,Genre3Minutes,Percentage3);
|
||||
topGenresController.top3SubGenres(monthInt, yearInt,Subgenre1Name,Subgenre1Minutes,Subgenre1Percentage,Subgenre2Name,Subgenre2Minutes,Subgenre2Percentage,Subgenre3Name,Subgenre3Minutes,Subgenre3Percentage);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--import pt Components namesapace ca sa putem refolosi componente (this some DRY shit)
|
||||
asta e syntaxa: xmlns:controls="clr-namespace:TechTitans.Views.Components"-->
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:custom="clr-namespace:TechTitans.Views.Components"
|
||||
x:Class="TechTitans.Views.ArtistPage"
|
||||
Title="Welcome DummyArtist69!">
|
||||
<VerticalStackLayout>
|
||||
<Label
|
||||
Text="Your Top Songs"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Start"
|
||||
FontAttributes="Bold"
|
||||
FontSize="16"
|
||||
Margin="10,0,0,0"
|
||||
/>
|
||||
<BoxView Color="#6E6E6E" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="10,5"/>
|
||||
<VerticalStackLayout Spacing="15" Padding="10, 0">
|
||||
<Grid x:Name="SongsGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
</VerticalStackLayout>
|
||||
</VerticalStackLayout>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,133 @@
|
||||
namespace TechTitans.Views;
|
||||
using TechTitans.Views.Components.Artist;
|
||||
using TechTitans.Views.Components;
|
||||
using TechTitans.Models;
|
||||
using TechTitans.Services;
|
||||
|
||||
public partial class ArtistPage : ContentPage
|
||||
{
|
||||
public ArtistSongDashboardController service = new();
|
||||
public ArtistPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
LoadSongs();
|
||||
}
|
||||
|
||||
private void LoadSongs()
|
||||
{
|
||||
var songs = service.getSongsForMainPage(); // Get your list of songs from somewhere (e.g., database, API, local storage)
|
||||
|
||||
// initial row
|
||||
SongsGrid.RowDefinitions.Add(new RowDefinition());
|
||||
|
||||
|
||||
// Loop through each song and dynamically create SongItem controls
|
||||
int rowIndex = 0;
|
||||
int columnIndex = 0;
|
||||
foreach (var song in songs)
|
||||
{
|
||||
var songItem = new SongItem(); // Create a new instance of SongItem
|
||||
songItem.BindingContext = song; // Set the song as the binding context of the SongItem
|
||||
songItem.Margin = new Thickness(0, 5, 0, 5); // Set margin as needed
|
||||
|
||||
// Add TapGestureRecognizer to handle tap event
|
||||
var tapGestureRecognizer = new TapGestureRecognizer();
|
||||
tapGestureRecognizer.Tapped += SongItem_Tapped;
|
||||
songItem.GestureRecognizers.Add(tapGestureRecognizer);
|
||||
|
||||
// Set the row and column of the SongItem in the grid
|
||||
Grid.SetRow(songItem, rowIndex);
|
||||
Grid.SetColumn(songItem, columnIndex);
|
||||
// Add the SongItem to the grid
|
||||
SongsGrid.Children.Add(songItem);
|
||||
columnIndex++;
|
||||
if (columnIndex == 2) // bun cod
|
||||
{
|
||||
columnIndex = 0;
|
||||
rowIndex++;
|
||||
SongsGrid.RowDefinitions.Add(new RowDefinition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SongItem_Tapped(object sender, System.EventArgs e)
|
||||
{
|
||||
// open ArtistSongDashboard page with song details
|
||||
var songItem = (SongItem)sender;
|
||||
var songInfo = songItem.BindingContext as SongBasicInfo;
|
||||
Navigation.PushAsync(new ArtistSongDashboard(songInfo));
|
||||
}
|
||||
|
||||
// Sample method to get list of songs (replace this with your actual method)
|
||||
private List<SongBasicInfo> GetSongs()
|
||||
{
|
||||
// mocked songs, to be replaced with actual data retrieval from db
|
||||
return new List<SongBasicInfo>
|
||||
{
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 10,
|
||||
Name = "Song 1",
|
||||
Artist = "Artist 1",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 201,
|
||||
Name = "Song 2",
|
||||
Artist = "Artist 2",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 2,
|
||||
Name = "Song 3",
|
||||
Artist = "Artist 3",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 3,
|
||||
Name = "Song 4",
|
||||
Artist = "Artist 4",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 4,
|
||||
Name = "Song 5",
|
||||
Artist = "Artist 5",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 5,
|
||||
Name = "Song 6",
|
||||
Artist = "Artist 6",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 6,
|
||||
Name = "Song 7",
|
||||
Artist = "Artist 7",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 7,
|
||||
Name = "Song 8",
|
||||
Artist = "Artist 8",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
new SongBasicInfo
|
||||
{
|
||||
SongId = 8,
|
||||
Name = "Song 9",
|
||||
Artist = "Artist 9",
|
||||
Image = "song_img_default.png"
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:custom="clr-namespace:TechTitans.Views.Components"
|
||||
x:Class="TechTitans.Views.Components.Artist.ArtistSongDashboard"
|
||||
Title="Song Dashboard">
|
||||
|
||||
<VerticalStackLayout>
|
||||
<VerticalStackLayout Padding="20" Spacing="10">
|
||||
<Image
|
||||
x:Name="SongImage"
|
||||
HorizontalOptions="Start"
|
||||
HeightRequest="256"
|
||||
WidthRequest="256"
|
||||
/>
|
||||
<Label
|
||||
x:Name="SongTitle"
|
||||
Text=""
|
||||
FontSize="32"
|
||||
FontAttributes="Bold"
|
||||
WidthRequest="256"
|
||||
HorizontalOptions="Start"
|
||||
/>
|
||||
<Label
|
||||
x:Name="SongArtist"
|
||||
Text=""
|
||||
FontSize="20"
|
||||
TextColor="#6E6E6E"
|
||||
Margin="0,-10,0,0"
|
||||
HorizontalOptions="Start"
|
||||
/>
|
||||
<Label
|
||||
x:Name="SongAlbum"
|
||||
Text=""
|
||||
FontSize="24"
|
||||
HorizontalOptions="Start"
|
||||
/>
|
||||
</VerticalStackLayout>
|
||||
<!--linie f ghetto-->
|
||||
<BoxView Color="Gray" HeightRequest="2" HorizontalOptions="FillAndExpand" Margin="10, 5" />
|
||||
<HorizontalStackLayout HorizontalOptions="CenterAndExpand" Spacing="10">
|
||||
<VerticalStackLayout>
|
||||
<Button
|
||||
Text="Info"
|
||||
TextColor="#6E6E6E"
|
||||
FontAttributes="Bold"
|
||||
Style="{StaticResource TabNavButton}"
|
||||
Clicked="OnInfoClick"
|
||||
/>
|
||||
<BoxView x:Name="InfoBoxView" Color="#6E6E6E" HeightRequest="2" HorizontalOptions="FillAndExpand"/>
|
||||
</VerticalStackLayout>
|
||||
<VerticalStackLayout>
|
||||
<Button
|
||||
Text="Performance"
|
||||
TextColor="#6E6E6E"
|
||||
FontAttributes="Bold"
|
||||
Style="{StaticResource TabNavButton}"
|
||||
Clicked="OnPerformanceCLick"
|
||||
/>
|
||||
<BoxView x:Name="PerformanceBoxView" Color="#1E1E1E" HeightRequest="2" HorizontalOptions="FillAndExpand"/>
|
||||
</VerticalStackLayout>
|
||||
</HorizontalStackLayout>
|
||||
<Frame
|
||||
CornerRadius="10"
|
||||
Margin="20,20,20,0"
|
||||
Padding="10"
|
||||
BackgroundColor="#6E6E6E"
|
||||
>
|
||||
<HorizontalStackLayout Spacing="40" HorizontalOptions="Center">
|
||||
<VerticalStackLayout Spacing="20" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
|
||||
<Label
|
||||
x:Name="label1"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
<Label
|
||||
x:Name="label2"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
<Label
|
||||
x:Name="label3"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
<Label
|
||||
x:Name="label4"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
</VerticalStackLayout>
|
||||
<VerticalStackLayout Spacing="20" VerticalOptions="FillAndExpand" HorizontalOptions="EndAndExpand">
|
||||
<Label
|
||||
x:Name="content1"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
<Label
|
||||
x:Name="content2"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
<Label
|
||||
x:Name="content3"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
<Label
|
||||
x:Name="content4"
|
||||
Text=""
|
||||
FontSize="16"
|
||||
/>
|
||||
</VerticalStackLayout>
|
||||
</HorizontalStackLayout>
|
||||
|
||||
</Frame>
|
||||
</VerticalStackLayout>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,85 @@
|
||||
using TechTitans.Models;
|
||||
using TechTitans.ViewModels;
|
||||
using TechTitans.Services;
|
||||
namespace TechTitans.Views.Components.Artist;
|
||||
|
||||
public partial class ArtistSongDashboard : ContentPage
|
||||
{
|
||||
public ArtistSongDashboardController service = new ();
|
||||
// alt domain song type cu mai multe detalii
|
||||
int songId;
|
||||
ArtistSongDashboardViewModel viewModel;
|
||||
public ArtistSongDashboard(SongBasicInfo song)
|
||||
{
|
||||
songId = song.SongId;
|
||||
InitializeComponent();
|
||||
populateViewModel(songId);
|
||||
LoadPage();
|
||||
}
|
||||
private void populateViewModel(int songID)
|
||||
{
|
||||
viewModel = new ArtistSongDashboardViewModel() {
|
||||
SongInfo = service.getSongInfo(songID),
|
||||
SongDetails = service.getSongDetails(songID),
|
||||
ArtistInfo = service.getArtistInfo(songID)
|
||||
};
|
||||
}
|
||||
private void LoadPage()
|
||||
{
|
||||
SongImage.Source = viewModel.SongInfo.Image;
|
||||
SongTitle.Text = viewModel.SongInfo.Name;
|
||||
SongArtist.Text = "by " + viewModel.ArtistInfo.Name;
|
||||
SongAlbum.Text = "from " + viewModel.SongInfo.Album;
|
||||
|
||||
// set song info panel
|
||||
label1.Text = "Genre:";
|
||||
content1.Text = viewModel.SongInfo.Genre;
|
||||
label2.Text = "Subgenre:";
|
||||
content2.Text = viewModel.SongInfo.Subgenre;
|
||||
label3.Text = "Country:";
|
||||
content3.Text = viewModel.SongInfo.Country;
|
||||
label4.Text = "Language:";
|
||||
content4.Text = viewModel.SongInfo.Language;
|
||||
}
|
||||
|
||||
// private ArtistSongDashboardViewModel getMockedViewModel()
|
||||
//{
|
||||
// var mockedModel = new ArtistSongDashboardViewModel()
|
||||
// {
|
||||
// SongInfo = new SongBasicInfo(),
|
||||
// SongDetails = new SongRecommendationDetails(),
|
||||
// ArtistInfo = new AuthorDetails(),
|
||||
// };
|
||||
// return mockedModel;
|
||||
//}
|
||||
|
||||
private void OnInfoClick(object sender, EventArgs e)
|
||||
{
|
||||
InfoBoxView.Color = Color.FromArgb("#6E6E6E");
|
||||
PerformanceBoxView.Color = Color.FromArgb("#1E1E1E");
|
||||
|
||||
label1.Text = "Genre:";
|
||||
content1.Text = viewModel.SongInfo.Genre;
|
||||
label2.Text = "Subgenre:";
|
||||
content2.Text = viewModel.SongInfo.Subgenre;
|
||||
label3.Text = "Country:";
|
||||
content3.Text = viewModel.SongInfo.Country;
|
||||
label4.Text = "Language:";
|
||||
content4.Text = viewModel.SongInfo.Language;
|
||||
}
|
||||
|
||||
private void OnPerformanceCLick(object sender, EventArgs e)
|
||||
{
|
||||
PerformanceBoxView.Color = Color.FromArgb("#6E6E6E");
|
||||
InfoBoxView.Color = Color.FromArgb("#1E1E1E");
|
||||
|
||||
label1.Text = "Minutes Listened:";
|
||||
content1.Text = viewModel.SongDetails.Minutes_Listened.ToString();
|
||||
label2.Text = "Total Plays:";
|
||||
content2.Text = viewModel.SongDetails.Number_Of_Plays.ToString();
|
||||
label3.Text = "Likes:";
|
||||
content3.Text = viewModel.SongDetails.Likes.ToString();
|
||||
label4.Text = "Dislikes:";
|
||||
content4.Text = viewModel.SongDetails.Dislikes.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.Components.BackHomeButton">
|
||||
<VerticalStackLayout>
|
||||
<Button
|
||||
x:Name="HomeBtn"
|
||||
Text="Go Home"
|
||||
Clicked="OnBackClick"
|
||||
HorizontalOptions="Start"
|
||||
Margin="15,0,0,0"
|
||||
/>
|
||||
<!--xaml e retardat ca se ia left,top,right,bottom la margin si restu in loc sa inceapa de la top ca in css-->
|
||||
</VerticalStackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace TechTitans.Views.Components;
|
||||
|
||||
public partial class BackHomeButton : ContentView
|
||||
{
|
||||
public BackHomeButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnBackClick(object sender, EventArgs e) => Application.Current.MainPage = new NavigationPage(new MainPage());
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.FirstScreen">
|
||||
<StackLayout x:Name="Background" BackgroundColor="#0A14C8" VerticalOptions="FillAndExpand">
|
||||
<Label
|
||||
Text="Sounds like you had quite the 2023. Let's play it back..."
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White"/>
|
||||
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
|
||||
<Image
|
||||
Source= "first_screen_1.jpg"
|
||||
HeightRequest="256"
|
||||
WidthRequest="256"
|
||||
Aspect="Fill"
|
||||
x:Name="GenericImage"
|
||||
/>
|
||||
</StackLayout>
|
||||
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,44 @@
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class FirstScreen : ContentView
|
||||
{
|
||||
public FirstScreen()
|
||||
{
|
||||
InitializeComponent();
|
||||
ChangeImageAndBackgraound();
|
||||
}
|
||||
|
||||
private async void ChangeImageAndBackgraound()
|
||||
{
|
||||
await Task.Delay(3000);
|
||||
var imagesource = new FileImageSource
|
||||
{
|
||||
File = "first_screen_2.jpg"
|
||||
};
|
||||
GenericImage.Source = imagesource;
|
||||
Background.BackgroundColor = new Color(200, 20, 200);
|
||||
await Task.Delay(3000);
|
||||
imagesource = new FileImageSource
|
||||
{
|
||||
File = "first_screen_3.jpg"
|
||||
};
|
||||
GenericImage.Source = imagesource;
|
||||
Background.BackgroundColor = new Color(100, 200, 100);
|
||||
await Task.Delay(3000);
|
||||
imagesource = new FileImageSource
|
||||
{
|
||||
File = "first_screen_4.jpg"
|
||||
};
|
||||
GenericImage.Source = imagesource;
|
||||
Background.BackgroundColor = new Color(200, 200, 20);
|
||||
await Task.Delay(3000);
|
||||
imagesource = new FileImageSource
|
||||
{
|
||||
File = "first_screen_1.jpg"
|
||||
};
|
||||
GenericImage.Source = imagesource;
|
||||
Background.BackgroundColor = new Color(10, 20, 200);
|
||||
ChangeImageAndBackgraound();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.ListenerPersonalityScreen"
|
||||
xmlns:local="clr-namespace:TechTitans.ViewModels">
|
||||
<ContentView.BindingContext>
|
||||
<local:EndOfYearRecapViewModel/>
|
||||
</ContentView.BindingContext>
|
||||
<StackLayout x:Name="MainContent">
|
||||
<Label
|
||||
x:Name="MainLabel"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White" >
|
||||
</Label>
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,33 @@
|
||||
using TechTitans.Enums;
|
||||
using TechTitans.ViewModels;
|
||||
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class ListenerPersonalityScreen : ContentView
|
||||
{
|
||||
public EndOfYearRecapViewModel ViewModel { get; set; }
|
||||
public ListenerPersonalityScreen(EndOfYearRecapViewModel _viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
ViewModel = _viewModel;
|
||||
switch (ViewModel.ListenerPersonality)
|
||||
{
|
||||
case ListenerPersonality.Vanilla:
|
||||
MainContent.BackgroundColor = new Color(200, 200, 100);
|
||||
MainLabel.Text = "You've been categorized as Vanilla, indicating that you've listened to very few songs. That's absolutely fine! Everyone has their own preferences when it comes to music, and there's beauty in simplicity. Whether you choose to explore more or stick to your familiar tunes, the most important thing is that music brings you joy in its own special way.";
|
||||
break;
|
||||
case ListenerPersonality.Casual:
|
||||
MainContent.BackgroundColor = new Color(100, 200, 100);
|
||||
MainLabel.Text = "You're a Casual listener, someone who enjoys music without delving too deep into it. While you may not have listened to a vast number of songs, your appreciation for the tunes you've encountered is undeniable. Keep enjoying music at your own pace, letting it add flavor to your moments without overwhelming them.";
|
||||
break;
|
||||
case ListenerPersonality.Melophile:
|
||||
MainContent.BackgroundColor = new Color(100, 100, 100);
|
||||
MainLabel.Text = "Congratulations! You've been classified as a Melophile, someone who has listened to a lot of songs. Your passion for music knows no bounds, and your love for exploring different melodies is truly commendable. Keep listening, keep discovering, and let the rhythm of life guide you.";
|
||||
break;
|
||||
case ListenerPersonality.Explorer:
|
||||
MainContent.BackgroundColor = new Color(50, 0, 100);
|
||||
MainLabel.Text = "Kudos to you! You're an Explorer in the realm of music, always eager to delve into new genres and sounds. Your adventurous spirit leads you to uncharted musical territories, expanding your horizons with each tune you encounter. Embrace the journey of discovery and let the melodies carry you to places you've never been.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.MinutesListenedScreen">
|
||||
<StackLayout BackgroundColor="Black">
|
||||
<Label
|
||||
Text="{Binding MinutesListened, StringFormat='You\'ve listened to {0} minutes of music this year...'}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White"/>
|
||||
<AbsoluteLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
|
||||
<Image x:Name="RedHalfCircle"
|
||||
Source="half_circle.svg"
|
||||
HeightRequest="256"
|
||||
Aspect="AspectFit">
|
||||
<Image.Behaviors>
|
||||
<toolkit:IconTintColorBehavior TintColor="Red" />
|
||||
</Image.Behaviors>
|
||||
</Image>
|
||||
<Image x:Name="BlueHalfCircle"
|
||||
Source="half_circle.svg"
|
||||
HeightRequest="256"
|
||||
Scale="0"
|
||||
Aspect="AspectFit">
|
||||
<Image.Behaviors>
|
||||
<toolkit:IconTintColorBehavior TintColor="Blue" />
|
||||
</Image.Behaviors>
|
||||
</Image>
|
||||
</AbsoluteLayout>
|
||||
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class MinutesListenedScreen : ContentView
|
||||
{
|
||||
public MinutesListenedScreen()
|
||||
{
|
||||
InitializeComponent();
|
||||
CrazyFuckingAnimation();
|
||||
}
|
||||
|
||||
public async void CrazyFuckingAnimation()
|
||||
{
|
||||
await RedHalfCircle.ScaleTo(0, 1000, Easing.CubicIn);
|
||||
await BlueHalfCircle.ScaleTo(1, 1000, Easing.CubicIn);
|
||||
await BlueHalfCircle.ScaleTo(0, 1000, Easing.CubicIn);
|
||||
await RedHalfCircle.ScaleTo(1, 1000, Easing.CubicIn);
|
||||
CrazyFuckingAnimation();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:custom="clr-namespace:TechTitans.Views.Components"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.MostListenedGenresScreen">
|
||||
<VerticalStackLayout>
|
||||
<Label Text="Overall your music this year was..."
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White" >
|
||||
</Label>
|
||||
<CollectionView ItemsSource="{Binding Top5Genres}">
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Stroke="#C49B33"
|
||||
StrokeThickness="4"
|
||||
Background="#2B0B98"
|
||||
Padding="16,8"
|
||||
HorizontalOptions="Center"
|
||||
Margin="10">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="40,0,0,40" />
|
||||
</Border.StrokeShape>
|
||||
<Label Text="{Binding .}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="30"
|
||||
TextColor="White"
|
||||
BackgroundColor="#2B0B98"
|
||||
WidthRequest="350"
|
||||
HorizontalTextAlignment="Center"
|
||||
VerticalTextAlignment="Center"
|
||||
Padding="0, 20, 0, 20"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class MostListenedGenresScreen : ContentView
|
||||
{
|
||||
public MostListenedGenresScreen()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.MostPlayedArtistScreen"
|
||||
xmlns:custom="clr-namespace:TechTitans.Views.Components"
|
||||
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
|
||||
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
|
||||
<Image x:Name="RedHalfCircle1"
|
||||
Source="half_circle.svg"
|
||||
HeightRequest="128"
|
||||
Aspect="AspectFit">
|
||||
<Image.Behaviors>
|
||||
<toolkit:IconTintColorBehavior TintColor="Red" />
|
||||
</Image.Behaviors>
|
||||
</Image>
|
||||
<Label VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White" >
|
||||
<Label.Text>
|
||||
<MultiBinding StringFormat="{}Your top artist this year was {0}">
|
||||
<Binding Path="MostPlayedArtistPercentile.Item1" />
|
||||
</MultiBinding>
|
||||
</Label.Text>
|
||||
</Label>
|
||||
<custom:Piechart Progress="{Binding MostPlayedArtistPercentile.Item2}"
|
||||
ProgressColor="Red"
|
||||
ProgressLeftColor="LightGreen"
|
||||
Size="140"
|
||||
TextColor="DarkGreen"
|
||||
Thickness="4"
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"/>
|
||||
<Label VerticalOptions="End"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White" >
|
||||
<Label.Text>
|
||||
<MultiBinding StringFormat="{}Out of all your songs, {0:F2} were by {1}">
|
||||
<Binding Path="MostPlayedArtistPercentile.Item2" />
|
||||
<Binding Path="MostPlayedArtistPercentile.Item1" />
|
||||
</MultiBinding>
|
||||
</Label.Text>
|
||||
</Label>
|
||||
<Image x:Name="RedHalfCircle2"
|
||||
Source="half_circle.svg"
|
||||
HeightRequest="128"
|
||||
Aspect="AspectFit">
|
||||
<Image.Behaviors>
|
||||
<toolkit:IconTintColorBehavior TintColor="Red" />
|
||||
</Image.Behaviors>
|
||||
</Image>
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class MostPlayedArtistScreen : ContentView
|
||||
{
|
||||
public MostPlayedArtistScreen()
|
||||
{
|
||||
InitializeComponent();
|
||||
AnotherCrazyAnimation();
|
||||
}
|
||||
|
||||
public async void AnotherCrazyAnimation()
|
||||
{
|
||||
var t1 = RedHalfCircle1.RotateTo(36000, 200000, Easing.Linear);
|
||||
var t2 = RedHalfCircle2.RotateTo(-36000, 200000, Easing.Linear);
|
||||
await Task.WhenAll(t1, t2);
|
||||
AnotherCrazyAnimation();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.MostPlayedSongScreen"
|
||||
xmlns:custom="clr-namespace:TechTitans.Views.Components">
|
||||
<VerticalStackLayout>
|
||||
<Label VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White" >
|
||||
<Label.Text>
|
||||
<MultiBinding StringFormat="{}{0} by {1} was your top track this year">
|
||||
<Binding Path="MostPlayedSongPercentile.Item1.Name" />
|
||||
<Binding Path="MostPlayedSongPercentile.Item1.Artist" />
|
||||
</MultiBinding>
|
||||
</Label.Text>
|
||||
</Label>
|
||||
<Image
|
||||
Source="{Binding MostPlayedSongPercentile.Item1.Image}"
|
||||
HeightRequest="256"
|
||||
Aspect="AspectFit"
|
||||
Margin="0,40,0,40"
|
||||
/>
|
||||
<Label Text="{Binding MostPlayedSongPercentile.Item2, StringFormat='You played it a whopping {0:F2}% of the time'}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White"
|
||||
VerticalTextAlignment="Center"
|
||||
HorizontalTextAlignment="Center"/>
|
||||
<custom:Piechart Progress="{Binding MostPlayedSongPercentile.Item2}"
|
||||
ProgressColor="Red"
|
||||
ProgressLeftColor="LightGreen"
|
||||
Size="140"
|
||||
TextColor="DarkGreen"
|
||||
Thickness="4"
|
||||
HorizontalOptions="Center"/>
|
||||
</VerticalStackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class MostPlayedSongScreen : ContentView
|
||||
{
|
||||
public MostPlayedSongScreen()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.NewGenresScreen">
|
||||
<VerticalStackLayout>
|
||||
<Label Text="This year you discovered a new taste in music..."
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White" >
|
||||
</Label>
|
||||
<CollectionView ItemsSource="{Binding NewGenresDiscovered}">
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Stroke="#C49B33"
|
||||
StrokeThickness="4"
|
||||
Background="#2B0B98"
|
||||
Padding="16,8"
|
||||
HorizontalOptions="Center"
|
||||
Margin="10">
|
||||
<Border.StrokeShape>
|
||||
<RoundRectangle CornerRadius="40,0,0,40" />
|
||||
</Border.StrokeShape>
|
||||
<Label Text="{Binding .}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="30"
|
||||
TextColor="White"
|
||||
BackgroundColor="#2B0B98"
|
||||
WidthRequest="350"
|
||||
HorizontalTextAlignment="Center"
|
||||
VerticalTextAlignment="Center"
|
||||
Padding="0, 20, 0, 20"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
|
||||
</VerticalStackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class NewGenresScreen : ContentView
|
||||
{
|
||||
public NewGenresScreen()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:custom="clr-namespace:TechTitans.Views.Components"
|
||||
x:Class="TechTitans.Views.Components.EndOfYearRecap.Top5SongsScreen">
|
||||
<StackLayout BackgroundColor="Black">
|
||||
<Label
|
||||
Text="These were your top five trancks of 2023"
|
||||
VerticalOptions="Start"
|
||||
HorizontalOptions="Center"
|
||||
FontSize="25"
|
||||
Padding="20,40,20,20"
|
||||
TextColor="White"/>
|
||||
<CollectionView ItemsSource="{Binding Top5MostListenedSongs}">
|
||||
<CollectionView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<custom:SongItem Padding="20,20,0,0" BindingContext="{Binding .}"/>
|
||||
</DataTemplate>
|
||||
</CollectionView.ItemTemplate>
|
||||
</CollectionView>
|
||||
|
||||
</StackLayout>
|
||||
</ContentView>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace TechTitans.Views.Components.EndOfYearRecap;
|
||||
|
||||
public partial class Top5SongsScreen : ContentView
|
||||
{
|
||||
public Top5SongsScreen()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView
|
||||
x:Class="TechTitans.Views.Components.Piechart"
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:drawables="clr-namespace:TechTitans.Views.Components"
|
||||
x:Name="this">
|
||||
|
||||
<GraphicsView>
|
||||
<GraphicsView.Drawable>
|
||||
<drawables:PiechartDrawble
|
||||
Progress="{Binding Progress, Source={x:Reference this}}"
|
||||
Size="{Binding Size, Source={x:Reference this}}"
|
||||
TextColor="{Binding TextColor, Source={x:Reference this}}"
|
||||
Thickness="{Binding Thickness, Source={x:Reference this}}"
|
||||
ProgressColor="{Binding ProgressColor, Source={x:Reference this}}"
|
||||
ProgressLeftColor="{Binding ProgressLeftColor, Source={x:Reference this}}"/>
|
||||
</GraphicsView.Drawable>
|
||||
</GraphicsView>
|
||||
|
||||
</ContentView>
|
||||
@@ -0,0 +1,63 @@
|
||||
namespace TechTitans.Views.Components;
|
||||
|
||||
public partial class Piechart : ContentView
|
||||
{
|
||||
public Piechart()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static readonly BindableProperty ProgressProperty = BindableProperty.Create(nameof(Progress), typeof(float), typeof(Piechart));
|
||||
public static readonly BindableProperty SizeProperty = BindableProperty.Create(nameof(Size), typeof(int), typeof(Piechart));
|
||||
public static readonly BindableProperty ThicknessProperty = BindableProperty.Create(nameof(Thickness), typeof(int), typeof(Piechart));
|
||||
public static readonly BindableProperty ProgressColorProperty = BindableProperty.Create(nameof(ProgressColor), typeof(Color), typeof(Piechart));
|
||||
public static readonly BindableProperty ProgressLeftColorProperty = BindableProperty.Create(nameof(ProgressLeftColor), typeof(Color), typeof(Piechart));
|
||||
public static readonly BindableProperty TextColorProperty = BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(Piechart));
|
||||
|
||||
public float Progress
|
||||
{
|
||||
get { return (float)GetValue(ProgressProperty); }
|
||||
set { SetValue(ProgressProperty, value); }
|
||||
}
|
||||
|
||||
public int Size
|
||||
{
|
||||
get { return (int)GetValue(SizeProperty); }
|
||||
set { SetValue(SizeProperty, value); }
|
||||
}
|
||||
|
||||
public int Thickness
|
||||
{
|
||||
get { return (int)GetValue(ThicknessProperty); }
|
||||
set { SetValue(ThicknessProperty, value); }
|
||||
}
|
||||
|
||||
public Color ProgressColor
|
||||
{
|
||||
get { return (Color)GetValue(ProgressColorProperty); }
|
||||
set { SetValue(ProgressColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color ProgressLeftColor
|
||||
{
|
||||
get { return (Color)GetValue(ProgressLeftColorProperty); }
|
||||
set { SetValue(ProgressLeftColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color TextColor
|
||||
{
|
||||
get { return (Color)GetValue(TextColorProperty); }
|
||||
set { SetValue(TextColorProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(string propertyName = null)
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
|
||||
if (propertyName == SizeProperty.PropertyName)
|
||||
{
|
||||
HeightRequest = Size;
|
||||
WidthRequest = Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TechTitans.Views.Components
|
||||
{
|
||||
public class PiechartDrawble : BindableObject, IDrawable
|
||||
{
|
||||
public static readonly BindableProperty ProgressProperty = BindableProperty.Create(nameof(Progress), typeof(float), typeof(PiechartDrawble));
|
||||
public static readonly BindableProperty SizeProperty = BindableProperty.Create(nameof(Size), typeof(int), typeof(PiechartDrawble));
|
||||
public static readonly BindableProperty ThicknessProperty = BindableProperty.Create(nameof(Thickness), typeof(int), typeof(PiechartDrawble));
|
||||
public static readonly BindableProperty ProgressColorProperty = BindableProperty.Create(nameof(ProgressColor), typeof(Color), typeof(PiechartDrawble));
|
||||
public static readonly BindableProperty ProgressLeftColorProperty = BindableProperty.Create(nameof(ProgressLeftColor), typeof(Color), typeof(PiechartDrawble));
|
||||
public static readonly BindableProperty TextColorProperty = BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(PiechartDrawble));
|
||||
|
||||
public float Progress
|
||||
{
|
||||
get => (float)GetValue(ProgressProperty);
|
||||
set => SetValue(ProgressProperty, value);
|
||||
}
|
||||
|
||||
public int Size
|
||||
{
|
||||
get { return (int)GetValue(SizeProperty); }
|
||||
set { SetValue(SizeProperty, value); }
|
||||
}
|
||||
|
||||
public int Thickness
|
||||
{
|
||||
get { return (int)GetValue(ThicknessProperty); }
|
||||
set { SetValue(ThicknessProperty, value); }
|
||||
}
|
||||
|
||||
public Color ProgressColor
|
||||
{
|
||||
get { return (Color)GetValue(ProgressColorProperty); }
|
||||
set { SetValue(ProgressColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color ProgressLeftColor
|
||||
{
|
||||
get { return (Color)GetValue(ProgressLeftColorProperty); }
|
||||
set { SetValue(ProgressLeftColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color TextColor
|
||||
{
|
||||
get { return (Color)GetValue(TextColorProperty); }
|
||||
set { SetValue(TextColorProperty, value); }
|
||||
}
|
||||
|
||||
public void Draw(ICanvas canvas, RectF dirtyRect)
|
||||
{
|
||||
float effectiveSize = Size - Thickness;
|
||||
float x = Thickness / 2;
|
||||
float y = Thickness / 2;
|
||||
|
||||
if (Progress < 0)
|
||||
{
|
||||
Progress = 0;
|
||||
}
|
||||
else if (Progress > 100)
|
||||
{
|
||||
Progress = 100;
|
||||
}
|
||||
|
||||
if (Progress < 100)
|
||||
{
|
||||
float angle = GetAngle(Progress);
|
||||
|
||||
canvas.StrokeColor = ProgressLeftColor;
|
||||
canvas.StrokeSize = Thickness;
|
||||
canvas.DrawEllipse(x, y, effectiveSize, effectiveSize);
|
||||
|
||||
// Draw arc
|
||||
canvas.StrokeColor = ProgressColor;
|
||||
canvas.StrokeSize = Thickness;
|
||||
canvas.DrawArc(x, y, effectiveSize, effectiveSize, 90, angle, true, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw circle
|
||||
canvas.StrokeColor = ProgressColor;
|
||||
canvas.StrokeSize = Thickness;
|
||||
canvas.DrawEllipse(x, y, effectiveSize, effectiveSize);
|
||||
}
|
||||
|
||||
// Make the percentage always the same size in relation to the size of the progress bar
|
||||
}
|
||||
|
||||
private float GetAngle(float progress)
|
||||
{
|
||||
float factor = 90f / 25f;
|
||||
|
||||
if (progress > 75)
|
||||
{
|
||||
return -180 - ((progress - 75) * factor);
|
||||
}
|
||||
else if (progress > 50)
|
||||
{
|
||||
return -90 - ((progress - 50) * factor);
|
||||
}
|
||||
else if (progress > 25)
|
||||
{
|
||||
return 0 - ((progress - 25) * factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 90 - (progress * factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TechTitans.Views.Components.SongItem"
|
||||
>
|
||||
<HorizontalStackLayout>
|
||||
<Image
|
||||
Source="{Binding Image}"
|
||||
HeightRequest="64"
|
||||
Aspect="AspectFit"
|
||||
/>
|
||||
<VerticalStackLayout Padding="10,0">
|
||||
<Label
|
||||
Text="{Binding Name}"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Start"
|
||||
FontSize="24"
|
||||
/>
|
||||
<Label
|
||||
Text="{Binding Artist}"
|
||||
VerticalOptions="Center"
|
||||
HorizontalOptions="Start"
|
||||
FontSize="16"
|
||||
/>
|
||||
</VerticalStackLayout>
|
||||
</HorizontalStackLayout>
|
||||
</ContentView>
|
||||