From b3955d8eed3d71c1063dc0b5ae5deb3f067ab188 Mon Sep 17 00:00:00 2001 From: Alberto Balbo Date: Wed, 7 Jan 2026 15:28:19 +0100 Subject: [PATCH] Aggiunta Media Browser e restyling UI tema scuro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Introdotti MediaBrowserViewModel e MediaBrowserPage per esplorazione e gestione media scaricati, con filtri e ricerca - Aggiornata App.xaml con palette colori, gradienti e nuovi stili scuri per card, bottoni, textbox e titoli - Restyling completo di Dashboard, Targets e Settings con layout moderni, card, icone e badge - Aggiornata NavigationView con nuova voce "Esplora Media", header grafico e footer con stato/versione - Navigazione verso MediaBrowserPage e dimensione finestra iniziale più ampia - Rimosse risorse legacy "Data" dal progetto, aggiunto launchSettings.json - Esperienza utente più moderna, coerente e accessibile --- Teti/App.xaml | 205 +++++++++++++- Teti/App.xaml.cs | 1 + Teti/InstaArchive.csproj | 23 +- Teti/MainWindow.xaml | 104 ++++++- Teti/MainWindow.xaml.cs | 15 +- Teti/Properties/launchSettings.json | 11 + Teti/Teti.csproj | 0 Teti/ViewModels/MediaBrowserViewModel.cs | 134 ++++++++++ Teti/Views/DashboardPage.xaml | 327 +++++++++++++++++------ Teti/Views/MediaBrowserPage.xaml | 229 ++++++++++++++++ Teti/Views/MediaBrowserPage.xaml.cs | 17 ++ Teti/Views/SettingsPage.xaml | 308 +++++++++++++++------ Teti/Views/TargetsPage.xaml | 325 +++++++++++++++------- 13 files changed, 1425 insertions(+), 274 deletions(-) create mode 100644 Teti/Properties/launchSettings.json create mode 100644 Teti/Teti.csproj create mode 100644 Teti/ViewModels/MediaBrowserViewModel.cs create mode 100644 Teti/Views/MediaBrowserPage.xaml create mode 100644 Teti/Views/MediaBrowserPage.xaml.cs diff --git a/Teti/App.xaml b/Teti/App.xaml index 1c7980a..36a4ccc 100644 --- a/Teti/App.xaml +++ b/Teti/App.xaml @@ -2,17 +2,220 @@ x:Class="InstaArchive.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:converters="using:InstaArchive.Converters"> + xmlns:converters="using:InstaArchive.Converters" + RequestedTheme="Dark"> + + + + #E1306C + #F77EA4 + #C13584 + #5B51D8 + #7B72E8 + #34C759 + #FF9500 + #FF3B30 + #5856D6 + + + #0A0A0A + #141414 + #1C1C1E + #2C2C2E + #38383A + + + #FFFFFF + #8E8E93 + #48484A + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Teti/App.xaml.cs b/Teti/App.xaml.cs index c089317..d1b451d 100644 --- a/Teti/App.xaml.cs +++ b/Teti/App.xaml.cs @@ -59,6 +59,7 @@ public partial class App : Application services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); Services = services.BuildServiceProvider(); } diff --git a/Teti/InstaArchive.csproj b/Teti/InstaArchive.csproj index d544793..5a0270a 100644 --- a/Teti/InstaArchive.csproj +++ b/Teti/InstaArchive.csproj @@ -17,6 +17,12 @@ None true + + + + + + @@ -43,6 +49,21 @@ - + + + + + + + + + + + + + + MSBuild:Compile + + diff --git a/Teti/MainWindow.xaml b/Teti/MainWindow.xaml index 3630eb8..784d056 100644 --- a/Teti/MainWindow.xaml +++ b/Teti/MainWindow.xaml @@ -7,18 +7,110 @@ mc:Ignorable="d" Title="InstaArchive"> - + + IsPaneToggleButtonVisible="True" + IsSettingsVisible="False" + SelectionChanged="NavView_SelectionChanged" + OpenPaneLength="280" + CompactModeThresholdWidth="640" + CompactPaneLength="56" + Background="{StaticResource DarkSurfaceBrush}"> + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/Teti/MainWindow.xaml.cs b/Teti/MainWindow.xaml.cs index c51265c..959b81b 100644 --- a/Teti/MainWindow.xaml.cs +++ b/Teti/MainWindow.xaml.cs @@ -10,9 +10,21 @@ public sealed partial class MainWindow : Window public MainWindow() { InitializeComponent(); + + // Set window properties ExtendsContentIntoTitleBar = true; SetTitleBar(null); + // Set initial size + var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(Microsoft.UI.Win32Interop.GetWindowIdFromWindow( + WinRT.Interop.WindowNative.GetWindowHandle(this))); + + if (appWindow != null) + { + appWindow.Resize(new Windows.Graphics.SizeInt32(1400, 900)); + } + + // Navigate to Dashboard ContentFrame.Navigate(typeof(DashboardPage)); } @@ -25,11 +37,12 @@ public sealed partial class MainWindow : Window { "Dashboard" => typeof(DashboardPage), "Targets" => typeof(TargetsPage), + "MediaBrowser" => typeof(MediaBrowserPage), "Settings" => typeof(SettingsPage), _ => null }; - if (pageType != null) + if (pageType != null && ContentFrame.CurrentSourcePageType != pageType) { ContentFrame.Navigate(pageType); } diff --git a/Teti/Properties/launchSettings.json b/Teti/Properties/launchSettings.json new file mode 100644 index 0000000..43ad452 --- /dev/null +++ b/Teti/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "WSL": { + "commandName": "WSL2", + "distributionName": "" + }, + "InstaArchive": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/Teti/Teti.csproj b/Teti/Teti.csproj new file mode 100644 index 0000000..e69de29 diff --git a/Teti/ViewModels/MediaBrowserViewModel.cs b/Teti/ViewModels/MediaBrowserViewModel.cs new file mode 100644 index 0000000..9cf2af3 --- /dev/null +++ b/Teti/ViewModels/MediaBrowserViewModel.cs @@ -0,0 +1,134 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading.Tasks; +using InstaArchive.Models; +using InstaArchive.Repositories; + +namespace InstaArchive.ViewModels; + +public partial class MediaBrowserViewModel : ObservableObject +{ + private readonly FileBasedMediaRepository _mediaRepository; + private readonly FileBasedUserRepository _userRepository; + + [ObservableProperty] + private ObservableCollection allMedia = new(); + + [ObservableProperty] + private ObservableCollection filteredMedia = new(); + + [ObservableProperty] + private ObservableCollection allUsers = new(); + + [ObservableProperty] + private InstagramUser? selectedUserFilter; + + [ObservableProperty] + private string searchQuery = string.Empty; + + [ObservableProperty] + private MediaItem? selectedMedia; + + public MediaBrowserViewModel( + FileBasedMediaRepository mediaRepository, + FileBasedUserRepository userRepository) + { + _mediaRepository = mediaRepository; + _userRepository = userRepository; + + _ = LoadDataAsync(); + } + + partial void OnSearchQueryChanged(string value) + { + FilterMedia(); + } + + partial void OnSelectedUserFilterChanged(InstagramUser? value) + { + FilterMedia(); + } + + private void FilterMedia() + { + var filtered = AllMedia.AsEnumerable(); + + // Filter by search query + if (!string.IsNullOrWhiteSpace(SearchQuery)) + { + var query = SearchQuery.ToLower(); + filtered = filtered.Where(m => + m.FileName.ToLower().Contains(query) || + m.Caption?.ToLower().Contains(query) == true + ); + } + + // Filter by user + if (SelectedUserFilter != null) + { + filtered = filtered.Where(m => m.UserId == SelectedUserFilter.UserId); + } + + FilteredMedia.Clear(); + foreach (var item in filtered) + { + FilteredMedia.Add(item); + } + } + + [RelayCommand] + private async Task RefreshAsync() + { + await LoadDataAsync(); + } + + [RelayCommand] + private void OpenMedia(MediaItem media) + { + if (media == null) + { + return; + } + + // Open media in default application + _ = Windows.System.Launcher.LaunchUriAsync( + new System.Uri($"file:///{media.LocalPath}") + ); + } + + [RelayCommand] + private async Task DeleteMediaAsync(MediaItem media) + { + if (media == null) + { + return; + } + + // TODO: Implement delete confirmation and deletion + AllMedia.Remove(media); + FilterMedia(); + await Task.CompletedTask; + } + + private async Task LoadDataAsync() + { + var mediaList = await _mediaRepository.GetAllMediaAsync(); + var userList = await _userRepository.GetAllUsersAsync(); + + AllMedia.Clear(); + foreach (var item in mediaList.OrderByDescending(m => m.DownloadedAt)) + { + AllMedia.Add(item); + } + + AllUsers.Clear(); + foreach (var user in userList) + { + AllUsers.Add(user); + } + + FilterMedia(); + } +} diff --git a/Teti/Views/DashboardPage.xaml b/Teti/Views/DashboardPage.xaml index 7dbffc0..2f9afb0 100644 --- a/Teti/Views/DashboardPage.xaml +++ b/Teti/Views/DashboardPage.xaml @@ -4,42 +4,62 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - mc:Ignorable="d"> + mc:Ignorable="d" + Background="{StaticResource DarkBackgroundBrush}"> - + + - - + + - + + + + - - + + + + - - + + @@ -47,78 +67,180 @@ - - - - + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + - - - - + + + + + + + + IsItemClickEnabled="False" + Padding="0"> - - - - - + + + + + + + + @@ -126,26 +248,57 @@ - - - - + + + + + + + + + + + + - + - - - - - - - + + + + + + + + + + + + + + + diff --git a/Teti/Views/MediaBrowserPage.xaml b/Teti/Views/MediaBrowserPage.xaml new file mode 100644 index 0000000..3c71597 --- /dev/null +++ b/Teti/Views/MediaBrowserPage.xaml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Teti/Views/MediaBrowserPage.xaml.cs b/Teti/Views/MediaBrowserPage.xaml.cs new file mode 100644 index 0000000..b07f569 --- /dev/null +++ b/Teti/Views/MediaBrowserPage.xaml.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.UI.Xaml.Controls; +using InstaArchive.ViewModels; + +namespace InstaArchive.Views; + +public sealed partial class MediaBrowserPage : Page +{ + public MediaBrowserViewModel ViewModel { get; } + + public MediaBrowserPage() + { + InitializeComponent(); + ViewModel = App.Services.GetRequiredService(); + DataContext = ViewModel; + } +} diff --git a/Teti/Views/SettingsPage.xaml b/Teti/Views/SettingsPage.xaml index 28f377b..417c9d1 100644 --- a/Teti/Views/SettingsPage.xaml +++ b/Teti/Views/SettingsPage.xaml @@ -4,28 +4,45 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - mc:Ignorable="d"> + mc:Ignorable="d" + Background="{StaticResource DarkBackgroundBrush}"> - + - + + + + + - + - - - + + + + + + + + + + + @@ -35,124 +52,259 @@ + Margin="0,0,12,0"/> - + IsOn="{x:Bind ViewModel.Settings.EnableDateSubfolders, Mode=TwoWay}" + OffContent="I file verranno salvati direttamente nella cartella utente" + OnContent="I file verranno organizzati in sottocartelle per data"/> + Text="{x:Bind ViewModel.Settings.DateFolderFormat, Mode=TwoWay}" + Style="{StaticResource DarkTextBoxStyle}"/> - - - + + + + + + + + + + + + IsOn="{x:Bind ViewModel.Settings.EnableMetadataInjection, Mode=TwoWay}" + OffContent="I metadati non verranno inseriti nei file" + OnContent="I metadati (autore, data, descrizione) verranno inseriti nei file"/> - - - + + + + + + + + + + + + Maximum="10" + SpinButtonPlacementMode="Compact" + Description="Numero massimo di download simultanei"/> - + + + + + + + - + + + IsOn="{x:Bind ViewModel.Settings.AutoStartMonitoring, Mode=TwoWay}" + OffContent="Richiede avvio manuale" + OnContent="Il monitoraggio si avvia all'apertura dell'app"/> - - - + + + + + + + + + + + + IsOn="{x:Bind ViewModel.Settings.EnableRateLimiting, Mode=TwoWay}" + OffContent="Nessuna limitazione (sconsigliato)" + OnContent="Le richieste verranno limitate per sicurezza"/> + Maximum="1000" + SpinButtonPlacementMode="Compact" + Description="Numero massimo di richieste all'API di Instagram per ora"/> - + + + + + + + - + + - - - + + + + + + + + + + + - - + + - - - + - diff --git a/Teti/Views/TargetsPage.xaml b/Teti/Views/TargetsPage.xaml index 4da3111..edb320d 100644 --- a/Teti/Views/TargetsPage.xaml +++ b/Teti/Views/TargetsPage.xaml @@ -6,15 +6,16 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:models="using:InstaArchive.Models" - mc:Ignorable="d"> + mc:Ignorable="d" + Background="{StaticResource DarkBackgroundBrush}"> - + - + - + @@ -23,143 +24,267 @@ - + + + + + - - - + + + + Style="{StaticResource CardTitleStyle}"/> + Text="{x:Bind ViewModel.NewUserId, Mode=TwoWay}" + Style="{StaticResource DarkTextBoxStyle}"/> + PlaceholderText="Es. nomeutente" + Text="{x:Bind ViewModel.NewUsername, Mode=TwoWay}" + Style="{StaticResource DarkTextBoxStyle}"/> - - - - - + + + + + + + + + + + SelectionMode="Single" + Background="Transparent"> - - - - - - - - - - + + + + + + + + + + + + + + + + - - + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + - + + + + + + + + + + - - - - - + + + + + + + + + Text="{x:Bind ViewModel.SelectedUser.CustomBasePath, Mode=TwoWay}" + Style="{StaticResource DarkTextBoxStyle}"/> - -