2022-11-12 21:35:23 +00:00
{
2022-09-19 18:31:25 +00:00
/ *
2023-09-16 23:29:05 +00:00
* Bluetooth . println ( JSON . stringify ( { t : "intent" , target : "" , action : "" , flags : [ "flag1" , "flag2" , ... ] , categories : [ "category1" , "category2" , ... ] , package : "" , class : "" , mimetype : "" , data : "" , extra : { someKey : "someValueOrString" , anotherKey : "anotherValueOrString" , ... } } ) ) ;
2022-09-19 18:31:25 +00:00
* /
2022-11-12 21:35:23 +00:00
let R ;
let widgetUtils = require ( "widget_utils" ) ;
let backToMenu = false ;
let isPaused = true ;
let dark = g . theme . dark ; // bool
2022-09-19 18:31:25 +00:00
// The main layout of the app
2022-11-12 21:35:23 +00:00
let gfx = function ( ) {
widgetUtils . hide ( ) ;
2022-09-19 18:31:25 +00:00
R = Bangle . appRect ;
marigin = 8 ;
// g.drawString(str, x, y, solid)
g . clearRect ( R ) ;
g . reset ( ) ;
2022-11-12 21:35:23 +00:00
2022-10-10 22:55:51 +00:00
if ( dark ) { g . setColor ( 0x07E0 ) ; } else { g . setColor ( 0x03E0 ) ; } // Green on dark theme, DarkGreen on light theme.
2022-09-19 18:31:25 +00:00
g . setFont ( "4x6:2" ) ;
g . setFontAlign ( 1 , 0 , 0 ) ;
g . drawString ( "->" , R . x2 - marigin , R . y + R . h / 2 ) ;
g . setFontAlign ( - 1 , 0 , 0 ) ;
g . drawString ( "<-" , R . x + marigin , R . y + R . h / 2 ) ;
g . setFontAlign ( - 1 , 0 , 1 ) ;
g . drawString ( "<-" , R . x + R . w / 2 , R . y + marigin ) ;
g . setFontAlign ( 1 , 0 , 1 ) ;
g . drawString ( "->" , R . x + R . w / 2 , R . y2 - marigin ) ;
g . setFontAlign ( 0 , 0 , 0 ) ;
g . drawString ( "Play\nPause" , R . x + R . w / 2 , R . y + R . h / 2 ) ;
g . setFontAlign ( - 1 , - 1 , 0 ) ;
g . drawString ( "Menu" , R . x + 2 * marigin , R . y + 2 * marigin ) ;
g . setFontAlign ( - 1 , 1 , 0 ) ;
g . drawString ( "Wake" , R . x + 2 * marigin , R . y + R . h - 2 * marigin ) ;
g . setFontAlign ( 1 , - 1 , 0 ) ;
g . drawString ( "Srch" , R . x + R . w - 2 * marigin , R . y + 2 * marigin ) ;
g . setFontAlign ( 1 , 1 , 0 ) ;
g . drawString ( "Saved" , R . x + R . w - 2 * marigin , R . y + R . h - 2 * marigin ) ;
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
// Touch handler for main layout
2022-11-12 21:35:23 +00:00
let touchHandler = function ( _ , xy ) {
2022-09-19 18:31:25 +00:00
x = xy . x ;
y = xy . y ;
len = ( R . w < R . h + 1 ) ? ( R . w / 3 ) : ( R . h / 3 ) ;
// doing a<b+1 seemed faster than a<=b, also using a>b-1 instead of a>b.
if ( ( R . x - 1 < x && x < R . x + len ) && ( R . y - 1 < y && y < R . y + len ) ) {
//Menu
2022-12-06 11:20:52 +00:00
Bangle . removeListener ( "touch" , touchHandler ) ;
Bangle . removeListener ( "swipe" , swipeHandler ) ;
2022-09-19 18:31:25 +00:00
backToMenu = true ;
E . showMenu ( spotifyMenu ) ;
} else if ( ( R . x - 1 < x && x < R . x + len ) && ( R . y2 - len < y && y < R . y2 + 1 ) ) {
2023-06-19 18:19:32 +00:00
//Wake
2022-09-19 18:31:25 +00:00
gadgetbridgeWake ( ) ;
} else if ( ( R . x2 - len < x && x < R . x2 + 1 ) && ( R . y - 1 < y && y < R . y + len ) ) {
//Srch
2022-12-06 11:20:52 +00:00
Bangle . removeListener ( "touch" , touchHandler ) ;
Bangle . removeListener ( "swipe" , swipeHandler ) ;
2022-09-19 18:31:25 +00:00
E . showMenu ( searchMenu ) ;
} else if ( ( R . x2 - len < x && x < R . x2 + 1 ) && ( R . y2 - len < y && y < R . y2 + 1 ) ) {
//Saved
2022-12-06 11:20:52 +00:00
Bangle . removeListener ( "touch" , touchHandler ) ;
Bangle . removeListener ( "swipe" , swipeHandler ) ;
2022-09-19 18:31:25 +00:00
E . showMenu ( savedMenu ) ;
} else if ( ( R . x - 1 < x && x < R . x + len ) && ( R . y + R . h / 2 - len / 2 < y && y < R . y + R . h / 2 + len / 2 ) ) {
2023-06-19 18:19:32 +00:00
//Previous
2022-09-19 18:31:25 +00:00
spotifyWidget ( "PREVIOUS" ) ;
} else if ( ( R . x2 - len + 1 < x && x < R . x2 + 1 ) && ( R . y + R . h / 2 - len / 2 < y && y < R . y + R . h / 2 + len / 2 ) ) {
//Next
spotifyWidget ( "NEXT" ) ;
} else if ( ( R . x - 1 < x && x < R . x2 + 1 ) && ( R . y - 1 < y && y < R . y2 + 1 ) ) {
//play/pause
playPause = isPaused ? "play" : "pause" ;
Bangle . musicControl ( playPause ) ;
isPaused = ! isPaused ;
}
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
2022-12-06 11:20:52 +00:00
// Swipe handler for main layout, used for next previous track.
2022-11-12 21:35:23 +00:00
let swipeHandler = function ( LR , _ ) {
2022-09-19 18:31:25 +00:00
if ( LR == - 1 ) {
spotifyWidget ( "NEXT" ) ;
}
if ( LR == 1 ) {
spotifyWidget ( "PREVIOUS" ) ;
}
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
// Navigation input on the main layout
2022-11-12 21:35:23 +00:00
let setUI = function ( ) {
// Bangle.setUI code from rigrig's smessages app for volume control: https://git.tubul.net/rigrig/BangleApps/src/branch/personal/apps/smessages/app.js
2022-09-19 18:31:25 +00:00
Bangle . setUI (
2022-11-12 21:35:23 +00:00
{ mode : "updown" ,
remove : ( ) => {
Bangle . removeListener ( "touch" , touchHandler ) ;
Bangle . removeListener ( "swipe" , swipeHandler ) ;
clearWatch ( buttonHandler ) ;
widgetUtils . show ( ) ;
}
} ,
ud => {
if ( ud ) Bangle . musicControl ( ud > 0 ? "volumedown" : "volumeup" ) ;
}
2022-09-19 18:31:25 +00:00
) ;
Bangle . on ( "touch" , touchHandler ) ;
Bangle . on ( "swipe" , swipeHandler ) ;
2022-11-12 21:35:23 +00:00
let buttonHandler = setWatch ( ( ) => { load ( ) ; } , BTN , { edge : 'falling' } ) ;
} ;
2022-09-19 18:31:25 +00:00
// Get back to the main layout
2022-11-12 21:35:23 +00:00
let backToGfx = function ( ) {
2022-09-19 18:31:25 +00:00
E . showMenu ( ) ;
g . clear ( ) ;
g . reset ( ) ;
setUI ( ) ;
gfx ( ) ;
backToMenu = false ;
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
/ *
The functions for interacting with Android and the Spotify app
* /
2023-09-16 23:29:05 +00:00
let createCommand = function ( o ) {
return ( ) => {
Bluetooth . println ( "" ) ;
Bluetooth . println ( JSON . stringify ( o ) ) ;
} ;
} ;
let assembleSearchString = function ( ) {
return ( artist == "" ? "" : ( "artist:\"" + artist + "\"" ) ) + ( ( artist != "" && track != "" ) ? " " : "" ) + ( track == "" ? "" : ( "track:\"" + track + "\"" ) ) + ( ( ( artist != "" && album != "" ) || ( track != "" && album != "" ) ) ? " " : "" ) + ( album == "" ? "" : ( " album:\"" + album + "\"" ) ) ;
} ;
2023-12-26 11:34:42 +00:00
let simpleSearch = "" ;
2022-11-12 21:35:23 +00:00
let simpleSearchTerm = function ( ) { // input a simple search term without tags, overrides search with tags (artist and track)
2022-09-19 18:31:25 +00:00
require ( "textinput" ) . input ( { text : simpleSearch } ) . then ( result => { simpleSearch = result ; } ) . then ( ( ) => { E . showMenu ( searchMenu ) ; } ) ;
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
2023-12-26 11:34:42 +00:00
let artist = "" ;
2022-11-12 21:35:23 +00:00
let artistSearchTerm = function ( ) { // input artist to search for
2022-09-19 18:31:25 +00:00
require ( "textinput" ) . input ( { text : artist } ) . then ( result => { artist = result ; } ) . then ( ( ) => { E . showMenu ( searchMenu ) ; } ) ;
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
2023-12-26 11:34:42 +00:00
let track = "" ;
2022-11-12 21:35:23 +00:00
let trackSearchTerm = function ( ) { // input track to search for
2022-09-19 18:31:25 +00:00
require ( "textinput" ) . input ( { text : track } ) . then ( result => { track = result ; } ) . then ( ( ) => { E . showMenu ( searchMenu ) ; } ) ;
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
2023-12-26 11:34:42 +00:00
let album = "" ;
2022-11-12 21:35:23 +00:00
let albumSearchTerm = function ( ) { // input album to search for
2022-09-19 18:31:25 +00:00
require ( "textinput" ) . input ( { text : album } ) . then ( result => { album = result ; } ) . then ( ( ) => { E . showMenu ( searchMenu ) ; } ) ;
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
2023-09-16 23:29:05 +00:00
let searchPlayWOTags = createCommand ( { t : "intent" , action : "android.media.action.MEDIA_PLAY_FROM_SEARCH" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , target : "activity" , extra : { query : simpleSearch } , flags : [ "FLAG_ACTIVITY_NEW_TASK" ] } ) ;
2022-09-19 18:31:25 +00:00
2023-09-16 23:29:05 +00:00
let searchPlayWTags = createCommand ( { t : "intent" , action : "android.media.action.MEDIA_PLAY_FROM_SEARCH" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , target : "activity" , extra : { query : assembleSearchString ( ) } , flags : [ "FLAG_ACTIVITY_NEW_TASK" ] } ) ;
2022-09-19 18:31:25 +00:00
2023-09-16 23:29:05 +00:00
let playVreden = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:track:5QEFFJ5tAeRlVquCUNpAJY:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-09-19 18:31:25 +00:00
2023-12-26 12:25:25 +00:00
//let searchPlayVreden = createCommand({t:"intent", action:"android.media.action.MEDIA_PLAY_FROM_SEARCH", categories:["android.intent.category.DEFAULT"], package:"com.spotify.music", target:"activity", extra:{query:'artist:"Sara Parkman" track:"Vreden"'}, flags:["FLAG_ACTIVITY_NEW_TASK"]});
2022-09-19 18:31:25 +00:00
2023-09-16 23:29:05 +00:00
let openAlbum = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:album:3MVb2CWB36x7VwYo5sZmf2" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" ] } ) ;
2022-09-19 18:31:25 +00:00
2023-09-16 23:29:05 +00:00
let searchPlayAlbum = createCommand ( { t : "intent" , action : "android.media.action.MEDIA_PLAY_FROM_SEARCH" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , target : "activity" , extra : { query : 'album:"The blue room" artist:"Coldplay"' , "android.intent.extra.focus" : "vnd.android.cursor.item/album" } , flags : [ "FLAG_ACTIVITY_NEW_TASK" ] } ) ;
2022-09-19 18:31:25 +00:00
2022-11-12 21:35:23 +00:00
let spotifyWidget = function ( action ) {
2023-06-19 18:19:32 +00:00
Bluetooth . println ( "" ) ;
2022-09-19 18:31:25 +00:00
Bluetooth . println ( JSON . stringify ( { t : "intent" , action : ( "com.spotify.mobile.android.ui.widget." + action ) , package : "com.spotify.music" , target : "broadcastreceiver" } ) ) ;
2022-11-12 21:35:23 +00:00
} ;
2022-09-19 18:31:25 +00:00
2023-09-16 23:29:05 +00:00
let gadgetbridgeWake = createCommand ( { t : "intent" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_CLEAR_TASK" , "FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS" , "FLAG_ACTIVITY_NO_ANIMATION" ] , package : "gadgetbridge" , class : "nodomain.freeyourgadget.gadgetbridge.activities.WakeActivity" } ) ;
2022-09-19 18:31:25 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDW = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZEVXcRfaeEbxXIgb:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-09-19 18:31:25 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDM1 = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZF1E365VyzxE0mxF:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDM2 = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZF1E38LZHLFnrM61:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDM3 = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZF1E36RU87qzgBFP:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDM4 = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZF1E396gGyCXEBFh:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDM5 = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZF1E37a0Tt6CKJLP:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDM6 = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZF1E36UIQLQK79od:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistDD = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZF1EfWFiI7QfIAKq:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2023-12-26 12:09:37 +00:00
let spotifyPlaylistRR = createCommand ( { t : "intent" , action : "android.intent.action.VIEW" , categories : [ "android.intent.category.DEFAULT" ] , package : "com.spotify.music" , data : "spotify:user:spotify:playlist:37i9dQZEVXbs0XkE2V8sMO:play" , target : "activity" , flags : [ "FLAG_ACTIVITY_NEW_TASK" , "FLAG_ACTIVITY_NO_ANIMATION" ] } ) ;
2022-10-10 23:24:55 +00:00
2022-09-19 18:31:25 +00:00
// Spotify Remote Menu
2022-11-12 21:35:23 +00:00
let spotifyMenu = {
"" : { title : " Menu " ,
2022-09-19 18:31:25 +00:00
back : backToGfx } ,
"Controls" : ( ) => { E . showMenu ( controlMenu ) ; } ,
"Search and play" : ( ) => { E . showMenu ( searchMenu ) ; } ,
"Saved music" : ( ) => { E . showMenu ( savedMenu ) ; } ,
"Wake the android" : function ( ) { gadgetbridgeWake ( ) ; gadgetbridgeWake ( ) ; } ,
"Exit Spotify Remote" : ( ) => { load ( ) ; }
} ;
2023-09-16 23:29:05 +00:00
let menuBackFunc = ( ) => {
if ( backToMenu ) E . showMenu ( spotifyMenu ) ;
if ( ! backToMenu ) backToGfx ( ) ;
} ;
2022-09-19 18:31:25 +00:00
2022-11-12 21:35:23 +00:00
let controlMenu = {
"" : { title : " Controls " ,
2023-09-16 23:29:05 +00:00
back : menuBackFunc } ,
2022-09-19 18:31:25 +00:00
"Play" : ( ) => { Bangle . musicControl ( "play" ) ; } ,
"Pause" : ( ) => { Bangle . musicControl ( "pause" ) ; } ,
"Previous" : ( ) => { spotifyWidget ( "PREVIOUS" ) ; } ,
"Next" : ( ) => { spotifyWidget ( "NEXT" ) ; } ,
"Play (widget, next then previous)" : ( ) => { spotifyWidget ( "NEXT" ) ; spotifyWidget ( "PREVIOUS" ) ; } ,
"Messages Music Controls" : ( ) => { load ( "messagesmusic.app.js" ) ; } ,
} ;
2022-11-12 21:35:23 +00:00
let searchMenu = {
"" : { title : " Search " ,
2023-09-16 23:29:05 +00:00
back : menuBackFunc } ,
"Search term w/o tags" : simpleSearchTerm ,
"Execute search and play w/o tags" : searchPlayWOTags ,
"Search term w tag \"artist\"" : artistSearchTerm ,
"Search term w tag \"track\"" : trackSearchTerm ,
"Search term w tag \"album\"" : albumSearchTerm ,
"Execute search and play with tags" : searchPlayWTags ,
2022-09-19 18:31:25 +00:00
} ;
2022-11-12 21:35:23 +00:00
let savedMenu = {
"" : { title : " Saved " ,
2023-09-16 23:29:05 +00:00
back : menuBackFunc } ,
"Play Discover Weekly" : spotifyPlaylistDW ,
"Play Daily Mix 1" : spotifyPlaylistDM1 ,
"Play Daily Mix 2" : spotifyPlaylistDM2 ,
"Play Daily Mix 3" : spotifyPlaylistDM3 ,
"Play Daily Mix 4" : spotifyPlaylistDM4 ,
"Play Daily Mix 5" : spotifyPlaylistDM5 ,
"Play Daily Mix 6" : spotifyPlaylistDM6 ,
"Play Daily Drive" : spotifyPlaylistDD ,
"Play Release Radar" : spotifyPlaylistRR ,
"Play \"Vreden\" by Sara Parkman via uri-link" : playVreden ,
"Open \"The Blue Room\" EP (no autoplay)" : openAlbum ,
"Play \"The Blue Room\" EP via search&play" : searchPlayAlbum ,
2022-09-19 18:31:25 +00:00
} ;
Bangle . loadWidgets ( ) ;
setUI ( ) ;
gfx ( ) ;
2022-11-12 21:35:23 +00:00
}