Skip to content

Commit

Permalink
Fix multiple hooks and extensions breaking on new Spotify (Solves #845)…
Browse files Browse the repository at this point in the history
… (#945)

* Changed Custom app React symbols regex to match change in spotify client

* Fix React hook

* Fix Spicetify.Platform / API hook

* Fix Spicetify.Player.getProgress() and getProgressPercent

* Fix getProgress() continuing when music is paused

* Cleanup loop

* Disable sentry hooks regardless of config

* Reimplement hooks: Spicetify.ReactComponent -> ContextMenu, RightClickMenu, and Menu

* Fix loopyLoop.js

Co-authored-by: Adrian <[email protected]>
  • Loading branch information
itsmeow and Adrian authored Aug 17, 2021
1 parent 2a3e382 commit 732d0c5
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Extensions/loopyLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/// <reference path="../globals.d.ts" />

(function LoopyLoop(){
const bar = document.querySelector(".playback-bar .progress-bar");
const bar = document.querySelector(".playback-bar > div:nth-child(2)");
if (!bar) {
setTimeout(LoopyLoop, 100);
return;
Expand Down
4 changes: 2 additions & 2 deletions jsHelper/spicetifyWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ const Spicetify = {
}
Spicetify.Player.origin.seekTo(p);
},
getProgress: () => Spicetify.Player.origin._state.position,
getProgressPercent: () => (Spicetify.Player.origin._state.position/Spicetify.Player.origin._state.duration),
getProgress: () => (Spicetify.Player.origin._state.isPaused ? 0 : Date.now() - Spicetify.Player.origin2.state.position.timestamp) + Spicetify.Player.origin2.state.position.position,
getProgressPercent: () => (Spicetify.Player.getProgress()/Spicetify.Player.origin._state.duration),
getDuration: () => Spicetify.Player.origin._state.duration,
setVolume: (v) => { Spicetify.Player.origin.setVolume(v) },
increaseVolume: () => { Spicetify.Player.origin.setVolume(Spicetify.Player.getVolume() + 0.15) },
Expand Down
6 changes: 3 additions & 3 deletions src/apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func insertCustomApp(jsPath string, flags Flag) {
"Custom app React symbols",
content,
[]string{
`lazy\(\(\(\)=>(\w+)\.(\w+)\(\d+\).then\(\w+\.bind\(\w+,\d+\)\)\)\)`})
`lazy\(\(function\(\)\{return (\w+)\.(\w+)\(\d+\).then\(\w+\.bind\(\w+,\d+\)\)\}\)\)`})
eleSymbs := utils.FindSymbol(
"Custom app React Element",
content,
Expand All @@ -176,7 +176,7 @@ func insertCustomApp(jsPath string, flags Flag) {
appNameArray += fmt.Sprintf(`"%s",`, app)

appReactMap += fmt.Sprintf(
`,spicetifyApp%d=Spicetify.React.lazy((()=>%s.%s("%s").then(%s.bind(%s,"%s"))))`,
`,spicetifyApp%d=Spicetify.React.lazy((function(){return %s.%s("%s").then(%s.bind(%s,"%s"))}))`,
index, reactSymbs[0], reactSymbs[1],
appName, reactSymbs[0], reactSymbs[0], appName)

Expand All @@ -194,7 +194,7 @@ func insertCustomApp(jsPath string, flags Flag) {

utils.ReplaceOnce(
&content,
`lazy\(\(\(\)=>[\w\.]+\(\d+\)\.then\(\w+\.bind\(\w+,\d+\)\)\)\)`,
`lazy\(\(function\(\)\{return [\w\.]+\(\d+\).then\(\w+\.bind\(\w+,\d+\)\)\}\)\)`,
`${0}`+appReactMap)

utils.ReplaceOnce(
Expand Down
43 changes: 21 additions & 22 deletions src/preprocess/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package preprocess

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
Expand Down Expand Up @@ -198,8 +199,9 @@ func colorVariableReplaceForJS(content string) string {

func disableSentry(input string) string {
// utils.Replace(&input, `sentry\.install\(\)[,;]`, "")
utils.Replace(&input, `;if\(\w+\.type===\w+\.\w+\.LOG_INTERACTION`, ";return${0}")
utils.Replace(&input, `\("https://\[email protected]/\d+"`, `;("https://[email protected]/0"`)
// TODO Broken hooks
//utils.Replace(&input, `;if\(\w+\.type===\w+\.\w+\.LOG_INTERACTION`, ";return${0}")
//utils.Replace(&input, `\("https://\[email protected]/\d+"`, `;("https://[email protected]/0"`)
return input
}

Expand Down Expand Up @@ -258,40 +260,37 @@ func exposeAPIs_main(input string) string {
`\w+\(\)\.createElement\(\w+,\{onChange:this\.handleSaberStateChange\}\),`,
"")

utils.Replace(
// React Hook
utils.ReplaceOnce(
&input,
`;class \w+ extends (\w+)\(\).Component`,
`;Spicetify.React=${1}()${0}`)
`\w+=\(\w+,(\w+)\.lazy\)\(\(function\(\)\{return Promise\.resolve\(\)\.then\(\w+\.bind\(\w+,\w+\)\)\}\)\);`,
`${0}Spicetify.React=${1};`)

utils.Replace(
&input,
`"data-testid":`,
`"":`)

reAllAPIPromises := regexp.MustCompile(`await Promise.all\(\[([\w\(\)\.,]+?)\]\)([;,])`)
reAllAPIPromises := regexp.MustCompile(`return (\w+=\w+\.sent),\w+\.next=\d,(Promise.all\(\[(\w\.getSession\(\),)([\w\(\)\.,]+?)\]\))([;,])`)
allAPIPromises := reAllAPIPromises.FindAllStringSubmatch(input, -1)
for _, found := range allAPIPromises {
splitted := strings.Split(found[1], ",")
splitted := strings.Split(found[3] + found[4], ",")
if len(splitted) > 15 { // Actual number is about 24
re := regexp.MustCompile(`\w+\.(\w+)\(\)`)
code := "Spicetify.Platform = {"
// set t = e.sent, call Promise.all for APIs, then add Spicetify APIs to object
code := found[1] + ";" + found[2] + ".then(v => {Spicetify.Platform = {};"

for _, apiFunc := range splitted {
for apiFuncIndex, apiFunc := range splitted {
name := re.ReplaceAllString(apiFunc, `${1}`)

if strings.HasPrefix(name, "get") {
name = strings.Replace(name, "get", "", 1)
}

code += name + ": await " + apiFunc + ","
code += "Spicetify.Platform[\"" + name + "\"] = v[" + fmt.Sprint(apiFuncIndex) + "];"
}

code += "};"
if found[2] == "," { // Future proof
code = "undefined;" + code + "var "
}

input = strings.Replace(input, found[0], found[0]+code, 1)
code += "});"
// Promise.all(...).then(...); return t = e.sent, e.next = 6, Promise.all(...);
input = strings.Replace(input, found[0], code + found[0], 1)
}
}

Expand All @@ -313,14 +312,14 @@ Spicetify.React.useEffect(() => {
// React Component: Context Menu and Right Click Menu
utils.Replace(
&input,
`(const \w+)(=\w+=>\w+\(\)\.createElement\(([\w\.]+),\w+\(\)\(\{\},\w+,\{action:"open",trigger:"right-click"\}\)\)\})`,
`Spicetify.ReactComponent.ContextMenu=${3};${1}=Spicetify.ReactComponent.RightClickMenu${2}`)
`return (\w+\(\)\.createElement\(([\w\.]+),\w+\(\)\(\{\},\w+,\{action:"open",trigger:"right-click"\}\)\))`,
`Spicetify.ReactComponent.ContextMenu=${2};Spicetify.ReactComponent.RightClickMenu=${1};return Spicetify.ReactComponent.RightClickMenu`)

// React Component: Context Menu - Menu
utils.Replace(
&input,
`=\(\{children:\w+,onClose:\w+,getInitialFocusElement:\w+\}\)`,
`=Spicetify.ReactComponent.Menu${0}`)
`return (\w+\(\)\.createElement\("ul",\w+\(\)\(\{tabIndex:-?\d+,ref:\w+,role:"menu","data-depth":\w+\},\w+\),\w+\))`,//`\w+\(\)\.createElement\([\w\.]+,\{onClose:[\w\.]+,getInitialFocusElement:`,//`\w+\(\)\.createElement\([\w\.]+,\{className:[\w\.]+,onClose:[\w\.]+,onKeyDown:[\w\.]+,onKeyUp:[\w\.]+,getInitialFocusElement:[\w\.]+\},[\w\.]+\)`,
`return Spicetify.ReactComponent.Menu=${1}`)

// React Component: Context Menu - Menu Item
utils.Replace(
Expand Down

0 comments on commit 732d0c5

Please sign in to comment.