Skip to content

Conversation

@pyyupsk
Copy link
Contributor

@pyyupsk pyyupsk commented Dec 5, 2025

Summary

  • Add new regex patterns for async React lazy loading in Spotify 1.2.78+
  • Fix Image Snackbar preprocessing to only match in assignment context

Test plan

  • Tested on Windows with Spotify 1.2.78.418

Relates to #3601

Summary by CodeRabbit

  • Refactor
    • Expanded support for additional React code patterns and variations.
    • Improved compatibility with diverse React code structures, including async and Promise-based implementations.
    • Enhanced reliability in code detection and transformation.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add new regex patterns for async React lazy loading in apply.go
- Add FindSymbolWithPattern helper to return matched pattern for reuse
- Fix Image Snackbar preprocessing to only match in assignment context
- Add defer attribute to Spicetify.Config script block
@pyyupsk pyyupsk marked this pull request as ready for review December 5, 2025 07:48
@coderabbitai
Copy link

coderabbitai bot commented Dec 5, 2025

Walkthrough

The insertCustomApp function in src/apply/apply.go is refactored to replace hard-coded regex patterns with a dynamic, pattern-driven approach. A new utility function FindSymbolWithPattern is added to src/utils/utils.go that performs pattern matching while returning both the matched content and the pattern that matched.

Changes

Cohort / File(s) Summary
Pattern-driven refactoring
src/apply/apply.go
Replaces static REACT_REGEX and REACT_ELEMENT_REGEX constants with dynamic pattern sets (reactPatterns, elementPatterns). Updates insertCustomApp to use FindSymbolWithPattern for obtaining both matched patterns and symbol lists, adjusting control flow to apply replacements based on computed patterns instead of fixed constants.
New pattern matching utility
src/utils/utils.go
Adds FindSymbolWithPattern(debugInfo, content, clues) function that iterates over clue patterns as regex, returns matched submatch groups and the corresponding matching pattern, enabling pattern provenance tracking.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review the pattern set definitions and ensure all necessary React and element patterns are covered in the new dynamic approach
  • Verify that FindSymbolWithPattern correctly handles regex compilation and submatch extraction across multiple pattern candidates
  • Confirm that the refactored control flow in insertCustomApp maintains functional equivalence with the previous hard-coded approach
  • Check edge cases where no patterns match and verify error logging behavior

Poem

🐰 Patterns dance where once was stone,
No more hard-coded, all have grown!
Dynamic matching, flexible and free,
Finds the match and which it be! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(apply): add support for Spotify 1.2.78+' clearly and directly summarizes the main change: adding support for a new Spotify version with updated regex patterns.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/utils/utils.go (1)

316-332: LGTM! Consider optional DRY refactor.

The function is well-implemented and follows the existing codebase patterns. Returning both the matched symbols and the pattern enables more precise subsequent replacements in apply.go.

Minor DRY opportunity: FindSymbol and FindSymbolWithPattern share nearly identical logic. You could optionally refactor to have FindSymbol call FindSymbolWithPattern internally:

 func FindSymbol(debugInfo, content string, clues []string) []string {
-	for _, v := range clues {
-		re := regexp.MustCompile(v)
-		found := re.FindStringSubmatch(content)
-		if found != nil {
-			return found[1:]
-		}
-	}
-
-	if len(debugInfo) > 0 {
-		PrintError("Cannot find symbol for " + debugInfo)
-	}
-
-	return nil
+	symbols, _ := FindSymbolWithPattern(debugInfo, content, clues)
+	return symbols
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04155e7 and 59cbdba.

📒 Files selected for processing (3)
  • src/apply/apply.go (3 hunks)
  • src/preprocess/preprocess.go (1 hunks)
  • src/utils/utils.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/utils/utils.go (1)
src/utils/print.go (1)
  • PrintError (88-90)
src/apply/apply.go (1)
src/utils/utils.go (2)
  • FindSymbolWithPattern (318-332)
  • ReplaceOnce (175-188)
🔇 Additional comments (5)
src/preprocess/preprocess.go (1)

949-956: LGTM! Good defensive pattern matching.

The changes properly address the Image Snackbar patch:

  1. Capturing = in group 1 ensures we only match in assignment contexts, preventing false positives
  2. Adding Once: true prevents double-patching if the pattern appears multiple times
src/apply/apply.go (4)

161-170: LGTM! Correct use of defer for inline script.

Adding defer ensures the Spicetify.Config assignment runs after the DOM is parsed, which is appropriate for configuration scripts.


263-271: Good pattern expansion for Spotify 1.2.78+ support.

The three React lazy loading patterns correctly cover:

  1. Synchronous lazy loading (existing versions)
  2. Async lazy loading with await (1.2.78+)
  3. Async Promise.all pattern (1.2.78+)

The comments documenting each pattern variant are helpful.


281-294: LGTM! Pattern-driven symbol matching with good error handling.

Using FindSymbolWithPattern to capture both the symbols and the matching pattern enables precise subsequent replacements. The error messaging appropriately guides users when patterns don't match.


335-347: LGTM! Correct use of matched patterns for replacements.

Using matchedReactPattern and matchedElementPattern in ReplaceOnce ensures the replacement targets exactly the pattern that was matched during symbol extraction, preventing mismatches between detection and replacement phases.

- Remove defer attribute accidentally left from testing
- Revert Image Snackbar regex change left from testing
- Fix regex typo: \[ -> [ in createElement pattern
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59cbdba and b7eaf62.

📒 Files selected for processing (1)
  • src/apply/apply.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/apply/apply.go (1)
src/utils/utils.go (2)
  • FindSymbolWithPattern (318-332)
  • ReplaceOnce (175-188)
🔇 Additional comments (4)
src/apply/apply.go (4)

273-279: Past review concern appears resolved.

The past review comment mentioned a potential regex typo with \[ at line 278, but the current code correctly uses [\w_\$] (a character class) rather than \[\w_\$] (escaped bracket). The pattern should now properly match identifiers like X.createElement.


281-288: LGTM - pattern-driven approach improves flexibility.

The use of FindSymbolWithPattern with pattern arrays provides better flexibility for handling different Spotify versions compared to hard-coded patterns. The function correctly returns both the matched symbols and the pattern that matched, enabling dynamic replacement logic.


337-344: LGTM - dynamic pattern usage ensures precise replacements.

Using the matched patterns from FindSymbolWithPattern for the ReplaceOnce calls ensures that replacements occur at the exact locations that were successfully matched. This approach is more robust than using fixed patterns.


263-271: Verify the async pattern completeness (line 268) by testing against actual code.

The async pattern on line 268 does not explicitly match the closing } before the final ). According to the comment, the expected structure is m.lazy(async()=>{...await o.e(123).then(...)}), but the regex ends at \.then\(\w+\.bind\(\w+,\d+\)\) without capturing the closing braces. Verify whether this partial pattern is intentional for symbol extraction or if it should be \.then\(\w+\.bind\(\w+,\d+\)\)\}\) to match the complete structure.

