-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(ui): dynamic remove doesnt decrement counter
Add a function to decrement the value of the count of videos in the playlist Closes #19
- Loading branch information
avallete
committed
Mar 24, 2021
1 parent
1568a14
commit 98e4185
Showing
5 changed files
with
104 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/** | ||
* Search into two lists of objects needles and haystack using hashmap | ||
* If all elements from needles has been found into haystack it return the hashmap | ||
* If some elements are missing into haystack, we return false. | ||
* | ||
* The hashmap keys are generated using needleGetter and haystackGetter | ||
* The needles must not contain duplicates | ||
* | ||
* @param needles unique list of element to search | ||
* @param haystack list of elements to search in | ||
* @param needleKeyGetter get the value to use as key from needles | ||
* @param haystackKeyGetter get the value to match with needle key | ||
*/ | ||
export default function listMapSearch<T, U, K extends keyof any>( | ||
needles: Array<T>, | ||
haystack: Array<U>, | ||
needleKeyGetter: (item: T) => K, | ||
haystackKeyGetter: (item: U) => K | ||
): Record<K, U> | false { | ||
const searchMap: Record<K, U | undefined> = {} as Record<K, U> | ||
// We cannot found all our needles into our haystack | ||
if (haystack.length < needles.length) { | ||
return false | ||
} | ||
// Fill our searchMap keys with needles to search | ||
for (const needle of needles) { | ||
searchMap[needleKeyGetter(needle)] = undefined | ||
} | ||
// matches elements from needles with haystack | ||
let found = 0 | ||
for (const item of haystack) { | ||
const itemKey = haystackKeyGetter(item) | ||
// if key exist in the searchMap and value is still undefined | ||
if (Object.prototype.hasOwnProperty.call(searchMap, itemKey) === true && searchMap[itemKey] === undefined) { | ||
searchMap[itemKey] = item | ||
found += 1 | ||
// early break if all elements have already been found | ||
if (found === needles.length) { | ||
return searchMap as Record<K, U> | ||
} | ||
} | ||
} | ||
return found === needles.length ? (searchMap as Record<K, U>) : false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { XPATH } from '~src/selectors' | ||
import getElementsByXpath from '~src/lib/get-elements-by-xpath' | ||
import listMapSearch from '~src/lib/list-map-search' | ||
import { PlaylistVideo } from '~src/youtube' | ||
|
||
// We don't remove but only hide the videos since | ||
// Youtube webapp use the indexes to handle some actions (remove, reorder) | ||
// and removing videos from the DOM collide with that behavior | ||
export default function hideVideosFromPlaylistUI(videosToDelete: PlaylistVideo[]) { | ||
// cast Node as any to access .data property availlable on ytd-playlist-video-renderer elements | ||
const playlistVideoRendererNodes = getElementsByXpath(XPATH.YT_PLAYLIST_VIDEO_RENDERERS) as any[] | ||
// All videos to remove MAY be present in the UI because if there is more videos to remove | ||
// than videos found into the UI, some removed videos aren't loaded in the UI | ||
if (playlistVideoRendererNodes.length >= videosToDelete.length) { | ||
const searchMap = listMapSearch( | ||
videosToDelete, | ||
playlistVideoRendererNodes, | ||
(video) => video.videoId, | ||
(node) => node.data.videoId | ||
) | ||
// if all videos to remove are present in the UI | ||
if (searchMap) { | ||
const htmlElements: HTMLElement[] = Object.values(searchMap) as HTMLElement[] | ||
for (const element of htmlElements) { | ||
// hide each item from UI | ||
element.hidden = true | ||
} | ||
return | ||
} | ||
} | ||
throw new Error('some videos are missing from the UI, cannot dynamically delete') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,10 @@ | ||
import U from '~src/userscript' | ||
|
||
export const XPATH = { | ||
APP_RENDER_ROOT: '//ytd-playlist-sidebar-renderer/div[@id="items"]/*[last()]', | ||
YT_PLAYLIST_SIDEBAR_ITEMS: '//ytd-playlist-sidebar-renderer/div[@id="items"]', | ||
YT_PLAYLIST_VIDEO_RENDERERS: '//yt-playlist-video-renderer', | ||
YT_PLAYLIST_VIDEO_RENDERERS: '//ytd-playlist-video-renderer', | ||
YT_NUMBERS_OF_VIDEOS_IN_PLAYLIST: '//ytd-playlist-sidebar-primary-info-renderer/div/yt-formatted-string/span[1]', | ||
} | ||
|
||
export const ID = { | ||
APP_ROOT: `${U.id}-root`, | ||
export default { | ||
XPATH, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters