|
10 | 10 | @inject ToastService toastService |
11 | 11 | @inject TransactionInfoService tis |
12 | 12 | @inject IHostApplicationLifetime applicationLifetime |
| 13 | +@inject ITelegramService ts |
13 | 14 | @using TelegramDownloader.Shared |
14 | 15 |
|
15 | 16 | <style> |
|
727 | 728 | </button> |
728 | 729 | </div> |
729 | 730 | </div> |
| 731 | + |
| 732 | + <div class="config-item"> |
| 733 | + <div class="config-item-info"> |
| 734 | + <div class="config-item-label"> |
| 735 | + <i class="bi bi-star"></i> |
| 736 | + Orphaned Favorites |
| 737 | + </div> |
| 738 | + <div class="config-item-description"> |
| 739 | + Remove favorite channels that you no longer have access to in Telegram. |
| 740 | + @if (orphanedFavoritesCount > 0) |
| 741 | + { |
| 742 | + <span class="badge bg-warning text-dark ms-2">@orphanedFavoritesCount orphaned</span> |
| 743 | + } |
| 744 | + else |
| 745 | + { |
| 746 | + <span class="badge bg-success ms-2">All good</span> |
| 747 | + } |
| 748 | + </div> |
| 749 | + </div> |
| 750 | + <div class="config-item-control"> |
| 751 | + <button type="button" class="btn btn-outline-danger btn-sm d-flex align-items-center gap-2" |
| 752 | + @onclick="CleanOrphanedFavorites" |
| 753 | + disabled="@(orphanedFavoritesCount == 0 || isCleaningFavorites)"> |
| 754 | + @if (isCleaningFavorites) |
| 755 | + { |
| 756 | + <span class="spinner-border spinner-border-sm" role="status"></span> |
| 757 | + <span>Cleaning...</span> |
| 758 | + } |
| 759 | + else |
| 760 | + { |
| 761 | + <i class="bi bi-trash3"></i> |
| 762 | + <span>Clean (@orphanedFavoritesCount)</span> |
| 763 | + } |
| 764 | + </button> |
| 765 | + </div> |
| 766 | + </div> |
730 | 767 | </div> |
731 | 768 | </div> |
732 | 769 |
|
|
797 | 834 | // FFmpeg availability |
798 | 835 | private bool ffmpegAvailable = false; |
799 | 836 |
|
| 837 | + // Orphaned favorites |
| 838 | + private int orphanedFavoritesCount = 0; |
| 839 | + private bool isCleaningFavorites = false; |
| 840 | + |
800 | 841 | protected override async Task OnInitializedAsync() |
801 | 842 | { |
802 | 843 | Model = null; |
803 | 844 | await LoadModelAsync(); |
804 | 845 | await RefreshCounters(); |
805 | 846 | RefreshImageCacheInfo(); |
806 | 847 | CheckFFmpegAvailability(); |
| 848 | + RefreshOrphanedFavoritesCount(); |
807 | 849 | } |
808 | 850 |
|
809 | 851 | private void CheckFFmpegAvailability() |
|
898 | 940 | MainLayout.OpenDatabaseMaintenanceModal(); |
899 | 941 | } |
900 | 942 |
|
| 943 | + private void RefreshOrphanedFavoritesCount() |
| 944 | + { |
| 945 | + try |
| 946 | + { |
| 947 | + orphanedFavoritesCount = 0; |
| 948 | + if (GeneralConfigStatic.config?.FavouriteChannels != null) |
| 949 | + { |
| 950 | + foreach (var channelId in GeneralConfigStatic.config.FavouriteChannels) |
| 951 | + { |
| 952 | + var (_, exists) = ts.GetChannelInfo(channelId); |
| 953 | + if (!exists) |
| 954 | + { |
| 955 | + orphanedFavoritesCount++; |
| 956 | + } |
| 957 | + } |
| 958 | + } |
| 959 | + } |
| 960 | + catch |
| 961 | + { |
| 962 | + orphanedFavoritesCount = 0; |
| 963 | + } |
| 964 | + } |
| 965 | + |
| 966 | + private async Task CleanOrphanedFavorites() |
| 967 | + { |
| 968 | + isCleaningFavorites = true; |
| 969 | + await InvokeAsync(StateHasChanged); |
| 970 | + |
| 971 | + try |
| 972 | + { |
| 973 | + var orphanedIds = new List<long>(); |
| 974 | + |
| 975 | + if (GeneralConfigStatic.config?.FavouriteChannels != null) |
| 976 | + { |
| 977 | + foreach (var channelId in GeneralConfigStatic.config.FavouriteChannels.ToList()) |
| 978 | + { |
| 979 | + var (_, exists) = ts.GetChannelInfo(channelId); |
| 980 | + if (!exists) |
| 981 | + { |
| 982 | + orphanedIds.Add(channelId); |
| 983 | + } |
| 984 | + } |
| 985 | + } |
| 986 | + |
| 987 | + // Remove all orphaned favorites |
| 988 | + foreach (var id in orphanedIds) |
| 989 | + { |
| 990 | + GeneralConfigStatic.DeleteFavouriteChannel(id); |
| 991 | + } |
| 992 | + |
| 993 | + // Save changes to database |
| 994 | + await GeneralConfigStatic.SaveChanges(db, GeneralConfigStatic.config); |
| 995 | + |
| 996 | + RefreshOrphanedFavoritesCount(); |
| 997 | + toastService.Notify(new(ToastType.Success, $"Removed {orphanedIds.Count} orphaned favorite(s)") { Title = "Success", AutoHide = true }); |
| 998 | + } |
| 999 | + catch (Exception ex) |
| 1000 | + { |
| 1001 | + toastService.Notify(new(ToastType.Danger, $"Error cleaning favorites: {ex.Message}") { Title = "Error", AutoHide = true }); |
| 1002 | + } |
| 1003 | + |
| 1004 | + isCleaningFavorites = false; |
| 1005 | + await InvokeAsync(StateHasChanged); |
| 1006 | + } |
| 1007 | + |
901 | 1008 | private void RefreshImageCacheInfo() |
902 | 1009 | { |
903 | 1010 | try |
|
0 commit comments