2020-07-19 16:59:08 +02:00
//META{"name":"SpotifyControls","authorId":"278543574059057154","invite":"Jx3TjNS","donate":"https://www.paypal.me/MircoWittrien","patreon":"https://www.patreon.com/MircoWittrien","website":"https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/SpotifyControls","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/SpotifyControls/SpotifyControls.plugin.js"}*//
var SpotifyControls = ( _ => {
2020-08-15 20:27:43 +02:00
var _this , insertPatchCancel ;
2020-07-23 20:23:23 +02:00
var controls , lastSong , currentVolume , lastVolume , stopTime , previousIsClicked , previousDoubleTimeout , timelineTimeout , timelineDragging , updateInterval ;
2020-07-23 16:12:08 +02:00
var playbackState = { } ;
2020-08-31 16:38:37 +02:00
var settings = { } , buttonConfigs = { } ;
2020-07-21 15:08:40 +02:00
2020-07-23 16:12:08 +02:00
const repeatStates = [
"off" ,
"context" ,
"track"
] ;
2020-07-19 16:59:08 +02:00
const SpotifyControlsComponent = class SpotifyControls extends BdApi . React . Component {
componentDidMount ( ) {
controls = this ;
}
2020-07-23 16:12:08 +02:00
request ( socket , device , type , data ) {
2020-07-19 16:59:08 +02:00
return new Promise ( callback => {
2020-07-23 16:12:08 +02:00
let method = "PUT" ;
switch ( type ) {
case "next" :
case "previous" :
method = "POST" ;
break ;
case "get" :
type = "" ;
method = "GET" ;
break ;
} ;
2020-07-19 16:59:08 +02:00
BDFDB . LibraryRequires . request ( {
2020-07-23 16:12:08 +02:00
url : ` https://api.spotify.com/v1/me/player ${ type ? "/" + type : "" } ${ Object . entries ( Object . assign ( { } , data)).map(n => ` ? $ { n [ 0 ] } = $ { n [ 1 ] } ` ).join("")} ` ,
method : method ,
2020-07-19 16:59:08 +02:00
headers : {
authorization : ` Bearer ${ socket . accessToken } `
2020-07-23 16:12:08 +02:00
}
2020-07-19 16:59:08 +02:00
} , ( error , response , result ) => {
2020-07-19 17:58:17 +02:00
if ( response . statusCode == 401 ) {
2020-07-19 16:59:08 +02:00
BDFDB . LibraryModules . SpotifyUtils . getAccessToken ( socket . accountId ) . then ( promiseResult => {
let newSocketDevice = BDFDB . LibraryModules . SpotifyTrackUtils . getActiveSocketAndDevice ( ) ;
2020-07-23 16:12:08 +02:00
this . request ( newSocketDevice . socket , newSocketDevice . device , type , data ) . then ( _ => {
try { callback ( JSON . parse ( result ) ) ; }
catch ( err ) { callback ( { } ) ; }
2020-07-19 16:59:08 +02:00
} ) ;
} ) ;
}
2020-07-23 16:12:08 +02:00
else {
try { callback ( JSON . parse ( result ) ) ; }
catch ( err ) { callback ( { } ) ; }
}
2020-07-19 16:59:08 +02:00
} ) ;
} ) ;
}
render ( ) {
let socketDevice = BDFDB . LibraryModules . SpotifyTrackUtils . getActiveSocketAndDevice ( ) ;
2020-07-23 16:12:08 +02:00
if ( ! socketDevice ) return null ;
2020-07-19 17:21:45 +02:00
if ( this . props . song ) {
2020-07-23 16:12:08 +02:00
playbackState . is _playing = true ;
2020-08-31 16:38:37 +02:00
let fetchState = ! BDFDB . equals ( this . props . song , lastSong ) ;
2020-07-19 17:21:45 +02:00
lastSong = this . props . song ;
stopTime = null ;
2020-07-23 21:51:49 +02:00
if ( fetchState ) this . request ( socketDevice . socket , socketDevice . device , "get" ) . then ( response => {
playbackState = Object . assign ( { } , response ) ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
} ) ;
2020-07-19 17:21:45 +02:00
}
2020-07-23 16:12:08 +02:00
else if ( ! stopTime && lastSong ) {
playbackState . is _playing = false ;
stopTime = new Date ( ) ;
}
if ( ! lastSong ) return null ;
currentVolume = socketDevice . device . volume _percent ;
return BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . _spotifycontrolscontainer , this . props . maximized && BDFDB . disCN . _spotifycontrolscontainermaximized , this . props . timeline && BDFDB . disCN . _spotifycontrolscontainerwithtimeline ) ,
2020-07-19 16:59:08 +02:00
children : [
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolscontainerinner ,
children : [
2020-07-23 16:12:08 +02:00
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Clickable , {
className : BDFDB . disCN . _spotifycontrolscoverwrapper ,
onClick : _ => {
this . props . maximized = ! this . props . maximized ;
BDFDB . DataUtils . save ( this . props . maximized , _this , "playerState" , "maximized" ) ;
if ( this . props . maximized ) this . request ( socketDevice . socket , socketDevice . device , "get" ) . then ( response => {
playbackState = Object . assign ( { } , response ) ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
} ) ;
else BDFDB . ReactUtils . forceUpdate ( this ) ;
} ,
children : [
BDFDB . ReactUtils . createElement ( "img" , {
className : BDFDB . disCN . _spotifycontrolscover ,
src : BDFDB . LibraryModules . AssetUtils . getAssetImage ( lastSong . application _id , lastSong . assets . large _image )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
className : BDFDB . disCN . _spotifycontrolscovermaximizer ,
name : BDFDB . LibraryComponents . SvgIcon . Names . LEFT _CARET
} )
]
2020-07-19 16:59:08 +02:00
} ) ,
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolsdetails ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
className : BDFDB . disCN . _spotifycontrolssong ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextScroller , {
children : lastSong . details
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
className : BDFDB . disCNS . subtext + BDFDB . disCN . _spotifycontrolsinterpret ,
color : BDFDB . LibraryComponents . TextElement . Colors . CUSTOM ,
size : BDFDB . LibraryComponents . TextElement . Sizes . SIZE _12 ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextScroller , {
children : BDFDB . LanguageUtils . LanguageStringsFormat ( "USER_ACTIVITY_LISTENING_ARTISTS" , lastSong . state )
} )
} )
]
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : socketDevice . device . is _restricted ? "Can not control Spotify while playing on restricted device" : null ,
tooltipConfig : { color : "red" } ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
grow : 0 ,
children : [
2020-08-31 16:38:37 +02:00
BDFDB . ReactUtils . createElement ( SpotifyControlsButtonComponent , {
type : "share" ,
playerSize : this . props . maximized ? "big" : "small" ,
style : this . props . maximized ? { marginRight : 4 } : { } ,
2020-07-23 20:53:46 +02:00
onClick : _ => {
2020-07-23 21:51:49 +02:00
let url = BDFDB . ReactUtils . getValue ( playbackState , "item.external_urls.spotify" ) || BDFDB . ReactUtils . getValue ( playbackState , "context.external_urls.spotify" ) ;
if ( url ) {
BDFDB . LibraryRequires . electron . clipboard . write ( { text : url } ) ;
BDFDB . NotificationUtils . toast ( "Song URL was copied to clipboard." , { type : "success" } ) ;
}
else BDFDB . NotificationUtils . toast ( "Could not copy song URL to clipboard." , { type : "error" } ) ;
2020-07-23 20:53:46 +02:00
}
} ) ,
2020-08-31 16:38:37 +02:00
BDFDB . ReactUtils . createElement ( SpotifyControlsButtonComponent , {
type : "shuffle" ,
playerSize : this . props . maximized ? "big" : "small" ,
active : playbackState . shuffle _state ,
disabled : socketDevice . device . is _restricted ,
onClick : _ => {
2020-07-23 16:12:08 +02:00
playbackState . shuffle _state = ! playbackState . shuffle _state ;
this . request ( socketDevice . socket , socketDevice . device , "shuffle" , {
state : playbackState . shuffle _state
} ) ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
}
} ) ,
2020-08-31 16:38:37 +02:00
BDFDB . ReactUtils . createElement ( SpotifyControlsButtonComponent , {
type : "previous" ,
playerSize : this . props . maximized ? "big" : "small" ,
disabled : socketDevice . device . is _restricted ,
onClick : _ => {
2020-07-23 16:12:08 +02:00
if ( previousIsClicked ) {
previousIsClicked = false ;
this . request ( socketDevice . socket , socketDevice . device , "previous" ) ;
}
else {
previousIsClicked = true ;
previousDoubleTimeout = BDFDB . TimeUtils . timeout ( _ => {
previousIsClicked = false ;
this . request ( socketDevice . socket , socketDevice . device , "seek" , {
position _ms : 0
} ) ;
} , 300 ) ;
}
2020-07-19 16:59:08 +02:00
}
} ) ,
2020-08-31 16:38:37 +02:00
BDFDB . ReactUtils . createElement ( SpotifyControlsButtonComponent , {
type : "pauseplay" ,
playerSize : this . props . maximized ? "big" : "small" ,
icon : this . props . song ? 0 : 1 ,
disabled : socketDevice . device . is _restricted ,
onClick : _ => {
2020-07-23 16:12:08 +02:00
if ( this . props . song ) {
playbackState . is _playing = false ;
this . request ( socketDevice . socket , socketDevice . device , "pause" ) ;
}
else {
playbackState . is _playing = true ;
this . request ( socketDevice . socket , socketDevice . device , "play" ) ;
}
2020-07-19 16:59:08 +02:00
}
} ) ,
2020-08-31 16:38:37 +02:00
BDFDB . ReactUtils . createElement ( SpotifyControlsButtonComponent , {
type : "next" ,
playerSize : this . props . maximized ? "big" : "small" ,
disabled : socketDevice . device . is _restricted ,
onClick : _ => {
2020-07-19 16:59:08 +02:00
this . request ( socketDevice . socket , socketDevice . device , "next" ) ;
}
2020-07-23 16:12:08 +02:00
} ) ,
2020-08-31 16:38:37 +02:00
BDFDB . ReactUtils . createElement ( SpotifyControlsButtonComponent , {
type : "repeat" ,
playerSize : this . props . maximized ? "big" : "small" ,
icon : playbackState . repeat _state != repeatStates [ 2 ] ? 0 : 1 ,
active : playbackState . repeat _state != repeatStates [ 0 ] ,
disabled : socketDevice . device . is _restricted ,
onClick : _ => {
2020-07-23 16:12:08 +02:00
playbackState . repeat _state = repeatStates [ repeatStates . indexOf ( playbackState . repeat _state ) + 1 ] || repeatStates [ 0 ] ;
this . request ( socketDevice . socket , socketDevice . device , "repeat" , {
state : playbackState . repeat _state
} ) ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
}
} ) ,
2020-08-31 16:38:37 +02:00
BDFDB . ReactUtils . createElement ( SpotifyControlsButtonComponent , {
type : "volume" ,
playerSize : this . props . maximized ? "big" : "small" ,
icon : Math . ceil ( currentVolume / 34 ) ,
disabled : socketDevice . device . is _restricted ,
style : this . props . maximized ? { marginLeft : 4 } : { } ,
onContextMenu : _ => {
if ( currentVolume == 0 ) {
if ( lastVolume ) this . request ( socketDevice . socket , socketDevice . device , "volume" , {
volume _percent : lastVolume
} ) ;
2020-07-23 16:12:08 +02:00
}
2020-08-31 16:38:37 +02:00
else {
lastVolume = currentVolume ;
this . request ( socketDevice . socket , socketDevice . device , "volume" , {
volume _percent : 0
} ) ;
}
} ,
2020-07-23 16:12:08 +02:00
renderPopout : instance => {
2020-08-31 16:38:37 +02:00
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Slider , {
2020-07-23 16:12:08 +02:00
className : BDFDB . disCN . _spotifycontrolsvolumeslider ,
2020-07-23 20:23:23 +02:00
defaultValue : currentVolume ,
digits : 0 ,
barStyles : { height : 6 , top : 3 } ,
fillStyles : { backgroundColor : BDFDB . DiscordConstants . Colors . SPOTIFY } ,
onValueRender : value => {
return value + "%" ;
} ,
onValueChange : value => {
currentVolume = value ;
this . request ( socketDevice . socket , socketDevice . device , "volume" , {
volume _percent : currentVolume
} ) ;
}
2020-07-23 16:12:08 +02:00
} ) ;
}
2020-07-19 16:59:08 +02:00
} )
2020-07-23 16:12:08 +02:00
] . filter ( n => n )
2020-07-19 16:59:08 +02:00
} )
} )
]
} ) ,
2020-07-23 16:12:08 +02:00
this . props . timeline && BDFDB . ReactUtils . createElement ( SpotifyControlsTimelineComponent , {
2020-07-23 20:23:23 +02:00
song : lastSong ,
socket : socketDevice . socket ,
device : socketDevice . device ,
controls : this
2020-07-19 16:59:08 +02:00
} )
2020-07-21 15:08:40 +02:00
] . filter ( n => n )
2020-07-19 16:59:08 +02:00
} ) ;
}
} ;
2020-08-31 16:38:37 +02:00
const SpotifyControlsButtonComponent = class SpotifyControlsButton extends BdApi . React . Component {
render ( ) {
if ( ! this . props . playerSize || ! buttonConfigs [ this . props . type ] || ! buttonConfigs [ this . props . type ] [ this . props . playerSize ] ) return null ;
let button = BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , BDFDB . ObjectUtils . exclude ( Object . assign ( { } , this . props , {
className : BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . accountinfobutton , this . props . disabled ? BDFDB . disCN . accountinfobuttondisabled : BDFDB . disCN . accountinfobuttonenabled , this . props . active && BDFDB . disCN . _spotifycontrolsbuttonactive ) ,
look : BDFDB . LibraryComponents . Button . Looks . BLANK ,
size : BDFDB . LibraryComponents . Button . Sizes . NONE ,
children : _this . defaults . buttonConfigs [ this . props . type ] && _this . defaults . buttonConfigs [ this . props . type ] . icons ? ( _this . defaults . buttonConfigs [ this . props . type ] . icons [ this . props . icon ] || _this . defaults . buttonConfigs [ this . props . type ] . icons [ 0 ] ) : "?" ,
onClick : this . props . disabled ? _ => { } : this . props . onClick ,
onContextMenu : this . props . disabled ? _ => { } : this . props . onContextMenu ,
} ) , "active" , "disabled" , "renderPopout" , "icon" , "type" ) ) ;
return ! this . props . disabled && typeof this . props . renderPopout == "function" ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . PopoutContainer , {
children : button ,
animation : BDFDB . LibraryComponents . PopoutContainer . Animation . SCALE ,
position : BDFDB . LibraryComponents . PopoutContainer . Positions . TOP ,
align : BDFDB . LibraryComponents . PopoutContainer . Align . CENTER ,
arrow : true ,
shadow : true ,
renderPopout : this . props . renderPopout
} ) : button ;
}
} ;
2020-07-19 16:59:08 +02:00
const SpotifyControlsTimelineComponent = class SpotifyControlsTimeline extends BdApi . React . Component {
componentDidMount ( ) {
BDFDB . TimeUtils . clear ( updateInterval ) ;
updateInterval = BDFDB . TimeUtils . interval ( _ => {
if ( ! this . updater || typeof this . updater . isMounted != "function" || ! this . updater . isMounted ( this ) ) BDFDB . TimeUtils . clear ( updateInterval ) ;
2020-07-23 16:12:08 +02:00
else if ( playbackState . is _playing ) {
2020-07-21 15:12:43 +02:00
let song = BDFDB . LibraryModules . SpotifyTrackUtils . getActivity ( false ) ;
2020-07-19 17:10:13 +02:00
if ( ! song ) BDFDB . ReactUtils . forceUpdate ( controls ) ;
2020-07-23 16:12:08 +02:00
else if ( playbackState . is _playing ) BDFDB . ReactUtils . forceUpdate ( this ) ;
2020-07-19 17:10:13 +02:00
}
2020-07-19 16:59:08 +02:00
} , 1000 ) ;
}
formatTime ( time ) {
let seconds = Math . floor ( ( time / 1000 ) % 60 ) ;
let minutes = Math . floor ( ( time / ( 1000 * 60 ) ) % 60 ) ;
let hours = Math . floor ( ( time / ( 1000 * 60 * 60 ) ) % 24 ) ;
return ` ${ hours > 0 ? hours + ":" : "" } ${ hours > 0 && minutes < 10 ? "0" + minutes : minutes } : ${ seconds < 10 ? "0" + seconds : seconds } `
}
render ( ) {
let maxTime = this . props . song . timestamps . end - this . props . song . timestamps . start ;
2020-07-23 16:12:08 +02:00
let currentTime = ( ! playbackState . is _playing && stopTime ? stopTime : new Date ( ) ) - this . props . song . timestamps . start ;
2020-07-19 17:10:13 +02:00
currentTime = currentTime > maxTime ? maxTime : currentTime ;
2020-07-19 16:59:08 +02:00
return BDFDB . ReactUtils . createElement ( "div" , {
2020-07-21 15:15:26 +02:00
className : BDFDB . disCN . _spotifycontrolstimeline ,
2020-07-19 16:59:08 +02:00
children : [
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolsbar ,
2020-07-23 20:23:23 +02:00
children : [
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolsbarfill ,
style : { width : ` ${ currentTime / maxTime * 100 } % ` }
} ) ,
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolsbargrabber ,
style : { left : ` ${ currentTime / maxTime * 100 } % ` }
} )
] ,
onClick : event => {
let rects = BDFDB . DOMUtils . getRects ( BDFDB . DOMUtils . getParent ( BDFDB . dotCN . _spotifycontrolsbar , event . target ) ) ;
this . props . controls . request ( this . props . socket , this . props . device , "seek" , {
position _ms : Math . round ( BDFDB . NumberUtils . mapRange ( [ rects . left , rects . left + rects . width ] , [ 0 , maxTime ] , event . clientX ) )
} ) ;
}
2020-07-19 16:59:08 +02:00
} ) ,
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolsbartext ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
className : BDFDB . disCN . height12 ,
size : BDFDB . LibraryComponents . TextElement . Sizes . SIZE _12 ,
children : this . formatTime ( currentTime )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
className : BDFDB . disCN . height12 ,
size : BDFDB . LibraryComponents . TextElement . Sizes . SIZE _12 ,
children : this . formatTime ( maxTime )
} )
]
} )
]
} ) ;
}
} ;
return class SpotifyControls {
getName ( ) { return "SpotifyControls" ; }
2020-08-31 16:38:37 +02:00
getVersion ( ) { return "1.0.8" ; }
2020-07-19 16:59:08 +02:00
getAuthor ( ) { return "DevilBro" ; }
getDescription ( ) { return "Adds a control panel to discord when listening to spotify." ; }
constructor ( ) {
2020-07-19 17:54:47 +02:00
this . changelog = {
2020-08-31 16:38:37 +02:00
"fixed" : [ [ "Button Configuration" , "You can now enable/disable control buttons for the small and big player version in the plugin settings" ] ]
2020-07-19 17:54:47 +02:00
} ;
2020-07-19 16:59:08 +02:00
this . patchedModules = {
2020-08-15 20:27:43 +02:00
before : {
AppView : "render"
2020-07-19 16:59:08 +02:00
}
} ;
2020-07-19 17:26:50 +02:00
}
initConstructor ( ) {
2020-07-23 16:12:08 +02:00
_this = this ;
2020-07-21 15:08:40 +02:00
this . defaults = {
settings : {
2020-08-31 16:38:37 +02:00
addTimeline : { value : true , description : "Show the song timeline in the controls" }
} ,
buttonConfigs : {
share : { value : { small : false , big : true } , icons : [ "" ] , description : "Share" } ,
shuffle : { value : { small : false , big : true } , icons : [ "" ] , description : "Shuffle" } ,
previous : { value : { small : true , big : true } , icons : [ "" ] , description : "Previous" } ,
pauseplay : { value : { small : true , big : true } , icons : [ "" , "" ] , description : "Pause/Play" } ,
next : { value : { small : true , big : true } , icons : [ "" ] , description : "Next" } ,
repeat : { value : { small : false , big : true } , icons : [ "" , "" ] , description : "Repeat" } ,
volume : { value : { small : false , big : true } , icons : [ "" , "" , "" , "" ] , description : "Volume" }
2020-07-21 15:08:40 +02:00
}
} ;
2020-07-19 16:59:08 +02:00
this . css = `
@ font - face {
font - family : glue1 - spoticon ;
src : url ( "https://mwittrien.github.io/BetterDiscordAddons/Plugins/SpotifyControls/res/spoticon.ttf" ) format ( "truetype" ) ;
font - weight : 400 ;
font - style : normal
}
$ { BDFDB . dotCN . _spotifycontrolscontainer } {
2020-07-21 15:08:40 +02:00
display : flex ;
flex - direction : column ;
justify - content : center ;
min - height : 52 px ;
2020-07-19 16:59:08 +02:00
margin - bottom : 1 px ;
border - bottom : 1 px solid var ( -- background - modifier - accent ) ;
2020-07-21 15:08:40 +02:00
padding : 0 8 px ;
box - sizing : border - box ;
}
$ { BDFDB . dotCN . _spotifycontrolscontainer + BDFDB . dotCN . _spotifycontrolscontainerwithtimeline } {
padding - top : 8 px ;
2020-07-19 16:59:08 +02:00
}
$ { BDFDB . dotCN . _spotifycontrolscontainerinner } {
display : flex ;
align - items : center ;
font - size : 14 px ;
2020-07-23 16:12:08 +02:00
width : 100 % ;
2020-07-19 16:59:08 +02:00
}
2020-07-21 15:15:26 +02:00
$ { BDFDB . dotCN . _spotifycontrolstimeline } {
2020-07-23 20:23:23 +02:00
margin : 6 px 0 4 px 0 ;
2020-07-19 16:59:08 +02:00
}
$ { BDFDB . dotCN . _spotifycontrolsbar } {
2020-07-23 20:23:23 +02:00
position : relative ;
2020-07-19 16:59:08 +02:00
border - radius : 2 px ;
background - color : rgba ( 79 , 84 , 92 , 0.16 ) ;
height : 4 px ;
margin - bottom : 4 px ;
}
$ { BDFDB . dotCN . _spotifycontrolsbarfill } {
border - radius : 2 px ;
height : 100 % ;
min - width : 4 px ;
border - radius : 2 px ;
2020-07-21 15:18:00 +02:00
background : var ( -- text - normal ) ;
2020-07-19 16:59:08 +02:00
}
2020-07-23 20:23:23 +02:00
$ { BDFDB . dotCN . _spotifycontrolstimeline } : hover $ { BDFDB . dotCN . _spotifycontrolsbarfill } {
background : $ { BDFDB . DiscordConstants . Colors . SPOTIFY } ;
}
$ { BDFDB . dotCN . _spotifycontrolsbargrabber } {
display : none ;
position : absolute ;
top : 0 ;
left : 0 ;
width : 8 px ;
height : 8 px ;
margin - top : - 2 px ;
margin - left : - 2 px ;
background : var ( -- text - normal ) ;
border - radius : 50 % ;
}
$ { BDFDB . dotCN . _spotifycontrolstimeline } : hover $ { BDFDB . dotCN . _spotifycontrolsbargrabber } {
display : block ;
}
2020-07-19 16:59:08 +02:00
$ { BDFDB . dotCN . _spotifycontrolsbartext } {
display : flex ;
align - items : center ;
justify - content : space - between ;
}
2020-07-23 16:12:08 +02:00
$ { BDFDB . dotCN . _spotifycontrolscoverwrapper } {
position : relative ;
2020-07-19 16:59:08 +02:00
width : 32 px ;
2020-07-23 16:12:08 +02:00
min - width : 32 px ;
2020-07-19 16:59:08 +02:00
height : 32 px ;
2020-07-23 16:12:08 +02:00
min - height : 32 px ;
2020-07-19 16:59:08 +02:00
margin - right : 8 px ;
border - radius : 4 px ;
2020-07-23 16:12:08 +02:00
overflow : hidden ;
transition : width . 3 s ease , height . 3 s ease ;
}
$ { BDFDB . dotCN . _spotifycontrolscover } {
display : block ;
width : 100 % ;
height : 100 % ;
2020-07-19 16:59:08 +02:00
object - fit : cover ;
}
2020-07-23 16:12:08 +02:00
$ { BDFDB . dotCN . _spotifycontrolscovermaximizer } {
visibility : hidden ;
position : absolute ;
background - color : rgba ( 0 , 0 , 0 , 0.5 ) ;
color : rgba ( 255 , 255 , 255 , 0.5 ) ;
top : 0 ;
right : 0 ;
border - radius : 50 % ;
width : 12 px ;
height : 12 px ;
padding : 3 px ;
transform : rotate ( 90 deg ) ;
transition : width . 3 s ease , height . 3 s ease , transform . 3 s ease ;
pointer - events : none ;
}
$ { BDFDB . dotCN . _spotifycontrolscoverwrapper } : hover $ { BDFDB . dotCN . _spotifycontrolscovermaximizer } {
visibility : visible ;
}
2020-07-19 16:59:08 +02:00
$ { BDFDB . dotCN . _spotifycontrolsdetails } {
user - select : text ;
flex - grow : 1 ;
margin - right : 4 px ;
min - width : 0 ;
}
$ { BDFDB . dotCN . _spotifycontrolssong } {
font - weight : 500 ;
}
$ { BDFDB . dotCN . _spotifycontrolsinterpret } {
font - weight : 300 ;
}
2020-07-23 16:12:08 +02:00
$ { BDFDB . dotCN . _spotifycontrolsvolumeslider } {
2020-07-23 20:23:23 +02:00
height : 12 px ;
2020-07-23 16:12:08 +02:00
width : 140 px ;
margin : 5 px ;
}
$ { BDFDB . dotCNS . _spotifycontrolsvolumeslider + BDFDB . dotCN . slidergrabber } {
height : 10 px ;
margin - top : - 6 px ;
border - radius : 50 % ;
}
2020-07-23 20:23:23 +02:00
$ { BDFDB . dotCNS . _spotifycontrolscontainer + BDFDB . dotCN . accountinfobuttondisabled } {
cursor : no - drop ;
}
$ { BDFDB . dotCNS . _spotifycontrolscontainer + BDFDB . dotCNS . accountinfobutton + BDFDB . dotCN . buttoncontents } {
font - family : glue1 - spoticon ! important ;
}
2020-07-23 16:12:08 +02:00
$ { BDFDB . dotCNS . _spotifycontrolscontainer + BDFDB . dotCN . accountinfobutton + BDFDB . dotCN . _spotifycontrolsbuttonactive } {
color : $ { BDFDB . DiscordConstants . Colors . SPOTIFY } ;
}
$ { BDFDB . dotCN . _spotifycontrolscontainer + BDFDB . dotCN . _spotifycontrolscontainermaximized } {
padding - top : 0 ;
}
$ { BDFDB . dotCN . _spotifycontrolscontainer + BDFDB . dotCNS . _spotifycontrolscontainermaximized + BDFDB . dotCN . _spotifycontrolscontainerinner } {
flex - direction : column ;
}
$ { BDFDB . dotCN . _spotifycontrolscontainer + BDFDB . dotCNS . _spotifycontrolscontainermaximized + BDFDB . dotCN . _spotifycontrolsdetails } {
margin : 0 0 4 px 0 ;
width : 100 % ;
text - align : center ;
}
$ { BDFDB . dotCN . _spotifycontrolscontainer + BDFDB . dotCNS . _spotifycontrolscontainermaximized + BDFDB . dotCN . _spotifycontrolscoverwrapper } {
width : calc ( 100 % + 16 px ) ;
height : 100 % ;
margin : 0 0 8 px 0 ;
border - radius : 0 ;
}
$ { BDFDB . dotCN . _spotifycontrolscontainer + BDFDB . dotCNS . _spotifycontrolscontainermaximized + BDFDB . dotCN . _spotifycontrolscovermaximizer } {
top : 4 px ;
right : 4 px ;
width : 22 px ;
height : 22 px ;
padding : 5 px ;
transform : rotate ( - 90 deg ) ;
}
2020-08-31 16:38:37 +02:00
$ { BDFDB . dotCN . _spotifycontrolssettingsicon } {
margin : 4 px ;
font - size : 16 px ;
font - family : glue1 - spoticon ! important ;
}
$ { BDFDB . dotCN . _spotifycontrolssettingslabel } {
margin - left : 10 px ;
}
2020-07-19 16:59:08 +02:00
` ;
}
2020-07-23 20:23:23 +02:00
getSettingsPanel ( collapseStates = { } ) {
if ( ! window . BDFDB || typeof BDFDB != "object" || ! BDFDB . loaded || ! this . started ) return ;
let settingsPanel , settingsItems = [ ] ;
2020-08-31 16:38:37 +02:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Settings" ,
collapseStates : collapseStates ,
children : Object . keys ( settings ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom8 ,
type : "Switch" ,
plugin : this ,
keys : [ "settings" , key ] ,
label : this . defaults . settings [ key ] . description ,
value : settings [ key ]
} ) )
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Button Settings" ,
collapseStates : collapseStates ,
children : [ BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormTitle , {
className : BDFDB . disCN . marginbottom4 ,
tag : BDFDB . LibraryComponents . FormComponents . FormTitle . Tags . H3 ,
children : "Add control buttons in small and/or big player version:"
} ) ] . concat ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsList , {
settings : Object . keys ( this . defaults . buttonConfigs [ Object . keys ( this . defaults . buttonConfigs ) [ 0 ] ] . value ) ,
data : Object . keys ( buttonConfigs ) . map ( key => Object . assign ( { } , buttonConfigs [ key ] , {
key : key ,
label : this . defaults . buttonConfigs [ key ] . description ,
icons : this . defaults . buttonConfigs [ key ] . icons
} ) ) ,
noRemove : true ,
renderLabel : data => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
justify : BDFDB . LibraryComponents . Flex . Justify . CENTER ,
wrap : BDFDB . LibraryComponents . Flex . Wrap . WRAP ,
basis : 50 ,
grow : 0 ,
children : data . icons . map ( icon => BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolssettingsicon ,
children : icon
} ) )
} ) ,
BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _spotifycontrolssettingslabel ,
children : data . label
} )
]
} ) ,
onCheckboxChange : ( value , instance ) => {
buttonConfigs [ instance . props . cardId ] [ instance . props . settingId ] = value ;
BDFDB . DataUtils . save ( buttonConfigs , this , "buttonConfigs" ) ;
this . SettingsUpdated = true ;
}
} ) )
2020-07-23 20:23:23 +02:00
} ) ) ;
return settingsPanel = BDFDB . PluginUtils . createSettingsPanel ( this , settingsItems ) ;
}
2020-07-19 16:59:08 +02:00
// Legacy
2020-08-21 16:17:47 +02:00
load ( ) {
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) BDFDB . PluginUtils . load ( this ) ;
}
2020-07-19 16:59:08 +02:00
start ( ) {
if ( ! window . BDFDB ) window . BDFDB = { myPlugins : { } } ;
if ( window . BDFDB && window . BDFDB . myPlugins && typeof window . BDFDB . myPlugins == "object" ) window . BDFDB . myPlugins [ this . getName ( ) ] = this ;
let libraryScript = document . querySelector ( "head script#BDFDBLibraryScript" ) ;
if ( ! libraryScript || ( performance . now ( ) - libraryScript . getAttribute ( "date" ) ) > 600000 ) {
if ( libraryScript ) libraryScript . remove ( ) ;
libraryScript = document . createElement ( "script" ) ;
libraryScript . setAttribute ( "id" , "BDFDBLibraryScript" ) ;
libraryScript . setAttribute ( "type" , "text/javascript" ) ;
libraryScript . setAttribute ( "src" , "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js" ) ;
libraryScript . setAttribute ( "date" , performance . now ( ) ) ;
libraryScript . addEventListener ( "load" , _ => { this . initialize ( ) ; } ) ;
document . head . appendChild ( libraryScript ) ;
}
else if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) this . initialize ( ) ;
this . startTimeout = setTimeout ( _ => {
try { return this . initialize ( ) ; }
catch ( err ) { console . error ( ` %c[ ${ this . getName ( ) } ]%c ` , "color: #3a71c1; font-weight: 700;" , "" , "Fatal Error: Could not initiate plugin! " + err ) ; }
} , 30000 ) ;
}
initialize ( ) {
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
if ( this . started ) return ;
BDFDB . PluginUtils . init ( this ) ;
BDFDB . ModuleUtils . patch ( this , BDFDB . LibraryModules . SpotifyTrackUtils , "getActivity" , { after : e => {
2020-07-21 15:12:43 +02:00
if ( e . methodArguments [ 0 ] !== false ) {
if ( e . returnValue && e . returnValue . name == "Spotify" ) this . updatePlayer ( e . returnValue ) ;
else if ( ! e . returnValue ) this . updatePlayer ( null ) ;
}
2020-07-19 16:59:08 +02:00
} } ) ;
BDFDB . ModuleUtils . patch ( this , BDFDB . LibraryModules . SpotifyTrackUtils , "wasAutoPaused" , { instead : e => {
return false ;
} } ) ;
BDFDB . ModuleUtils . patch ( this , BDFDB . LibraryModules . SpotifyUtils , "pause" , { instead : e => {
return false ;
} } ) ;
2020-07-26 19:05:14 +02:00
if ( ! BDFDB . LibraryModules . SpotifyTrackUtils . hasConnectedAccount ( ) ) BDFDB . ModalUtils . open ( this , {
size : "SMALL" ,
header : this . name + ": Something is missing..." ,
subheader : "You need to connect a Spotify account" ,
text : "You are missing a connected Spotify account, without a connected account you won't be able to use Spotify Controls. To connect a Spotify account with your discord account click the button below." ,
buttons : [ {
contents : BDFDB . LanguageUtils . LanguageStrings . CONNECT ,
color : "BRAND" ,
close : true ,
click : modal => {
BDFDB . LibraryModules . UserSettingsUtils . open ( BDFDB . DiscordConstants . UserSettingsSections . CONNECTIONS )
}
} ]
} ) ;
2020-07-21 15:08:40 +02:00
this . forceUpdateAll ( ) ;
2020-07-19 16:59:08 +02:00
}
else {
console . error ( ` %c[ ${ this . getName ( ) } ]%c ` , 'color: #3a71c1; font-weight: 700;' , '' , 'Fatal Error: Could not load BD functions!' ) ;
}
}
stop ( ) {
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
this . stopping = true ;
2020-07-21 15:08:40 +02:00
this . forceUpdateAll ( ) ;
2020-08-15 20:27:43 +02:00
if ( typeof insertPatchCancel == "function" ) insertPatchCancel ( ) ;
2020-07-19 16:59:08 +02:00
BDFDB . PluginUtils . clear ( this ) ;
}
}
// Begin of own functions
2020-07-21 15:08:40 +02:00
onSettingsClosed ( ) {
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
this . forceUpdateAll ( ) ;
}
}
2020-08-15 20:27:43 +02:00
processAppView ( e ) {
if ( typeof insertPatchCancel == "function" ) insertPatchCancel ( ) ;
insertPatchCancel = BDFDB . ModuleUtils . patch ( this , e . instance , "renderChannelSidebar" , { after : e2 => {
let [ children , index ] = BDFDB . ReactUtils . findParent ( e2 . returnValue , { props : [ [ "section" , BDFDB . DiscordConstants . AnalyticsSections . ACCOUNT _PANEL ] ] } ) ;
if ( index > - 1 ) children . splice ( index - 1 , 0 , BDFDB . ReactUtils . createElement ( SpotifyControlsComponent , {
song : BDFDB . LibraryModules . SpotifyTrackUtils . getActivity ( false ) ,
maximized : BDFDB . DataUtils . load ( this , "playerState" , "maximized" ) ,
timeline : settings . addTimeline
2020-08-31 16:38:37 +02:00
} , true ) ) ;
2020-08-15 20:27:43 +02:00
} } , { force : true , noCache : true } ) ;
2020-07-19 16:59:08 +02:00
}
updatePlayer ( song ) {
if ( controls ) {
controls . props . song = song ;
BDFDB . ReactUtils . forceUpdate ( controls ) ;
}
}
2020-07-21 15:08:40 +02:00
forceUpdateAll ( ) {
settings = BDFDB . DataUtils . get ( this , "settings" ) ;
2020-08-31 16:38:37 +02:00
buttonConfigs = BDFDB . DataUtils . get ( this , "buttonConfigs" ) ;
2020-07-21 15:08:40 +02:00
BDFDB . ModuleUtils . forceAllUpdates ( this ) ;
}
2020-07-19 16:59:08 +02:00
}
2020-07-26 17:02:25 +02:00
} ) ( ) ;
module . exports = SpotifyControls ;