REACT_ELEMENT_REGEX})
elementPatterns)

if (len(reactSymbs) < 2) || (len(eleSymbs) == 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Insufficient bounds checking could cause index out of bounds.

The validation checks len(reactSymbs) < 2 and len(eleSymbs) == 0, but the code accesses reactSymbs[2] (line 318) and eleSymbs[2] (lines 305-308, 323). Since all patterns capture exactly 3 groups, the validation should ensure both arrays have at least 3 elements.

Apply this diff to fix the bounds check:

-	if (len(reactSymbs) < 2) || (len(eleSymbs) == 0) {
+	if (len(reactSymbs) < 3) || (len(eleSymbs) < 3) {
🤖 Prompt for AI Agents
In src/apply/apply.go around line 290, the current validation uses
(len(reactSymbs) < 2) || (len(eleSymbs) == 0) which is insufficient because the
code later accesses reactSymbs[2] and eleSymbs[2]; update the condition to
require at least 3 elements in both slices (e.g., if len(reactSymbs) < 3 ||
len(eleSymbs) < 3) and adjust the error handling path accordingly so you never
index out of bounds.

@pyyupsk pyyupsk requested a review from rxri December 5, 2025 13:49
@pyyupsk
Copy link
Contributor Author

pyyupsk commented Dec 5, 2025

Removed, this was leftover from testing, sorry about that

@rxri
Copy link
Member

rxri commented Dec 5, 2025

and what about another coderabbit's review?
edit: nvm

@rxri rxri changed the title fix(apply): add support for Spotify 1.2.78+ fix(apply): add support for Spotify 1.2.78+ Dec 5, 2025
@rxri
Copy link
Member

rxri commented Dec 5, 2025

i will fix snackbar thingies with my local commit

@rxri rxri merged commit 90fcc18 into spicetify:main Dec 5, 2025
8 checks passed
@pyyupsk pyyupsk deleted the fix/spotify-1.2.78-support branch December 5, 2025 14:23
@rxri
Copy link
Member

rxri commented Dec 5, 2025

@pyyupsk did custom apps work properly on your end? aka could you access them as fine? because your patch works, just they don't display anything :)

@pyyupsk
Copy link
Contributor Author

pyyupsk commented Dec 5, 2025

@pyyupsk did custom apps work properly on your end? aka could you access them as fine? because your patch works, just they don't display anything :)

custom apps load fine, but marketplace shows blank (no extensions/themes/snippets). issue is in the marketplace repo it accesses Spicetify.Platform.History before it ready with the new async lazy loading. maybe

@pyyupsk
Copy link
Contributor Author

pyyupsk commented Dec 5, 2025

also some files use the old marketplace url spicetify/spicetify-marketplace, i forgot all about it, it was so long ago when i try

@rxri
Copy link
Member

rxri commented Dec 5, 2025

issue is in the marketplace repo it accesses Spicetify.Platform.History before it ready with the new async lazy loading. maybe

Ohhh. Weird that it does not throw an error tho. Okay. Will just do it to wait for it I guess?

@rxri
Copy link
Member

rxri commented Dec 5, 2025

I mean, lyrics-plus from what i see is also broken so dunno if we should do something on our end or just let devs update their custom apps tbh

@pyyupsk
Copy link
Contributor Author

pyyupsk commented Dec 5, 2025

dont know bro, if i have a time ill try to fix it again

@kxvvvvv

This comment was marked as off-topic.

@kuchingneko28

This comment was marked as off-topic.

@spicetify spicetify locked as resolved and limited conversation to collaborators Dec 5, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants