From c0463c0d5e0faceda8ef04cc38e469d082096569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=84min=20Baumeler?= Date: Mon, 13 Oct 2025 22:07:26 +0200 Subject: [PATCH] imprv: faster playlist handling and a few bugs fixed --- src/main.sh | 25 ++++++++++++--- src/sh/awk.sh | 1 + src/sh/cache.sh | 50 +++++++++++++++++++++++++++++ src/sh/lists.sh | 15 +++++++++ src/sh/local.sh | 52 ++++-------------------------- src/sh/playlist.sh | 80 +++++++++++++++++++++++++++++++++++++--------- src/sh/theme.sh | 42 +++++++++++++----------- 7 files changed, 183 insertions(+), 82 deletions(-) diff --git a/src/main.sh b/src/main.sh index 4b2f068..16b4346 100755 --- a/src/main.sh +++ b/src/main.sh @@ -426,6 +426,12 @@ case "${1:-}" in stored_playlists exit 0 ;; +"--print-playlist") + # Pretty print playlist + list_playlist_stored "${2:-}" | + cut -d "$(printf '\t')" -f 1 + exit 0 + ;; "--help") # Print help string cat < Show release given by --playlists List stored playlists and exit --load-playlist Load specified playlist + --print-playlist Print specified playlist and exit MANAGE LOCAL MUSIC: --decorate Decorate directory containing a tagged release @@ -541,7 +548,10 @@ export LOCKFILE RESULTS PIDFILE mpv_start # Playback possible now -[ "${1:-}" = "--load-playlist" ] && $0 --playlist "$PLAYLIST_CMD_LOAD" "${2:-}" +if [ "${1:-}" = "--load-playlist" ]; then + sleep 1 + $0 --playlist "$PLAYLIST_CMD_LOAD" "${2:-}" +fi # main loop # states are stored in (in)visible labels @@ -655,7 +665,7 @@ while true; do sel=$( stored_playlists | $FZF \ --border=double \ - --border-label="$TITLE_PLYLST_LIST" \ + --border-label="$TITLE_PLYLST_STORE" \ --margin="2%,10%" \ --bind="$KEYS_I_NORMAL:" \ --bind="$KEYS_DOWN:down" \ @@ -666,9 +676,16 @@ while true; do --bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_PLAYLIST_PLAYLISTSTORE" \ --bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \ --bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \ + --bind="$KEYS_PREVIEW_TOGGLE_WRAP:toggle-preview-wrap" \ + --bind="$KEYS_PREVIEW_TOGGLE_SIZE:change-preview-window(right,90%,border-line,nowrap|$FZF_DEFAULT_PREVIEW_WINDOW)" \ + --bind="$KEYS_PREVIEW_OPEN:show-preview" \ --bind="$KEYS_PREVIEW_CLOSE:hide-preview" \ - --bind="$KEYS_PLAYLISTSTORE_SELECT:transform:[ {1} ] && $0 --playlist $PLAYLIST_CMD_LOAD {1} && echo accept" \ - --bind="$KEYS_PLAYLISTSTORE_DELETE:transform:[ {1} ] && rm \"$PLAYLIST_DIRECTORY/{r1}\" && echo \"reload($0 --playlists\)\"" \ + --bind="$KEYS_PLAYLISTSTORE_SELECT:transform:[ {1} ] && $0 --playlist $PLAYLIST_CMD_LOAD {2} && echo accept" \ + --bind="$KEYS_PLAYLISTSTORE_DELETE:transform:[ {1} ] && rm \"$PLAYLIST_DIRECTORY/{r2}\" && echo \"reload($0 --playlists\)\"" \ + --preview="$0 --print-playlist {2}" \ + --preview-window="$FZF_DEFAULT_PREVIEW_WINDOW" \ + --with-nth="{1}" \ + --delimiter="\t" \ --wrap-sign="" || true ) VIEW="$VIEW_PLAYLIST" diff --git a/src/sh/awk.sh b/src/sh/awk.sh index 8cd89df..ee528b7 100644 --- a/src/sh/awk.sh +++ b/src/sh/awk.sh @@ -115,6 +115,7 @@ awk_releasegroups() { -v hassecondary_yes="$RGV_FMT_HASSECONDARY_YES" \ -v hassecondary_no="$RGV_FMT_HASSECONDARY_NO" \ -v fmtsecondary="$RGV_FMT_SECONDARY" \ + -v secondary_compilation="$RGV_FMT_SECONDARY_COMPILATION" \ -v secondary_soundtrack="$RGV_FMT_SECONDARY_SOUNDTRACK" \ -v secondary_spokenword="$RGV_FMT_SECONDARY_SPOKENWORD" \ -v secondary_interview="$RGV_FMT_SECONDARY_INTERVIEW" \ diff --git a/src/sh/cache.sh b/src/sh/cache.sh index 61c5111..23f3540 100644 --- a/src/sh/cache.sh +++ b/src/sh/cache.sh @@ -238,6 +238,18 @@ cache_get_file_batch() { awk -v dir="$CACHEDIR/$1/" -v f="/$fn" '{ print dir $0 f }' } +# Detect missing cache files +# +# @argument $1: type +# @argument $2: path to list with MusicBrainz IDs +# +# This method returns a nonzero value if some MusicBrainz objects listed in $2 +# are not cached. +cached() { + cache_get_file_batch "$1" <"$2" | + xargs -d '\n' ls >/dev/null 2>&1 || return 1 +} + # Print MusicBrainz ID associated to the file paths # # This reads from stdin any number of paths (one per line) @@ -295,3 +307,41 @@ cache_rm_release() { info "Removing $d from cache" rm -rf "$d" } + +# Load missing cache entries (batch mode) +# +# argument $1: type +# +# This method reads one MusicBrainz IDs of the specified type from stdin (one +# per line), and fetches the missing items. +batch_load_missing() { + tmpf=$(mktemp) + cat | + cache_get_file_batch "$1" | + xargs -d '\n' \ + sh -c 'for f; do [ -e "$f" ] || echo "$f"; done' _ | + cache_mbid_from_path_batch >"$tmpf" + lines=$(wc -l "$tmpf" | cut -d ' ' -f 1) + if [ "$lines" -gt 0 ]; then + case "$1" in + "$TYPE_ARTIST") tt="artists" ;; + "$TYPE_RELEASEGROUP") tt="release groups" ;; + "$TYPE_RELEASE") tt="releases" ;; + esac + info "Fetching missing $tt" + cnt=0 + while IFS= read -r mbid; do + case "$1" in + "$TYPE_ARTIST") + name=$(mb_artist "$mbid" | $JQ '.name') + ;; + "$TYPE_RELEASEGROUP") name=$(mb_releasegroup "$mbid" | $JQ '.title') ;; + "$TYPE_RELEASE") name=$(mb_release "$mbid" | $JQ '.title') ;; + esac + cnt=$((cnt + 1)) + info "$(printf "%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$name")" + sleep 1 + done <"$tmpf" + fi + rm -f "$tmpf" +} diff --git a/src/sh/lists.sh b/src/sh/lists.sh index f3fc0f1..3d782ba 100644 --- a/src/sh/lists.sh +++ b/src/sh/lists.sh @@ -98,6 +98,7 @@ list_artists_from_json() { # Print playlist currently loaded list_playlist() { count=$(mpv_playlist_count) + [ "$count" ] || return 0 [ "$count" -eq 0 ] && return 0 mpvquery="" for i in $(seq 0 $((count - 1))); do @@ -105,3 +106,17 @@ list_playlist() { done __mpv_get "$mpvquery" | grep '.' | awk_playlist } + +# List stored playlist +# +# @argument $1: paylist name +list_playlist_stored() { + t=$(mktemp) + r=$(mktemp) + generate_playlist_stored "$PLAYLIST_DIRECTORY/$1" | + grep "$(printf '\t')" | + cut -d "," -f 2- >"$t" + grep -v "/dev/null$" "$t" | cut -d "$(printf '\t')" -f 2 >"$r" + awk_recordings "$r" <"$t" + rm -f "$t" "$r" +} diff --git a/src/sh/local.sh b/src/sh/local.sh index 26915f4..f4a70ab 100644 --- a/src/sh/local.sh +++ b/src/sh/local.sh @@ -183,44 +183,6 @@ END { for (i in id) print title[i], id[i], fname[i] } return 0 } -# Load missing cache entries (batch mode) -# -# argument $1: type -# -# This method reads one MusicBrainz IDs of the specified type from stdin (one -# per line), and fetches the missing items. -__batch_load_missing() { - tmpf=$(mktemp) - cat | - cache_get_file_batch "$1" | - xargs \ - sh -c 'for f; do [ -e "$f" ] || echo "$f"; done' _ | - cache_mbid_from_path_batch >"$tmpf" - lines=$(wc -l "$tmpf" | cut -d ' ' -f 1) - if [ "$lines" -gt 0 ]; then - case "$1" in - "$TYPE_ARTIST") tt="artists" ;; - "$TYPE_RELEASEGROUP") tt="release groups" ;; - "$TYPE_RELEASE") tt="releases" ;; - esac - info "Fetching missing $tt" - cnt=0 - while IFS= read -r mbid; do - case "$1" in - "$TYPE_ARTIST") - name=$(mb_artist "$mbid" | $JQ '.name') - ;; - "$TYPE_RELEASEGROUP") name=$(mb_releasegroup "$mbid" | $JQ '.title') ;; - "$TYPE_RELEASE") name=$(mb_release "$mbid" | $JQ '.title') ;; - esac - cnt=$((cnt + 1)) - info "$(printf "%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$name")" - sleep 1 - done <"$tmpf" - fi - rm -f "$tmpf" -} - # Precompute lists # # The main views (VIEW_ARTIST and TYPE_RELEASEGROUP) for locally available @@ -278,7 +240,7 @@ reloaddb() { tmpreleases=$(mktemp) cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" | tee "$tmpreleases" | - __batch_load_missing "$TYPE_RELEASE" + batch_load_missing "$TYPE_RELEASE" tmpreleasefiles=$(mktemp) cache_get_file_batch "$TYPE_RELEASE" <"$tmpreleases" >"$tmpreleasefiles" ( @@ -299,8 +261,8 @@ reloaddb() { ) & wait rm -f "$tmpreleases" "$tmpreleasefiles" - __batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" - __batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" + batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" + batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" __precompute_lists } @@ -311,8 +273,8 @@ reloaddb() { # derivation of the MusicBrainz artist IDs and MusicBrainz release-group IDs # from the MusicBrainz releases (see the `reloaddb` method above). local_files_present() { - cache_get_file_batch "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" | xargs ls >/dev/null 2>&1 || return 1 - cache_get_file_batch "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" | xargs ls >/dev/null 2>&1 || return 1 + cached "$TYPE_ARTIST" "$LOCALDATA_ARTISTS" || return 1 + cached "$TYPE_RELEASEGROUP" "$LOCALDATA_RELEASEGROUPS" || return 1 } # Load missing files @@ -320,6 +282,6 @@ local_files_present() { # If missing files were detected with `local_files_present`, then these missing # files may be cached using the present method. load_missing_files() { - __batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" - __batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" + batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" + batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" } diff --git a/src/sh/playlist.sh b/src/sh/playlist.sh index e291914..3154ec4 100644 --- a/src/sh/playlist.sh +++ b/src/sh/playlist.sh @@ -29,7 +29,7 @@ fi # # This prints the names of the stored playlists. stored_playlists() { - find "$PLAYLIST_DIRECTORY" -mindepth 1 -maxdepth 1 -type f -printf '%f\n' | + find "$PLAYLIST_DIRECTORY" -mindepth 1 -maxdepth 1 -type f -printf "$PLYSTORE_PLAYLIST\t%f\n" | sort } @@ -78,15 +78,23 @@ generate_playlist() { map("#EXTINF:" + .length + "," + .t + "\n" + $base + "/" + .file)[]' } -# Generate playlist content from stored playlist +# Generate m3u playlist from stored playlist # # @argument $1: Playlist file generate_playlist_stored() { f="${1:-}" [ -s "$f" ] || return - tab="$(printf '\t')" - PLAYLISTSTART="#EXTM3U" - printf "%s\n" "$PLAYLISTSTART" + # Check that we have all releases cached, else fetch missing ones + relf=$(mktemp) + cut -d "$(printf '\t')" -f 1 "$f" >"$relf" + cached "$TYPE_RELEASE" "$relf" || batch_load_missing "$TYPE_RELEASE" <"$relf" + jrelf=$(mktemp) + # Write json file with all releases + cache_get_file_batch "$TYPE_RELEASE" <"$relf" | + xargs -d '\n' cat >"$jrelf" + # Get associated decorations and write json file with all decorations + jpf=$(mktemp) + jdecf=$(mktemp) awk -F '\t' \ -v rfile="$LOCALDATA_RELEASES" \ 'BEGIN { @@ -94,17 +102,59 @@ generate_playlist_stored() { while ((getline < rfile) == 1) release[$1] = $2 close(rfile) + print "[" } - { - if (release[$1]) - print $1, release[$1], $2 - }' <"$f" | - while IFS= read -r line; do - rid=$(echo "$line" | cut -d "$tab" -f 1) - path=$(echo "$line" | cut -d "$tab" -f 2) - tid=$(echo "$line" | cut -d "$tab" -f 3) - generate_playlist "$rid" "$path" "$tid" - done | grep -v "^$PLAYLISTSTART$" + NR > 1 { print "," } + { print "{\"rid\":\"" $1 "\",\"tid\":\"" $2 "\",\"deco\":\"" (release[$1] ? release[$1] : "") "\"}" } + END {print "]"}' <"$f" >"$jpf" + $JQ 'map(.deco) | join("\n")' "$jpf" | + grep '.' | + xargs -d '\n' cat >"$jdecf" + # Merge all data using jq and print playlist + printf "#EXTM3U\n" + $JQ \ + --slurpfile deco "$jdecf" \ + --slurpfile mb "$jrelf" \ + '$deco as $decorations | + $mb as $releases | + map( + . as $item | + first( + if ($item.deco | length) > 0 then + ($item.deco | sub("/[^/]+$"; "")) as $base | + first($deco[] | select(.releaseid == $item.rid).tracks | to_entries[] | select(.key == $item.tid).value) as $fn | + $base + "/" + $fn + else + "/dev/null" + end + ) as $p | + first( + $mb[] | select(.id == $item.rid).media[].tracks[] | select(.id == $item.tid) + ) as $track | + ( + $track.length // 0 / 1000 | round | tostring + ) as $length | + ( if ($item.deco | length) > 0 then $item.deco else "/dev/null" end) as $d | + $item + { + path: $p, + length: $length, + t: [ + $item.rid, + $item.tid, + "", + "", + "", + $length, + $track.title, + ($track."artist-credit" | map([.name, .joinphrase] | join("")) | join("")), + $d + ] | join("\t") + } + ) | + map("#EXTINF:" + .length + "," + .t + "\n" + .path)[]' \ + "$jpf" + # Clean up + rm -f "$relf" "$jrelf" "$jpf" "$jdecf" } # Run playback commands diff --git a/src/sh/theme.sh b/src/sh/theme.sh index 92bf535..8c51ff6 100644 --- a/src/sh/theme.sh +++ b/src/sh/theme.sh @@ -19,6 +19,7 @@ if [ ! "${THEME_LOADED:-}" ]; then CNOTE="${ESC}[38;5;242m" CXXX="${ESC}[38;5;109m" CDESC="${ESC}[38;5;254m" + CPURPLE="${ESC}[38;5;213m" CKB="${ESC}[38;5;224m" OFF="${ESC}[m" @@ -99,6 +100,7 @@ if [ ! "${THEME_LOADED:-}" ]; then RGV_FMT_HASSECONDARY_YES="${RGV_FMT_HASSECONDARY_YES:-"☼"}" RGV_FMT_HASSECONDARY_NO="${RGV_FMT_HASSECONDARY_NO:-""}" RGV_FMT_SECONDARY="${RGV_FMT_SECONDARY:-"${CNOTE}[☼: %s]${OFF}"}" + RGV_FMT_SECONDARY_COMPILATION="${RGV_FMT_SECONDARY_COMPILATION:-"🧩 compilation"}" RGV_FMT_SECONDARY_SOUNDTRACK="${RGV_FMT_SECONDARY_SOUNDTRACK:-"🎬 soundtrack"}" RGV_FMT_SECONDARY_SPOKENWORD="${RGV_FMT_SECONDARY_SPOKENWORD:-"📖 spokenword"}" RGV_FMT_SECONDARY_INTERVIEW="${RGV_FMT_SECONDARY_INTERVIEW:-"💬 interview"}" @@ -117,12 +119,13 @@ if [ ! "${THEME_LOADED:-}" ]; then RGV_FMT_FLAG_NO_LOCAL RGV_FMT_TYPE_SINGLE RGV_FMT_TYPE_ALBUM \ RGV_FMT_TYPE_EP RGV_FMT_TYPE_BROADCAST RGV_FMT_TYPE_OTHER \ RGV_FMT_TYPE_UNKNOWN RGV_FMT_HASSECONDARY_YES RGV_FMT_HASSECONDARY_NO \ - RGV_FMT_SECONDARY RGV_FMT_SECONDARY_SOUNDTRACK \ - RGV_FMT_SECONDARY_SPOKENWORD RGV_FMT_SECONDARY_INTERVIEW \ - RGV_FMT_SECONDARY_AUDIOBOOK RGV_FMT_SECONDARY_AUDIODRAMA \ - RGV_FMT_SECONDARY_LIVE RGV_FMT_SECONDARY_REMIX RGV_FMT_SECONDARY_DJMIX \ - RGV_FMT_SECONDARY_MIXTAPE RGV_FMT_SECONDARY_DEMO \ - RGV_FMT_SECONDARY_FIELDREC RGV_FMT_TITLE RGV_FMT_ARTIST RGV_FMT_YEAR + RGV_FMT_SECONDARY RGV_FMT_SECONDARY_COMPILATION \ + RGV_FMT_SECONDARY_SOUNDTRACK RGV_FMT_SECONDARY_SPOKENWORD \ + RGV_FMT_SECONDARY_INTERVIEW RGV_FMT_SECONDARY_AUDIOBOOK \ + RGV_FMT_SECONDARY_AUDIODRAMA RGV_FMT_SECONDARY_LIVE \ + RGV_FMT_SECONDARY_REMIX RGV_FMT_SECONDARY_DJMIX \ + RGV_FMT_SECONDARY_MIXTAPE RGV_FMT_SECONDARY_DEMO RGV_FMT_SECONDARY_FIELDREC \ + RGV_FMT_TITLE RGV_FMT_ARTIST RGV_FMT_YEAR # Release view # ============ @@ -172,7 +175,7 @@ if [ ! "${THEME_LOADED:-}" ]; then # <> string Track duration REC_FMT="${REC_FMT:-"<>\t<>\t<>\t<>\t<<artist>>\t<<duration>>"}" REC_FMT_CNT=$(($(printf "$REC_FMT" | tr -cd '\t' | wc -c) + 1)) - REC_FMT_RIGHTALIGN="${REC_FMT_RIGHTALIGN:-"1,2,3,6"}" + REC_FMT_RIGHTALIGN="${REC_FMT_RIGHTALIGN:-"1,2,3"}" REC_FMT_FLAG_LOCAL="${REC_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}" REC_FMT_FLAG_NO_LOCAL="${REC_FMT_FLAG_NO_LOCAL:-""}" REC_FMT_MEDIA="${REC_FMT_MEDIA:-"${CNOTE}${FAINT}%s${OFF}"}" @@ -237,6 +240,7 @@ if [ ! "${THEME_LOADED:-}" ]; then HEADER_RG_FMT_HASSECONDARY_YES="${HEADER_RG_FMT_HASSECONDARY_YES:-"$RGV_FMT_HASSECONDARY_YES"}" HEADER_RG_FMT_HASSECONDARY_NO="${HEADER_RG_FMT_HASSECONDARY_NO:-"$RGV_FMT_HASSECONDARY_NO"}" HEADER_RG_FMT_SECONDARY="${HEADER_RG_FMT_SECONDARY:-"$RGV_FMT_SECONDARY"}" + HEADER_RG_FMT_SECONDARY_COMPILATION="${HEADER_RG_FMT_SECONDARY_COMPILATION:-"$RGV_FMT_SECONDARY_COMPILATION"}" HEADER_RG_FMT_SECONDARY_SOUNDTRACK="${HEADER_RG_FMT_SECONDARY_SOUNDTRACK:-"$RGV_FMT_SECONDARY_SOUNDTRACK"}" HEADER_RG_FMT_SECONDARY_SPOKENWORD="${HEADER_RG_FMT_SECONDARY_SPOKENWORD:-"$RGV_FMT_SECONDARY_SPOKENWORD"}" HEADER_RG_FMT_SECONDARY_INTERVIEW="${HEADER_RG_FMT_SECONDARY_INTERVIEW:-"$RGV_FMT_SECONDARY_INTERVIEW"}" @@ -257,13 +261,13 @@ if [ ! "${THEME_LOADED:-}" ]; then HEADER_RG_FMT_TYPE_BROADCAST HEADER_RG_FMT_TYPE_OTHER \ HEADER_RG_FMT_TYPE_UNKNOWN HEADER_RG_FMT_HASSECONDARY_YES \ HEADER_RG_FMT_HASSECONDARY_NO HEADER_RG_FMT_SECONDARY \ - HEADER_RG_FMT_SECONDARY_SOUNDTRACK HEADER_RG_FMT_SECONDARY_SPOKENWORD \ - HEADER_RG_FMT_SECONDARY_INTERVIEW HEADER_RG_FMT_SECONDARY_AUDIOBOOK \ - HEADER_RG_FMT_SECONDARY_AUDIODRAMA HEADER_RG_FMT_SECONDARY_LIVE \ - HEADER_RG_FMT_SECONDARY_REMIX HEADER_RG_FMT_SECONDARY_DJMIX \ - HEADER_RG_FMT_SECONDARY_MIXTAPE HEADER_RG_FMT_SECONDARY_DEMO \ - HEADER_RG_FMT_SECONDARY_FIELDREC HEADER_RG_FMT_TITLE HEADER_RG_FMT_ARTIST \ - HEADER_RG_FMT_YEAR + HEADER_RG_FMT_SECONDARY_COMPILATION HEADER_RG_FMT_SECONDARY_SOUNDTRACK \ + HEADER_RG_FMT_SECONDARY_SPOKENWORD HEADER_RG_FMT_SECONDARY_INTERVIEW \ + HEADER_RG_FMT_SECONDARY_AUDIOBOOK HEADER_RG_FMT_SECONDARY_AUDIODRAMA \ + HEADER_RG_FMT_SECONDARY_LIVE HEADER_RG_FMT_SECONDARY_REMIX \ + HEADER_RG_FMT_SECONDARY_DJMIX HEADER_RG_FMT_SECONDARY_MIXTAPE \ + HEADER_RG_FMT_SECONDARY_DEMO HEADER_RG_FMT_SECONDARY_FIELDREC \ + HEADER_RG_FMT_TITLE HEADER_RG_FMT_ARTIST HEADER_RG_FMT_YEAR # Header that displays the release (based on release view) HEADER_R_FMT="${HEADER_R_FMT:-"🎤\t<<artist>> 》<<title>> 〉<<tracks>> ${CRELINFO}tx${OFF} <<media>> | <<label>> <<country>> <<year>>"}" @@ -387,11 +391,13 @@ if [ ! "${THEME_LOADED:-}" ]; then KBF_DESC="${KBF_DESC:-"${CKB}%s${OFF}"}" export KBF_GROUP KBF_KEY KBF_DESC - # Playlist title - # ============== + # Playlist title and playlist store + # ================================= TITLE_PLYLST="${TITLE_PLYLST:-" 🎶 ${CARTIST}Playlist${OFF} "}" - TITLE_PLYLST_LIST="${TITLE_PLYLST_LIST:-" 🎶 ${CARTIST}Stored Playlists${OFF} "}" - export TITLE_PLYLST TITLE_PLYLST_LIST + TITLE_PLYLST_STORE="${TITLE_PLYLST_STORE:-" 🎶 ${CARTIST}Stored Playlists${OFF} "}" + # In the following %f is the file name + PLYSTORE_PLAYLIST="${PLYSTORE_PLAYLIST:-"🎼 ${CPURPLE}%f${OFF}"}" + export TITLE_PLYLST TITLE_PLYLST_STORE PLYSTORE_PLAYLIST export THEME_LOADED=1 fi