For reference, the source code is in `~/src/rithik-b/PlaylistManager`. Here is how “add this map to a playlist” is wired in this repo. ### 1. User clicks Add (opens the picker) The Add button on the level detail screen calls `AddPlaylistModalController.ShowModal()`: ```64:70:PlaylistManager/UI/ViewControllers/LevelDetailButtonsViewController.cs [UIAction("add-button-click")] private void OpenAddModal() { addPlaylistController.ShowModal(); } ``` `ShowModal` parses the BSML if needed, opens the modal, and lists playlists from the default lib manager: ```97:103:PlaylistManager/UI/ViewControllers/AddPlaylistModalController.cs internal void ShowModal() { Parse(); parserParams.EmitEvent("close-modal"); parserParams.EmitEvent("open-modal"); ShowPlaylistsForManager(PlaylistLibUtils.playlistManager); } ``` ### 2. User picks a playlist row — that is where the map is actually added The real work is in `AddPlaylistModalController.OnCellSelect`: after navigating folders, choosing a playlist calls **`IPlaylist.Add(...)`** from **BeatSaberPlaylistsLib**, then persists and notifies: ```165:204:PlaylistManager/UI/ViewControllers/AddPlaylistModalController.cs [UIAction("select-cell")] private void OnCellSelect(TableView tableView, int index) { playlistTableData.TableView.ClearSelection(); // Folder Selected if (index < childManagers.Count) { ShowPlaylistsForManager(childManagers[index]); } else { index -= childManagers.Count; var selectedPlaylist = childPlaylists[index]; IPlaylistSong playlistSong; if (HighlightDifficulty) { playlistSong = selectedPlaylist.Add(standardLevelDetailViewController.beatmapLevel, standardLevelDetailViewController.beatmapKey); } else { playlistSong = selectedPlaylist.Add(standardLevelDetailViewController.beatmapLevel); } try { selectedPlaylist.RaisePlaylistChanged(); parentManager.StorePlaylist(selectedPlaylist); popupModalsController.ShowOkModal(modalTransform, string.Format("Song successfully added to {0}", selectedPlaylist.Title), null, animateParentCanvas: false); // TODO: Doesn't refresh the sprite. Events.RaisePlaylistSongAdded(playlistSong, selectedPlaylist); } catch (Exception e) { popupModalsController.ShowOkModal(modalTransform, "An error occured while adding song to playlist.", null, animateParentCanvas: false); Plugin.Log.Critical(string.Format("An exception was thrown while adding a song to a playlist.\nException Message: {0}", e.Message)); } finally { ShowPlaylistsForManager(parentManager); } } } ``` So: - **PlaylistManager code**: `AddPlaylistModalController.OnCellSelect` (orchestration, UI, `StorePlaylist`, `Events.RaisePlaylistSongAdded`). - **Library code**: `selectedPlaylist.Add(...)` — implementation of how the entry is stored lives in **BeatSaberPlaylistsLib** (`IPlaylist`), not in this repository. There is no other `.Add(` on a playlist for this flow in the grep results; removing a song is the parallel path in `LevelDetailButtonsViewController.RemoveSong()`. ## hooking into the process ### 1. Subscribe to PlaylistManager’s public event (simplest) After a successful add from the **Add to playlist** UI, PlaylistManager raises a **public static** event: ```16:18:PlaylistManager/Utilities/Events.cs /// /// Raised when an is added to an /// public static event Action playlistSongAdded; ``` It is invoked **after** `RaisePlaylistChanged()` and `StorePlaylist()` succeed: ```187:194:PlaylistManager/UI/ViewControllers/AddPlaylistModalController.cs try { selectedPlaylist.RaisePlaylistChanged(); parentManager.StorePlaylist(selectedPlaylist); popupModalsController.ShowOkModal(modalTransform, string.Format("Song successfully added to {0}", selectedPlaylist.Title), null, animateParentCanvas: false); // TODO: Doesn't refresh the sprite. Events.RaisePlaylistSongAdded(playlistSong, selectedPlaylist); } ``` In your plugin: add a **reference to `PlaylistManager.dll`**, a **manifest dependency** on PlaylistManager, then subscribe in `OnEnable` (or menu init) and unsubscribe in `OnDisable`: - Namespace: `PlaylistManager.Utilities` - Type: `Events` - Event: `playlistSongAdded` - Handler signature: `(IPlaylistSong song, IPlaylist playlist)` from `BeatSaberPlaylistsLib.Types` **Caveat:** This is only raised for adds that go through **this** code path. It is the **only** `RaisePlaylistSongAdded` call site in the repo, so adds done only via BeatSaberPlaylistsLib (or another mod) will **not** fire this event.