2019-09-20 22:32:52 +02:00
//META{"name":"FriendNotifications","website":"https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/FriendNotifications","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/FriendNotifications/FriendNotifications.plugin.js"}*//
2018-10-11 10:21:26 +02:00
class FriendNotifications {
2019-01-17 23:48:29 +01:00
getName ( ) { return "FriendNotifications" ; }
2020-01-22 13:54:03 +01:00
getVersion ( ) { return "1.3.8" ; }
2019-01-17 23:48:29 +01:00
getAuthor ( ) { return "DevilBro" ; }
2019-08-22 16:17:21 +02:00
getDescription ( ) { return "Notifies you when a Friend or a User your choose to observe changing his online status, can be configured individually in the settings." ; }
2019-01-26 22:45:19 +01:00
2019-09-04 12:34:02 +02:00
constructor ( ) {
2019-05-01 21:02:25 +02:00
this . changelog = {
2020-01-22 13:54:03 +01:00
"improved" : [ [ "New Library Structure & React" , "Restructured my Library and switched to React rendering instead of DOM manipulation" ] ]
2019-01-03 10:20:41 +01:00
} ;
2019-09-04 12:34:02 +02:00
}
2019-01-26 22:45:19 +01:00
2019-09-04 12:34:02 +02:00
initConstructor ( ) {
2019-08-22 16:17:21 +02:00
this . userStatusStore = { } ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . timeLog = [ ] ;
2020-01-22 13:54:03 +01:00
this . lastTimes = { } ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . css = `
2020-01-22 13:54:03 +01:00
. $ { this . name } - Log - modal . log - time {
width : 160 px ;
}
. $ { this . name } - Log - modal . log - user {
margin : 0 10 px ;
2018-10-11 10:21:26 +02:00
}
2020-01-22 13:54:03 +01:00
. $ { this . name } - Log - modal . log - content {
max - width : 600 px ;
2018-10-11 10:21:26 +02:00
}
2020-01-22 13:54:03 +01:00
. $ { this . name } - settings . type - label {
2018-10-11 10:21:26 +02:00
border - radius : 3 px ;
padding : 0 3 px ;
2020-01-22 13:54:03 +01:00
margin : 0 6 px ;
2018-10-11 10:21:26 +02:00
}
2020-01-22 13:54:03 +01:00
. $ { this . name } - settings . settings - name {
max - width : 200 px ;
2018-10-11 10:21:26 +02:00
}
2019-01-24 13:37:08 +01:00
. $ { this . name } - settings . settings - avatar {
2020-01-22 13:54:03 +01:00
margin - right : 15 px ;
2018-10-11 10:21:26 +02:00
}
2019-01-24 13:37:08 +01:00
. $ { this . name } - settings . settings - avatar . disabled {
2019-08-22 16:17:21 +02:00
filter : grayscale ( 100 % ) brightness ( 50 % ) ;
2018-11-19 14:54:44 +01:00
} ` ;
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
this . defaults = {
settings : {
2019-09-19 16:02:12 +02:00
disableForNew : { value : false , description : "Disable Notifications for newly added Friends:" } ,
2018-10-11 10:21:26 +02:00
muteOnDND : { value : false , description : "Do not notify me when I am DnD:" } ,
openOnClick : { value : false , description : "Open the DM when you click a Notification:" }
2018-11-23 14:37:30 +01:00
} ,
2019-08-27 13:07:48 +02:00
notificationstrings : {
2019-09-19 16:02:12 +02:00
online : { value : "$user changed status to '$status'" , libstring : "STATUS_ONLINE" , init : true } ,
mobile : { value : "$user changed status to '$status'" , libstring : "STATUS_ONLINE_MOBILE" , init : true } ,
idle : { value : "$user changed status to '$status'" , libstring : "STATUS_IDLE" , init : false } ,
dnd : { value : "$user changed status to '$status'" , libstring : "STATUS_DND" , init : false } ,
playing : { value : "$user started playing '$game'" , statusname : "Playing" , init : false } ,
listening : { value : "$user started listening to '$song'" , statusname : "Listening" , init : false } ,
streaming : { value : "$user started streaming '$game'" , libstring : "STATUS_STREAMING" , init : false } ,
offline : { value : "$user changed status to '$status'" , libstring : "STATUS_OFFLINE" , init : true }
2019-08-27 13:07:48 +02:00
} ,
2019-09-19 19:32:29 +02:00
notificationsounds : { } ,
2019-08-22 16:17:21 +02:00
amounts : {
2019-10-02 12:53:51 +02:00
toastTime : { value : 5 , min : 1 , description : "Amount of seconds a toast notification stays on screen:" } ,
desktopTime : { value : 5 , min : 1 , description : "Amount of seconds a desktop notification stays on screen:" } ,
2019-08-22 16:17:21 +02:00
checkInterval : { value : 10 , min : 5 , description : "Check Users every X seconds:" }
2018-10-11 10:21:26 +02:00
}
} ;
2019-09-19 19:32:29 +02:00
for ( let type in this . defaults . notificationstrings ) {
this . defaults . notificationsounds [ "toast" + type ] = { value : { url : null , song : null , mute : false } } ;
this . defaults . notificationsounds [ "desktop" + type ] = { value : { url : null , song : null , mute : false } } ;
}
2019-09-19 16:02:12 +02:00
this . activityTypes = { } ;
for ( let type in BDFDB . DiscordConstants . ActivityTypes ) this . activityTypes [ BDFDB . DiscordConstants . ActivityTypes [ type ] ] = type ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-01-22 13:54:03 +01:00
getSettingsPanel ( collapseStates = { } ) {
2020-01-17 19:50:31 +01:00
if ( ! window . BDFDB || typeof BDFDB != "object" || ! BDFDB . loaded || ! this . started ) return ;
2020-01-22 13:54:03 +01:00
let changeNotificationType = ( type , userId , desktopon , disableon ) => {
let data = BDFDB . DataUtils . load ( this , type , userId ) || this . createDefaultConfig ( ) ;
data . desktop = desktopon ;
data . disabled = disableon ;
BDFDB . DataUtils . save ( data , this , type , userId ) ;
this . SettingsUpdated = true ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingspanel , collapseStates ) ;
} ;
let changeAllConfigs = ( type , config , enable ) => {
let data = BDFDB . DataUtils . load ( this , type ) ;
if ( config == "type" ) {
config = "desktop" ;
enable = ! enable ;
for ( let id in data ) data [ id ] . disabled = false ;
}
for ( let id in data ) data [ id ] [ config ] = enable ;
BDFDB . DataUtils . save ( data , this , type ) ;
this . SettingsUpdated = true ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingspanel , collapseStates ) ;
} ;
let successSavedAudio = ( type , parsedurl , parseddata ) => {
if ( parsedurl && parseddata ) BDFDB . NotificationUtils . toast ( ` Sound was saved successfully. ` , { type : "success" } ) ;
let notificationsound = BDFDB . DataUtils . get ( this , "notificationsounds" , type ) ;
notificationsound . url = parsedurl ;
notificationsound . song = parseddata ;
BDFDB . DataUtils . save ( notificationsound , this , "notificationsounds" , type ) ;
this . SettingsUpdated = true ;
} ;
let createUserList = ( users , type , title ) => {
let items = [ ] ;
items . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCNS . titledefault + BDFDB . disCN . cursordefault ,
children : [
"Click on an Icon to toggle" ,
BDFDB . ReactUtils . createElement ( "span" , {
className : "type-label" ,
style : { backgroundColor : BDFDB . DiscordConstants . Colors . BRAND } ,
children : "Toast"
} ) ,
"Notifications for that User:"
]
} ) ) ;
if ( "Notification" in window ) items . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCNS . titledefault + BDFDB . disCN . cursordefault ,
children : [
"Right-Click on an Icon to toggle" ,
BDFDB . ReactUtils . createElement ( "span" , {
className : "type-label" ,
style : { backgroundColor : BDFDB . DiscordConstants . Colors . STATUS _GREEN } ,
children : "Desktop"
} ) ,
"Notifications for that User:"
]
} ) ) ;
items . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsList , {
className : BDFDB . disCN . margintop20 ,
title : "type" ,
settings : Object . keys ( this . defaults . notificationstrings ) ,
data : users ,
renderLabel : data => [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Avatar , {
className : BDFDB . DOMUtils . formatClassName ( "settings-avatar" , data . disabled && "disabled" , data . destop && "desktop" ) ,
src : BDFDB . UserUtils . getAvatar ( data . user . id ) ,
status : BDFDB . UserUtils . getStatus ( data . user . id ) ,
size : BDFDB . LibraryComponents . Avatar . Sizes . SIZE _40 ,
onClick : ( e , instance ) => {
changeNotificationType ( type , data . user . id , false , ! ( data . disabled || data . desktop ) ) ;
} ,
onContextMenu : ( e , instance ) => {
changeNotificationType ( type , data . user . id , true , ! ( data . disabled || ! data . desktop ) ) ;
}
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextScroller , {
children : data . user . username
} )
] ,
onHeaderClick : ( config , instance ) => {
changeAllConfigs ( type , config , true ) ;
} ,
onHeaderContextMenu : ( config , instance ) => {
changeAllConfigs ( type , config , false ) ;
} ,
onCheckboxChange : ( value , instance ) => {
let data = BDFDB . DataUtils . load ( this , type , instance . props . cardId ) || this . createDefaultConfig ( ) ;
data [ instance . props . settingId ] = value ;
BDFDB . DataUtils . save ( data , this , type , instance . props . cardId ) ;
this . SettingsUpdated = true ;
} ,
noRemove : type == "friends" ,
onRemove : ( e , instance ) => {
BDFDB . DataUtils . remove ( this , type , instance . props . cardId ) ;
this . SettingsUpdated = true ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingspanel , collapseStates ) ;
}
} ) ) ;
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : title ,
collapseStates : collapseStates ,
dividertop : true ,
children : items
} ) ;
} ;
2019-10-22 19:49:57 +02:00
let settings = BDFDB . DataUtils . get ( this , "settings" ) ;
2020-01-22 13:54:03 +01:00
let amounts = BDFDB . DataUtils . get ( this , "amounts" ) ;
2019-10-22 19:49:57 +02:00
let notificationstrings = BDFDB . DataUtils . get ( this , "notificationstrings" ) ;
let notificationsounds = BDFDB . DataUtils . get ( this , "notificationsounds" ) ;
2019-09-04 12:34:02 +02:00
2019-09-11 12:14:43 +02:00
let friendIDs = BDFDB . LibraryModules . FriendUtils . getFriendIDs ( ) ;
2020-01-22 13:54:03 +01:00
let friendsData = BDFDB . DataUtils . load ( this , "friends" ) , nonFriendsData = BDFDB . DataUtils . load ( this , "nonfriends" ) ;
let friends = [ ] , nonFriends = [ ] ;
let settingspanel , settingsitems = [ ] , inneritems = [ ] ;
2019-08-22 16:17:21 +02:00
for ( let id of friendIDs ) {
2019-09-11 12:14:43 +02:00
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
2019-08-22 16:17:21 +02:00
if ( user ) {
2020-01-22 13:54:03 +01:00
friendsData [ id ] = Object . assign ( { } , friendsData [ id ] || nonFriendsData [ id ] || this . createDefaultConfig ( ) ) ;
delete nonFriendsData [ id ] ;
2019-08-22 16:17:21 +02:00
}
2018-11-23 14:37:30 +01:00
}
2020-01-22 13:54:03 +01:00
for ( let id in friendsData ) {
2019-12-17 11:15:02 +01:00
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
if ( user ) {
2020-01-22 13:54:03 +01:00
if ( ! friendIDs . includes ( id ) ) {
nonFriendsData [ id ] = Object . assign ( { } , friendsData [ id ] ) ;
delete friendsData [ id ] ;
}
else friends . push ( Object . assign ( { } , friendsData [ id ] , { key : id , user , className : friendsData [ id ] . disabled ? "" : ( friendsData [ id ] . desktop ? BDFDB . disCN . cardsuccessoutline : BDFDB . disCN . cardbrandoutline ) } ) ) ;
2019-12-17 11:15:02 +01:00
}
}
2020-01-22 13:54:03 +01:00
for ( let id in nonFriendsData ) {
2019-09-11 12:14:43 +02:00
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
2020-01-22 13:54:03 +01:00
if ( user ) nonFriends . push ( Object . assign ( { } , nonFriendsData [ id ] , { key : id , user , className : nonFriendsData [ id ] . disabled ? "" : ( nonFriendsData [ id ] . desktop ? BDFDB . disCN . cardsuccessoutline : BDFDB . disCN . cardbrandoutline ) } ) ) ;
2019-08-27 13:07:48 +02:00
}
2019-09-04 12:34:02 +02:00
2020-01-22 13:54:03 +01:00
BDFDB . DataUtils . save ( friendsData , this , "friends" ) ;
BDFDB . DataUtils . save ( nonFriendsData , this , "nonfriends" ) ;
for ( let key in settings ) inneritems . push ( 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 ]
} ) ) ;
for ( let key in amounts ) if ( key . indexOf ( "desktop" ) == - 1 || "Notification" in window ) inneritems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom8 ,
type : "TextInput" ,
childProps : {
type : "number"
} ,
plugin : this ,
keys : [ "amounts" , key ] ,
label : this . defaults . amounts [ key ] . description ,
basis : "20%" ,
min : this . defaults . amounts [ key ] . min ,
max : this . defaults . amounts [ key ] . max ,
value : amounts [ key ]
} ) ) ;
settingsitems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Settings" ,
collapseStates : collapseStates ,
children : inneritems
} ) ) ;
if ( friends . length ) settingsitems . push ( createUserList ( friends , "friends" , "Friend-List" ) ) ;
settingsitems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Add new Stranger" ,
collapseStates : collapseStates ,
dividertop : true ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . margintop8 ,
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
className : ` input-newstranger ` ,
placeholder : "userId" ,
value : ""
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
onClick : _ => {
let userId = settingspanel . querySelector ( ` .input-newstranger ` + BDFDB . dotCN . input ) . value . trim ( ) ;
if ( friendIDs . includes ( userId ) ) BDFDB . NotificationUtils . toast ( "User is already a friend of yours. Please use the 'Friend-List' area to configure him/her." , { type : "error" } ) ;
else if ( Object . keys ( nonFriends ) . includes ( userId ) ) BDFDB . NotificationUtils . toast ( "User is already being observed as a 'Stranger'." , { type : "error" } ) ;
else {
let user = BDFDB . LibraryModules . UserStore . getUser ( userId ) ;
if ( user ) {
BDFDB . DataUtils . save ( this . createDefaultConfig ( ) , this , "nonfriends" , userId ) ;
this . SettingsUpdated = true ;
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingspanel , collapseStates ) ;
}
else if ( /.+#[0-9]{4}/ . test ( userId ) ) BDFDB . NotificationUtils . toast ( "A UserID does not consist of the username and discriminator." , { type : "error" } ) ;
else BDFDB . NotificationUtils . toast ( "Please enter a valid UserID of a user that has been loaded in your client." , { type : "error" } ) ;
}
} ,
children : BDFDB . LanguageUtils . LanguageStrings . ADD
} )
]
} )
} ) ) ;
if ( nonFriends . length ) settingsitems . push ( createUserList ( nonFriends , "nonfriends" , "Stranger-List" ) ) ;
settingsitems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "LogIn/-Out Timelog" ,
collapseStates : collapseStates ,
dividertop : true ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Button" ,
className : BDFDB . disCN . marginbottom8 ,
label : "Overview of LogIns/-Outs of current Session" ,
onClick : _ => { this . showTimeLog ( ) } ,
children : "Timelog"
} )
} ) ) ;
settingsitems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Notification Messages" ,
collapseStates : collapseStates ,
dividertop : true ,
children : [ BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
children : BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCNS . titledefault + BDFDB . disCN . cursordefault ,
children : [
"Allows you to configure your own message strings for the different statuses. " ,
BDFDB . ReactUtils . createElement ( "strong" , { children : "$user" } ) ,
" is the placeholder for the username, " ,
BDFDB . ReactUtils . createElement ( "strong" , { children : "$status" } ) ,
" for the statusname, " ,
BDFDB . ReactUtils . createElement ( "strong" , { children : "$game" } ) ,
" for the gamename, " ,
BDFDB . ReactUtils . createElement ( "strong" , { children : "$song" } ) ,
" for the songname and " ,
BDFDB . ReactUtils . createElement ( "strong" , { children : "$artist" } ) ,
" for the songartist."
]
} )
} ) ] . concat ( Object . keys ( notificationstrings ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
className : BDFDB . disCN . marginbottom8 ,
type : "TextInput" ,
plugin : this ,
keys : [ "notificationstrings" , key ] ,
placeholder : this . defaults . notificationstrings [ key ] . value ,
label : ` ${ BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( key ) } Message: ` ,
basis : "70%" ,
value : notificationstrings [ key ]
} ) ) )
} ) ) ;
settingsitems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : "Notification Sounds" ,
collapseStates : collapseStates ,
dividertop : true ,
children : Object . keys ( notificationsounds ) . map ( ( key , i ) => ( key . indexOf ( "desktop" ) == - 1 || "Notification" in window ) && [
i != 0 && key . indexOf ( "toast" ) == 0 && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormDivider , {
className : BDFDB . disCN . marginbottom8
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
direction : BDFDB . LibraryComponents . Flex . Direction . HORIZONTAL ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsLabel , {
label : ` ${ key . split ( /(desktop)|(toast)/ ) . filter ( n => n ) . map ( n => BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( n ) ) . join ( "-" ) } Notification Sound: ` ,
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Switch" ,
mini : true ,
grow : 0 ,
label : "Mute:" ,
value : notificationsounds [ key ] . mute ,
onChange : value => {
notificationsounds [ key ] . mute = value ;
BDFDB . DataUtils . save ( notificationsounds , this , "notificationsounds" ) ;
}
} )
] . filter ( n => n )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
className : ` input- ${ key } src ` ,
type : "file" ,
filter : [ "audio" , "video" ] ,
useFilePath : true ,
placeholder : "Url or Filepath" ,
value : notificationsounds [ key ] . url
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
onClick : _ => {
let source = settingspanel . querySelector ( ` .input- ${ key } src ` + BDFDB . dotCN . input ) . value . trim ( ) ;
if ( ! source . length ) {
BDFDB . NotificationUtils . toast ( ` Sound file was removed. ` , { type : "warn" } ) ;
successSavedAudio ( key , source , source ) ;
}
else if ( source . indexOf ( "http" ) == 0 ) BDFDB . LibraryRequires . request ( source , ( error , response , result ) => {
if ( response ) {
let type = response . headers [ "content-type" ] ;
if ( type && ( type . indexOf ( "octet-stream" ) > - 1 || type . indexOf ( "audio" ) > - 1 || type . indexOf ( "video" ) > - 1 ) ) {
successSavedAudio ( key , source , source ) ;
return ;
}
}
BDFDB . NotificationUtils . toast ( "Use a valid direct link to a video or audio source. They usually end on something like .mp3, .mp4 or .wav." , { type : "danger" } ) ;
} ) ;
else BDFDB . LibraryRequires . fs . readFile ( source , ( error , response ) => {
if ( error ) BDFDB . NotificationUtils . toast ( "Could not fetch file. Please make sure the file exists." , { type : "danger" } ) ;
else successSavedAudio ( key , source , ` data:audio/mpeg;base64, ${ response . toString ( "base64" ) } ` ) ;
} ) ;
} ,
children : BDFDB . LanguageUtils . LanguageStrings . SAVE
} )
]
} )
] ) . flat ( 10 ) . filter ( n => n )
} ) ) ;
return settingspanel = BDFDB . PluginUtils . createSettingsPanel ( this , settingsitems ) ;
2018-10-11 10:21:26 +02:00
}
//legacy
load ( ) { }
start ( ) {
2020-01-17 19:50:31 +01:00
if ( ! window . BDFDB ) window . BDFDB = { myPlugins : { } } ;
if ( window . BDFDB && window . BDFDB . myPlugins && typeof window . BDFDB . myPlugins == "object" ) window . BDFDB . myPlugins [ this . getName ( ) ] = this ;
2020-01-21 12:56:26 +01:00
let libraryScript = document . querySelector ( "head script#BDFDBLibraryScript" ) ;
2019-05-26 13:55:26 +02:00
if ( ! libraryScript || ( performance . now ( ) - libraryScript . getAttribute ( "date" ) ) > 600000 ) {
2018-10-11 10:21:26 +02:00
if ( libraryScript ) libraryScript . remove ( ) ;
libraryScript = document . createElement ( "script" ) ;
2019-05-26 13:55:26 +02:00
libraryScript . setAttribute ( "id" , "BDFDBLibraryScript" ) ;
2018-10-11 10:21:26 +02:00
libraryScript . setAttribute ( "type" , "text/javascript" ) ;
2019-10-18 10:56:41 +02:00
libraryScript . setAttribute ( "src" , "https://mwittrien.github.io/BetterDiscordAddons/Plugins/BDFDB.min.js" ) ;
2019-01-17 23:48:29 +01:00
libraryScript . setAttribute ( "date" , performance . now ( ) ) ;
2020-01-14 00:06:07 +01:00
libraryScript . addEventListener ( "load" , _ => { this . initialize ( ) ; } ) ;
2018-10-11 10:21:26 +02:00
document . head . appendChild ( libraryScript ) ;
2019-05-26 13:55:26 +02:00
}
2020-01-17 19:50:31 +01:00
else if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) this . initialize ( ) ;
2020-01-14 00:06:07 +01:00
this . startTimeout = setTimeout ( _ => {
2019-11-01 10:27:07 +01:00
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 ) ;
2018-10-11 10:21:26 +02:00
}
initialize ( ) {
2020-01-17 19:50:31 +01:00
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
2019-01-22 11:05:54 +01:00
if ( this . started ) return ;
2019-10-22 18:55:25 +02:00
BDFDB . PluginUtils . init ( this ) ;
2019-01-26 22:45:19 +01:00
2019-05-01 21:02:25 +02:00
this . startInterval ( ) ;
2019-10-22 18:55:25 +02:00
BDFDB . ModuleUtils . forceAllUpdates ( this ) ;
2018-10-11 10:21:26 +02:00
}
2019-11-01 10:14:50 +01:00
else console . error ( ` %c[ ${ this . getName ( ) } ]%c ` , "color: #3a71c1; font-weight: 700;" , "" , "Fatal Error: Could not load BD functions!" ) ;
2018-10-11 10:21:26 +02:00
}
stop ( ) {
2020-01-17 19:50:31 +01:00
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
2019-10-22 11:37:23 +02:00
this . stopping = true ;
2019-11-01 11:09:32 +01:00
BDFDB . TimeUtils . clear ( this . checkInterval ) ;
2019-10-22 18:55:25 +02:00
BDFDB . PluginUtils . clear ( this ) ;
2018-10-11 10:21:26 +02:00
}
}
2019-01-26 22:45:19 +01:00
2018-10-11 10:21:26 +02:00
// begin of own functions
2019-09-04 12:34:02 +02:00
2019-12-17 11:15:02 +01:00
onSettingsClosed ( ) {
2019-08-22 16:17:21 +02:00
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
this . startInterval ( ) ;
}
2019-05-01 21:02:25 +02:00
}
2019-09-04 12:34:02 +02:00
2020-01-22 13:54:03 +01:00
createDefaultConfig ( ) {
return Object . assign ( {
desktop : false ,
disabled : BDFDB . DataUtils . get ( this , "settings" , "disableForNew" )
} , BDFDB . ObjectUtils . map ( this . defaults . notificationstrings , "init" ) ) ;
}
2019-09-19 16:02:12 +02:00
getStatusWithMobileAndActivity ( id , config ) {
2019-10-22 18:55:25 +02:00
let statusname = BDFDB . UserUtils . getStatus ( id ) ;
2019-09-19 16:02:12 +02:00
let status = { statusname , isactivity : false } ;
2019-11-01 11:32:38 +01:00
let activity = BDFDB . UserUtils . getActivitiy ( id ) ;
2019-09-19 16:02:12 +02:00
if ( activity && this . activityTypes [ activity . type ] ) {
let activityname = this . activityTypes [ activity . type ] . toLowerCase ( ) ;
if ( this . defaults . notificationstrings [ activityname ] && config [ activityname ] ) {
status = Object . assign ( { statusname : activityname , isactivity : true } , activity ) ;
2019-10-04 12:02:26 +02:00
if ( activityname == "listening" || activityname == "streaming" ) delete status . name ;
2019-09-19 16:02:12 +02:00
}
}
if ( status . statusname == "online" && BDFDB . LibraryModules . StatusMetaUtils . isMobileOnline ( id ) ) status . statusname = "mobile" ;
return status ;
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2019-05-01 21:02:25 +02:00
startInterval ( ) {
2019-11-01 11:09:32 +01:00
BDFDB . TimeUtils . clear ( this . checkInterval ) ;
2019-10-22 19:49:57 +02:00
let settings = BDFDB . DataUtils . get ( this , "settings" ) ;
let amounts = BDFDB . DataUtils . get ( this , "amounts" ) ;
let notificationstrings = BDFDB . DataUtils . get ( this , "notificationstrings" ) ;
let notificationsounds = BDFDB . DataUtils . get ( this , "notificationsounds" ) ;
let users = Object . assign ( { } , BDFDB . DataUtils . load ( this , "nonfriends" ) , BDFDB . DataUtils . load ( this , "friends" ) ) ;
2019-09-19 19:32:29 +02:00
for ( let id in users ) this . userStatusStore [ id ] = this . getStatusWithMobileAndActivity ( id , users [ id ] ) . statusname ;
2019-10-02 12:53:51 +02:00
let toasttime = ( amounts . toastTime > amounts . checkInterval ? amounts . checkInterval : amounts . toastTime ) * 1000 ;
let desktoptime = ( amounts . desktopTime > amounts . checkInterval ? amounts . checkInterval : amounts . desktopTime ) * 1000 ;
2020-01-14 00:06:07 +01:00
this . checkInterval = BDFDB . TimeUtils . interval ( _ => {
2019-08-22 16:17:21 +02:00
for ( let id in users ) if ( ! users [ id ] . disabled ) {
2019-09-11 12:14:43 +02:00
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
2019-09-19 16:02:12 +02:00
let status = this . getStatusWithMobileAndActivity ( id , users [ id ] ) ;
if ( user && this . userStatusStore [ id ] != status . statusname && users [ id ] [ status . statusname ] ) {
2020-01-22 13:54:03 +01:00
let EUdata = BDFDB . BDUtils . isPluginEnabled ( "EditUsers" ) && BDFDB . DataUtils . load ( "EditUsers" , "users" , user . id ) || { } ;
let name = EUdata . name || user . username ;
let avatar = EUdata . removeIcon ? "" : ( EUdata . url || BDFDB . UserUtils . getAvatar ( user . id ) ) ;
let timestring = ( new Date ( ) ) . toLocaleString ( ) ;
2019-10-19 11:41:39 +02:00
let libstring = ( this . defaults . notificationstrings [ status . statusname ] . libstring ? BDFDB . LanguageUtils . LanguageStrings [ this . defaults . notificationstrings [ status . statusname ] . libstring ] : ( this . defaults . notificationstrings [ status . statusname ] . statusname || "" ) ) . toLowerCase ( ) ;
2019-09-19 16:02:12 +02:00
let string = notificationstrings [ status . statusname ] || "$user changed status to $status" ;
2020-01-22 13:54:03 +01:00
let toaststring = BDFDB . StringUtils . htmlEscape ( string ) . replace ( /'{0,1}\$user'{0,1}/g , ` <strong> ${ BDFDB . StringUtils . htmlEscape ( name ) } </strong> ` ) . replace ( /'{0,1}\$status'{0,1}/g , ` <strong> ${ libstring } </strong> ` ) ;
2019-10-04 12:02:26 +02:00
if ( status . isactivity ) toaststring = toaststring . replace ( /'{0,1}\$song'{0,1}|'{0,1}\$game'{0,1}/g , ` <strong> ${ status . name || status . details } </strong> ` ) . replace ( /'{0,1}\$artist'{0,1}/g , ` <strong> ${ status . state } </strong> ` ) ;
2020-01-22 13:54:03 +01:00
this . timeLog . push ( {
string : toaststring ,
avatar ,
name ,
status : BDFDB . UserUtils . getStatus ( user . id ) ,
timestring
} ) ;
if ( ! ( settings . muteOnDND && BDFDB . UserUtils . getStatus ( ) == "dnd" ) && ( ! this . lastTimes [ user . id ] || this . lastTimes [ user . id ] != timestring ) ) {
this . lastTimes [ user . id ] = timestring ;
2020-01-14 00:06:07 +01:00
let openChannel = _ => {
2019-08-22 16:17:21 +02:00
if ( settings . openOnClick ) {
2019-10-22 23:04:58 +02:00
let DMid = BDFDB . LibraryModules . ChannelStore . getDMFromUserId ( user . id )
2019-09-11 12:14:43 +02:00
if ( DMid ) BDFDB . LibraryModules . SelectChannelUtils . selectPrivateChannel ( DMid ) ;
2019-10-22 18:55:25 +02:00
else BDFDB . LibraryModules . DirectMessageUtils . openPrivateChannel ( BDFDB . UserUtils . me . id , user . id ) ;
2019-12-30 09:32:59 +01:00
BDFDB . LibraryRequires . electron . remote . getCurrentWindow ( ) . focus ( ) ;
2019-08-22 16:17:21 +02:00
}
} ;
if ( ! users [ id ] . desktop ) {
2019-10-02 12:53:51 +02:00
if ( ! document . querySelector ( ` .friendnotifications- ${ id } -toast ` ) ) {
2019-10-22 18:55:25 +02:00
let toast = BDFDB . NotificationUtils . toast ( ` <div class="toast-inner"><div class="toast-avatar" style="background-image:url( ${ avatar } );"></div><div> ${ toaststring } </div></div> ` , { html : true , timeout : toasttime , color : BDFDB . UserUtils . getStatusColor ( status . statusname ) , icon : false , selector : ` friendnotifications- ${ status . statusname } -toast friendnotifications- ${ id } -toast ` } ) ;
2019-10-02 12:53:51 +02:00
toast . addEventListener ( "click" , openChannel ) ;
let notificationsound = notificationsounds [ "toast" + status . statusname ] || { } ;
if ( ! notificationsound . mute && notificationsound . song ) {
let audio = new Audio ( ) ;
audio . src = notificationsound . song ;
audio . play ( ) ;
}
2019-08-22 16:17:21 +02:00
}
}
else {
2020-01-22 13:54:03 +01:00
let desktopstring = string . replace ( /\$user/g , name ) . replace ( /\$status/g , libstring ) ;
2019-09-19 16:02:12 +02:00
if ( status . isactivity ) desktopstring = desktopstring . replace ( /\$song|\$game/g , status . name || status . details ) . replace ( /\$artist/g , status . state ) ;
let notificationsound = notificationsounds [ "desktop" + status . statusname ] || { } ;
2019-10-22 18:55:25 +02:00
BDFDB . NotificationUtils . desktop ( desktopstring , { icon : avatar , timeout : desktoptime , click : openChannel , silent : notificationsound . mute , sound : notificationsound . song } ) ;
2019-08-22 16:17:21 +02:00
}
}
}
2019-09-19 16:02:12 +02:00
this . userStatusStore [ id ] = status . statusname ;
2019-05-01 21:02:25 +02:00
}
2019-10-02 12:53:51 +02:00
} , amounts . checkInterval * 1000 ) ;
2020-01-22 13:54:03 +01:00
}
2019-05-01 21:02:25 +02:00
2019-01-17 23:48:29 +01:00
showTimeLog ( ) {
2020-01-22 13:54:03 +01:00
if ( ! this . timeLog . slice ( 0 ) . length ) BDFDB . NotificationUtils . toast ( "No logs saved yet" , { type : "error" } ) ;
else BDFDB . ModalUtils . open ( this , {
size : "MEDIUM" ,
header : "LogIn/-Out Timelog" ,
subheader : "" ,
className : ` ${ this . name } -Log-modal ` ,
children : this . timeLog . slice ( 0 ) . reverse ( ) . map ( ( log , i ) => [
i > 0 ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormDivider , {
className : BDFDB . disCNS . margintop8 + BDFDB . disCN . marginbottom8
} ) : null ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
color : BDFDB . LibraryComponents . TextElement . Colors . PRIMARY ,
className : "log-time" ,
children : ` [ ${ log . timestring } ] `
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Avatar , {
className : "log-user" ,
src : log . avatar ,
status : log . status ,
size : BDFDB . LibraryComponents . Avatar . Sizes . SIZE _40
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextScroller , {
className : "log-content" ,
speed : 1 ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextElement , {
color : BDFDB . LibraryComponents . TextElement . Colors . PRIMARY ,
children : BDFDB . ReactUtils . elementToReact ( BDFDB . DOMUtils . create ( log . string ) )
} )
} )
]
} )
] ) . flat ( 10 ) . filter ( n => n )
} ) ;
2018-10-11 10:21:26 +02:00
}
}