diff --git a/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs b/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs index 3790d6d..881cb58 100644 --- a/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs +++ b/src/KeyKeeper/ViewModels/UnlockedRepositoryViewModel.cs @@ -153,6 +153,25 @@ public class UnlockedRepositoryViewModel : ViewModelBase OnPropertyChanged(nameof(Passwords)); } + public void RemoveEntryFromFavourites(PassStoreEntry entry) + { + var favouritesGroup = PasswordGroups.FirstOrDefault(g => g.GroupType == FileFormatConstants.GROUP_TYPE_FAVOURITES); + if (favouritesGroup == null) + return; + + PassStoreEntryPassword? pwd = FollowLinkIfNeeded(entry); + if (pwd == null) + return; + + var linkToRemove = pwd.Backlinks.FirstOrDefault(bl => bl is PassStoreEntryLink lnk && lnk.Parent == favouritesGroup); + if (linkToRemove != null) + { + passStore.DeleteEntry(favouritesGroup, linkToRemove.Id); + HasUnsavedChanges = true; + OnPropertyChanged(nameof(Passwords)); + } + } + public void UpdateEntry(PassStoreEntryPassword updatedEntry) { passStore.UpdateEntry(null, updatedEntry.Id, updatedEntry); diff --git a/src/KeyKeeper/Views/RepositoryWindow.axaml b/src/KeyKeeper/Views/RepositoryWindow.axaml index eb0502c..1bafe80 100644 --- a/src/KeyKeeper/Views/RepositoryWindow.axaml +++ b/src/KeyKeeper/Views/RepositoryWindow.axaml @@ -169,6 +169,8 @@ + + diff --git a/src/KeyKeeper/Views/RepositoryWindow.axaml.cs b/src/KeyKeeper/Views/RepositoryWindow.axaml.cs index 2fad556..3efe299 100644 --- a/src/KeyKeeper/Views/RepositoryWindow.axaml.cs +++ b/src/KeyKeeper/Views/RepositoryWindow.axaml.cs @@ -257,12 +257,37 @@ public partial class RepositoryWindow : Window .OfType() .FirstOrDefault(m => m.Name == "entryCtxMenuRemoveFromGroup"); + var addToFavouritesItem = contextMenu.Items + .OfType() + .FirstOrDefault(m => m.Name == "entryCtxMenuAddToFavourites"); + + var removeFromFavouritesItem = contextMenu.Items + .OfType() + .FirstOrDefault(m => m.Name == "entryCtxMenuRemoveFromFavourites"); + var isNonDefaultGroup = pageVm.SelectedPasswordGroup.GroupType != FileFormatConstants.GROUP_TYPE_DEFAULT; if (removeFromGroupItem != null) { removeFromGroupItem.IsVisible = isNonDefaultGroup; } + // Check if entry is in Favourites group + var favouritesGroup = pageVm.PasswordGroups.FirstOrDefault(g => g.GroupType == FileFormatConstants.GROUP_TYPE_FAVOURITES); + var isInFavourites = false; + if (favouritesGroup != null && _contextMenuEntry != null) + { + PassStoreEntryPassword? pwd = UnlockedRepositoryViewModel.FollowLinkIfNeeded(_contextMenuEntry); + if (pwd != null) + { + isInFavourites = pwd.Backlinks.Any(bl => bl is PassStoreEntryLink lnk && lnk.Parent == favouritesGroup); + } + } + + if (addToFavouritesItem != null) + addToFavouritesItem.IsVisible = !isInFavourites; + if (removeFromFavouritesItem != null) + removeFromFavouritesItem.IsVisible = isInFavourites; + if (addToGroupItem == null) return; @@ -408,6 +433,28 @@ public partial class RepositoryWindow : Window this.FindControlRecursive("NotificationHost")?.Show("Removed from group"); } } + else if (s.Name == "entryCtxMenuAddToFavourites") + { + if (DataContext is RepositoryWindowViewModel vm && vm.CurrentPage is UnlockedRepositoryViewModel pageVm) + { + var favouritesGroup = pageVm.PasswordGroups.FirstOrDefault(g => g.GroupType == FileFormatConstants.GROUP_TYPE_FAVOURITES); + if (favouritesGroup != null) + { + if (pageVm.AddEntryToGroup(ent, favouritesGroup)) + this.FindControlRecursive("NotificationHost")?.Show("Added to Favourites"); + else + this.FindControlRecursive("NotificationHost")?.Show("Already in Favourites"); + } + } + } + else if (s.Name == "entryCtxMenuRemoveFromFavourites") + { + if (DataContext is RepositoryWindowViewModel vm && vm.CurrentPage is UnlockedRepositoryViewModel pageVm) + { + pageVm.RemoveEntryFromFavourites(ent); + this.FindControlRecursive("NotificationHost")?.Show("Removed from Favourites"); + } + } else if (s.Name == "entryCtxMenuDelete") { if (DataContext is RepositoryWindowViewModel vm && vm.CurrentPage is UnlockedRepositoryViewModel pageVm)