2020-02-27 08:44:03 +01:00
//META{"name":"FriendNotifications","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/FriendNotifications","source":"https://raw.githubusercontent.com/mwittrien/BetterDiscordAddons/master/Plugins/FriendNotifications/FriendNotifications.plugin.js"}*//
2018-10-11 10:21:26 +02:00
2020-02-09 14:51:48 +01:00
var FriendNotifications = ( _ => {
2020-04-15 09:14:05 +02:00
var _this ;
2020-04-13 19:58:23 +02:00
var userStatusStore , timeLog , lastTimes , friendCounter , checkInterval ;
2020-06-08 21:35:34 +02:00
var settings = { } , amounts = { } , notificationStrings = { } , notificationSounds = { } , observedUsers = { } ;
2020-02-20 23:12:40 +01:00
const FriendOnlineCounter = class FriendOnlineCounter extends BdApi . React . Component {
componentDidMount ( ) {
friendCounter = this ;
}
render ( ) {
return BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . guildouter ,
children : BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . _friendnotificationsfriendsonline ,
children : BDFDB . LanguageUtils . LanguageStringsFormat ( "FRIENDS_ONLINE_HEADER" , this . props . amount ) ,
onClick : _ => {
2020-04-15 09:14:05 +02:00
_this . showTimeLog ( ) ;
2020-02-20 23:12:40 +01:00
}
} )
} ) ;
}
} ;
2020-02-09 14:51:48 +01:00
return class FriendNotifications {
getName ( ) { return "FriendNotifications" ; }
2019-01-26 22:45:19 +01:00
2020-07-10 02:32:12 +02:00
getVersion ( ) { return "1.4.8" ; }
2019-01-26 22:45:19 +01:00
2020-02-09 14:51:48 +01:00
getAuthor ( ) { return "DevilBro" ; }
2019-01-26 22:45:19 +01:00
2020-02-10 13:14:20 +01:00
getDescription ( ) { return "Notifies you when a Friend or a User your choose to observe changes their online status, can be configured individually in the settings." ; }
2019-01-26 22:45:19 +01:00
2020-02-09 14:51:48 +01:00
constructor ( ) {
2020-06-29 18:50:47 +02:00
this . changelog = {
2020-07-12 17:55:10 +02:00
"fixed" : [ [ "200 cap" , "No longer caps timelog at 200 entries" ] ] ,
2020-07-06 13:34:43 +02:00
"improved" : [ [ "Pagination" , "Added Pagination to the settings and timelog, to stop the plugin from freezing for ppl who feel like they need to have over 500 friends on discord" ] ]
2020-06-29 18:50:47 +02:00
} ;
2020-02-20 23:12:40 +01:00
this . patchedModules = {
after : {
Guilds : "render"
}
} ;
2019-09-19 19:32:29 +02:00
}
2019-09-19 16:02:12 +02:00
2020-02-09 14:51:48 +01:00
initConstructor ( ) {
2020-04-15 09:14:05 +02:00
_this = this ;
2020-02-09 14:51:48 +01:00
userStatusStore = { } ;
timeLog = [ ] ;
lastTimes = { } ;
2020-02-20 23:12:40 +01:00
friendCounter = null ;
2020-01-22 13:54:03 +01:00
2020-02-09 14:51:48 +01:00
this . css = `
. $ { this . name } - Log - modal . log - time {
width : 160 px ;
2020-02-20 23:12:40 +01:00
}
2020-02-09 14:51:48 +01:00
. $ { this . name } - Log - modal . log - user {
margin : 0 10 px ;
2020-01-22 13:54:03 +01:00
}
2020-02-09 14:51:48 +01:00
. $ { this . name } - Log - modal . log - content {
max - width : 600 px ;
}
. $ { this . name } - settings . type - label {
border - radius : 3 px ;
padding : 0 3 px ;
margin : 0 6 px ;
}
. $ { this . name } - settings . settings - avatar {
margin - right : 15 px ;
}
. $ { this . name } - settings . settings - avatar . disabled {
filter : grayscale ( 100 % ) brightness ( 50 % ) ;
2020-02-20 23:12:40 +01:00
}
$ { BDFDB . dotCN . _friendnotificationsfriendsonline } {
color : var ( -- text - muted ) ;
text - align : center ;
text - transform : uppercase ;
font - size : 10 px ;
font - weight : 500 ;
line - height : 1.3 ;
width : 70 px ;
word - wrap : normal ;
white - space : nowrap ;
cursor : pointer ;
}
$ { BDFDB . dotCN . _friendnotificationsfriendsonline } : hover {
color : var ( -- header - secondary ) ;
}
$ { BDFDB . dotCN . _friendnotificationsfriendsonline } : active {
color : var ( -- header - primary ) ;
}
` ;
2019-09-04 12:34:02 +02:00
2020-02-09 14:51:48 +01:00
this . defaults = {
settings : {
2020-02-20 23:12:40 +01:00
addOnlineCount : { value : true , description : "Adds an online friend counter to the server list (click to open logs)" } ,
2020-02-09 14:51:48 +01:00
disableForNew : { value : false , description : "Disable Notifications for newly added Friends:" } ,
2020-02-20 23:12:40 +01: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" }
2020-02-09 14:51:48 +01:00
} ,
notificationstrings : {
2020-04-13 19:58:49 +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 } ,
2020-04-13 19:58:23 +02:00
playing : { value : "$user started playing '$game'" , statusName : "Playing" , init : false } ,
listening : { value : "$user started listening to '$song'" , statusName : "Listening" , init : false } ,
2020-04-13 19:58:49 +02:00
streaming : { value : "$user started streaming '$game'" , libString : "STATUS_STREAMING" , init : false } ,
offline : { value : "$user changed status to '$status'" , libString : "STATUS_OFFLINE" , init : true }
2020-02-09 14:51:48 +01:00
} ,
notificationsounds : { } ,
amounts : {
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:" } ,
checkInterval : { value : 10 , min : 5 , description : "Check Users every X seconds:" }
2020-01-22 13:54:03 +01:00
}
2020-02-09 14:51:48 +01: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-12-17 11:15:02 +01:00
}
2019-08-27 13:07:48 +02:00
}
2019-09-04 12:34:02 +02:00
2020-02-09 14:51:48 +01:00
getSettingsPanel ( collapseStates = { } ) {
if ( ! window . BDFDB || typeof BDFDB != "object" || ! BDFDB . loaded || ! this . started ) return ;
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 ;
2020-03-28 07:55:39 +01:00
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
2020-02-09 14:51:48 +01:00
} ;
let changeAllConfigs = ( type , config , enable ) => {
2020-06-08 21:35:34 +02:00
let allData = BDFDB . DataUtils . load ( this , type ) ;
2020-02-09 14:51:48 +01:00
if ( config == "type" ) {
config = "desktop" ;
enable = ! enable ;
2020-06-08 21:35:34 +02:00
let disabled = BDFDB . ObjectUtils . toArray ( allData ) . every ( d => ! d . disabled && d [ config ] == enable ) ;
for ( let id in allData ) allData [ id ] . disabled = disabled ;
2020-02-09 14:51:48 +01:00
}
2020-06-08 21:35:34 +02:00
for ( let id in allData ) allData [ id ] [ config ] = enable ;
BDFDB . DataUtils . save ( allData , this , type ) ;
2020-02-09 14:51:48 +01:00
this . SettingsUpdated = true ;
2020-03-28 07:55:39 +01:00
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
2020-02-09 14:51:48 +01:00
} ;
2020-06-08 21:35:34 +02:00
let successSavedAudio = ( type , parsedUrl , parsedData ) => {
if ( parsedUrl && parsedData ) BDFDB . NotificationUtils . toast ( ` Sound was saved successfully. ` , { type : "success" } ) ;
2020-06-09 09:03:02 +02:00
notificationSounds [ type ] . url = parsedUrl ;
notificationSounds [ type ] . song = parsedData ;
BDFDB . DataUtils . save ( notificationSounds [ type ] , this , "notificationsounds" , type ) ;
2020-02-09 14:51:48 +01:00
this . SettingsUpdated = true ;
} ;
let createUserList = ( users , type , title ) => {
let items = [ ] ;
items . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
2020-01-22 13:54:03 +01:00
className : BDFDB . disCNS . titledefault + BDFDB . disCN . cursordefault ,
children : [
2020-02-09 14:51:48 +01:00
"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:"
2020-01-22 13:54:03 +01:00
]
2020-02-09 14:51:48 +01:00
} ) ) ;
if ( "Notification" in window ) items . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCNS . titledefault + BDFDB . disCN . cursordefault ,
2020-01-22 13:54:03 +01:00
children : [
2020-02-09 14:51:48 +01:00
"Right-Click on an Icon to toggle" ,
BDFDB . ReactUtils . createElement ( "span" , {
className : "type-label" ,
style : { backgroundColor : BDFDB . DiscordConstants . Colors . STATUS _GREEN } ,
children : "Desktop"
2020-01-22 13:54:03 +01:00
} ) ,
2020-02-09 14:51:48 +01:00
"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 ,
2020-07-06 13:34:43 +02:00
pagination : {
alphabetKey : "username" ,
amount : 50
} ,
2020-02-09 14:51:48 +01:00
renderLabel : data => [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Avatar , {
className : BDFDB . DOMUtils . formatClassName ( "settings-avatar" , data . disabled && "disabled" , data . destop && "desktop" ) ,
2020-07-06 13:34:43 +02:00
src : BDFDB . UserUtils . getAvatar ( data . id ) ,
status : BDFDB . UserUtils . getStatus ( data . id ) ,
2020-02-09 14:51:48 +01:00
size : BDFDB . LibraryComponents . Avatar . Sizes . SIZE _40 ,
onClick : ( e , instance ) => {
2020-07-06 13:34:43 +02:00
changeNotificationType ( type , data . id , false , ! ( data . disabled || data . desktop ) ) ;
2020-02-09 14:51:48 +01:00
} ,
onContextMenu : ( e , instance ) => {
2020-07-06 13:34:43 +02:00
changeNotificationType ( type , data . id , true , ! ( data . disabled || ! data . desktop ) ) ;
2020-01-22 13:54:03 +01:00
}
2020-02-09 14:51:48 +01:00
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextScroller , {
2020-07-06 13:34:43 +02:00
children : data . username
2020-01-22 13:54:03 +01:00
} )
2020-02-09 14:51:48 +01:00
] ,
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 ) ;
2020-03-28 07:55:39 +01:00
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
2020-06-08 21:35:34 +02:00
this . SettingsUpdated = true ;
2020-02-09 14:51:48 +01:00
}
} ) ) ;
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
title : title ,
collapseStates : collapseStates ,
dividertop : true ,
children : items
} ) ;
} ;
let settings = BDFDB . DataUtils . get ( this , "settings" ) ;
let amounts = BDFDB . DataUtils . get ( this , "amounts" ) ;
2020-06-08 21:35:34 +02:00
let notificationStrings = BDFDB . DataUtils . get ( this , "notificationstrings" ) ;
let notificationSounds = BDFDB . DataUtils . get ( this , "notificationsounds" ) ;
2020-02-09 14:51:48 +01:00
2020-06-08 21:35:34 +02:00
let friendIds = BDFDB . LibraryModules . FriendUtils . getFriendIDs ( ) ;
2020-02-09 14:51:48 +01:00
let friendsData = BDFDB . DataUtils . load ( this , "friends" ) , nonFriendsData = BDFDB . DataUtils . load ( this , "nonfriends" ) ;
let friends = [ ] , nonFriends = [ ] ;
2020-03-28 07:55:39 +01:00
let settingsPanel , settingsItems = [ ] , innerItems = [ ] ;
2020-02-09 14:51:48 +01:00
2020-06-08 21:35:34 +02:00
for ( let id of friendIds ) {
2020-02-09 14:51:48 +01:00
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
if ( user ) {
friendsData [ id ] = Object . assign ( { } , friendsData [ id ] || nonFriendsData [ id ] || this . createDefaultConfig ( ) ) ;
delete nonFriendsData [ id ] ;
}
}
for ( let id in friendsData ) {
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
if ( user ) {
2020-06-08 21:35:34 +02:00
if ( ! friendIds . includes ( id ) ) {
2020-02-09 14:51:48 +01:00
nonFriendsData [ id ] = Object . assign ( { } , friendsData [ id ] ) ;
delete friendsData [ id ] ;
}
2020-07-06 16:16:09 +02:00
else if ( id != BDFDB . UserUtils . me . id ) friends . push ( Object . assign ( { } , user , friendsData [ id ] , { key : id , className : friendsData [ id ] . disabled ? "" : ( friendsData [ id ] . desktop ? BDFDB . disCN . cardsuccessoutline : BDFDB . disCN . cardbrandoutline ) } ) ) ;
2020-02-09 14:51:48 +01:00
}
}
for ( let id in nonFriendsData ) {
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
2020-07-06 16:16:09 +02:00
if ( user && id != BDFDB . UserUtils . me . id ) nonFriends . push ( Object . assign ( { } , user , nonFriendsData [ id ] , { key : id , className : nonFriendsData [ id ] . disabled ? "" : ( nonFriendsData [ id ] . desktop ? BDFDB . disCN . cardsuccessoutline : BDFDB . disCN . cardbrandoutline ) } ) ) ;
2020-02-09 14:51:48 +01:00
}
BDFDB . DataUtils . save ( friendsData , this , "friends" ) ;
BDFDB . DataUtils . save ( nonFriendsData , this , "nonfriends" ) ;
2020-03-28 07:55:39 +01:00
for ( let key in settings ) innerItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-02-09 14:51:48 +01:00
className : BDFDB . disCN . marginbottom8 ,
type : "Switch" ,
plugin : this ,
keys : [ "settings" , key ] ,
label : this . defaults . settings [ key ] . description ,
value : settings [ key ]
} ) ) ;
2020-03-28 07:55:39 +01:00
for ( let key in amounts ) if ( key . indexOf ( "desktop" ) == - 1 || "Notification" in window ) innerItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-02-09 14:51:48 +01:00
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 ]
} ) ) ;
2020-03-28 07:55:39 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-09 14:51:48 +01:00
title : "Settings" ,
collapseStates : collapseStates ,
2020-03-28 07:55:39 +01:00
children : innerItems
2020-02-09 14:51:48 +01:00
} ) ) ;
2020-03-28 07:55:39 +01:00
if ( friends . length ) settingsItems . push ( createUserList ( friends , "friends" , "Friend-List" ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-09 14:51:48 +01:00
title : "Add new Stranger" ,
collapseStates : collapseStates ,
dividertop : true ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . margintop8 ,
2020-01-22 13:54:03 +01:00
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
2020-02-09 14:51:48 +01:00
className : ` input-newstranger ` ,
2020-03-24 15:34:32 +01:00
placeholder : "user (id or name#discriminator)" ,
2020-02-09 14:51:48 +01:00
value : ""
2020-01-22 13:54:03 +01:00
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
onClick : _ => {
2020-03-28 07:55:39 +01:00
let userId = settingsPanel . querySelector ( ` .input-newstranger ` + BDFDB . dotCN . input ) . value . trim ( ) ;
2020-07-06 16:16:09 +02:00
if ( userId == BDFDB . UserUtils . me . id ) BDFDB . NotificationUtils . toast ( "Are you seriously trying to stalk yourself?" , { type : "error" } ) ;
else if ( friendIds . includes ( userId ) ) BDFDB . NotificationUtils . toast ( "User is already a friend of yours. Please use the 'Friend-List' area to configure them." , { type : "error" } ) ;
2020-02-09 14:51:48 +01:00
else if ( Object . keys ( nonFriends ) . includes ( userId ) ) BDFDB . NotificationUtils . toast ( "User is already being observed as a 'Stranger'." , { type : "error" } ) ;
else {
2020-06-29 18:50:47 +02:00
let user = /.+#[0-9]{4}/ . test ( userId ) ? BDFDB . LibraryModules . UserStore . findByTag ( userId . split ( "#" ) . slice ( 0 , - 1 ) . join ( "#" ) , userId . split ( "#" ) . pop ( ) ) : BDFDB . LibraryModules . UserStore . getUser ( userId ) ;
2020-02-09 14:51:48 +01:00
if ( user ) {
BDFDB . DataUtils . save ( this . createDefaultConfig ( ) , this , "nonfriends" , userId ) ;
2020-03-28 07:55:39 +01:00
BDFDB . PluginUtils . refreshSettingsPanel ( this , settingsPanel , collapseStates ) ;
2020-06-08 21:35:34 +02:00
this . SettingsUpdated = true ;
2020-01-22 13:54:03 +01:00
}
2020-02-09 14:51:48 +01:00
else BDFDB . NotificationUtils . toast ( "Please enter a valid UserID of a user that has been loaded in your client." , { type : "error" } ) ;
}
2020-01-22 13:54:03 +01:00
} ,
2020-02-09 14:51:48 +01:00
children : BDFDB . LanguageUtils . LanguageStrings . ADD
2020-01-22 13:54:03 +01:00
} )
]
} )
2020-02-09 14:51:48 +01:00
} ) ) ;
2020-03-28 07:55:39 +01:00
if ( nonFriends . length ) settingsItems . push ( createUserList ( nonFriends , "nonfriends" , "Stranger-List" ) ) ;
2020-02-09 14:51:48 +01:00
2020-03-28 07:55:39 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-09 14:51:48 +01:00
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"
} )
} ) ) ;
2020-03-28 07:55:39 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-09 14:51:48 +01:00
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" } ) ,
2020-04-13 19:58:23 +02:00
" for the statusName, " ,
2020-02-09 14:51:48 +01:00
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."
]
} )
2020-06-08 21:35:34 +02:00
} ) ] . concat ( Object . keys ( notificationStrings ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2020-02-09 14:51:48 +01:00
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%" ,
2020-06-08 21:35:34 +02:00
value : notificationStrings [ key ]
2020-02-09 14:51:48 +01:00
} ) ) )
} ) ) ;
2020-03-28 07:55:39 +01:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . CollapseContainer , {
2020-02-09 14:51:48 +01:00
title : "Notification Sounds" ,
collapseStates : collapseStates ,
dividertop : true ,
2020-06-08 21:35:34 +02:00
children : Object . keys ( notificationSounds ) . map ( ( key , i ) => ( key . indexOf ( "desktop" ) == - 1 || "Notification" in window ) && [
2020-02-09 14:51:48 +01:00
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:" ,
2020-06-08 21:35:34 +02:00
value : notificationSounds [ key ] . mute ,
2020-02-09 14:51:48 +01:00
onChange : value => {
2020-06-08 21:35:34 +02:00
notificationSounds [ key ] . mute = value ;
BDFDB . DataUtils . save ( notificationSounds , this , "notificationsounds" ) ;
2020-02-09 14:51:48 +01:00
}
} )
] . 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" ,
2020-06-08 21:35:34 +02:00
value : notificationSounds [ key ] . url
2020-02-09 14:51:48 +01:00
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Button , {
onClick : _ => {
2020-03-28 07:55:39 +01:00
let source = settingsPanel . querySelector ( ` .input- ${ key } src ` + BDFDB . dotCN . input ) . value . trim ( ) ;
2020-02-09 14:51:48 +01:00
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 )
} ) ) ;
2020-03-28 07:55:39 +01:00
return settingsPanel = BDFDB . PluginUtils . createSettingsPanel ( this , settingsItems ) ;
2020-02-09 14:51:48 +01:00
}
2018-10-11 10:21:26 +02:00
2020-04-11 19:32:58 +02:00
// Legacy
2020-02-09 14:51:48 +01:00
load ( ) { }
2018-10-11 10:21:26 +02:00
2020-02-09 14:51:48 +01: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 ) ;
2019-05-26 13:55:26 +02:00
}
2018-10-11 10:21:26 +02:00
2020-02-09 14:51:48 +01:00
initialize ( ) {
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
if ( this . started ) return ;
BDFDB . PluginUtils . init ( this ) ;
2019-01-26 22:45:19 +01:00
2020-02-09 14:51:48 +01:00
this . startInterval ( ) ;
2019-05-01 21:02:25 +02:00
2020-02-09 14:51:48 +01:00
BDFDB . ModuleUtils . forceAllUpdates ( this ) ;
}
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
}
2020-02-09 14:51:48 +01:00
stop ( ) {
if ( window . BDFDB && typeof BDFDB === "object" && BDFDB . loaded ) {
this . stopping = true ;
2019-10-22 11:37:23 +02:00
2020-02-20 23:12:40 +01:00
BDFDB . TimeUtils . clear ( checkInterval ) ;
BDFDB . ModuleUtils . forceAllUpdates ( this ) ;
2020-02-09 14:51:48 +01:00
BDFDB . PluginUtils . clear ( this ) ;
}
2018-10-11 10:21:26 +02:00
}
2019-01-26 22:45:19 +01:00
2020-04-11 19:32:58 +02:00
// Begin of own functions
2019-09-04 12:34:02 +02:00
2020-02-09 14:51:48 +01:00
onSettingsClosed ( ) {
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
2020-06-08 21:35:34 +02:00
2020-02-09 14:51:48 +01:00
this . startInterval ( ) ;
2020-06-08 21:35:34 +02:00
BDFDB . ModuleUtils . forceAllUpdates ( this ) ;
2020-02-09 14:51:48 +01:00
}
2019-08-22 16:17:21 +02:00
}
2020-02-20 23:12:40 +01:00
processGuilds ( e ) {
2020-06-08 21:35:34 +02:00
if ( settings . addOnlineCount ) {
2020-06-16 17:07:08 +02:00
let [ children , index ] = BDFDB . ReactUtils . findParent ( e . returnvalue , { name : "ConnectedUnreadDMs" } ) ;
2020-02-20 23:12:40 +01:00
if ( index > - 1 ) children . splice ( index , 0 , BDFDB . ReactUtils . createElement ( FriendOnlineCounter , {
2020-04-15 09:14:05 +02:00
amount : BDFDB . LibraryModules . StatusMetaUtils . getOnlineFriendCount ( )
2020-02-20 23:12:40 +01:00
} ) ) ;
}
}
2019-09-04 12:34:02 +02:00
2020-02-09 14:51:48 +01:00
createDefaultConfig ( ) {
return Object . assign ( {
desktop : false ,
2020-06-08 21:35:34 +02:00
disabled : settings . disableForNew
2020-02-09 14:51:48 +01:00
} , BDFDB . ObjectUtils . map ( this . defaults . notificationstrings , "init" ) ) ;
}
2020-01-22 13:54:03 +01:00
2020-02-09 14:51:48 +01:00
getStatusWithMobileAndActivity ( id , config ) {
2020-04-13 19:58:23 +02:00
let statusName = BDFDB . UserUtils . getStatus ( id ) ;
let status = { statusName , isActivity : false } ;
2020-02-09 14:51:48 +01:00
let activity = BDFDB . UserUtils . getActivitiy ( id ) ;
2020-04-13 19:58:23 +02:00
if ( activity && BDFDB . DiscordConstants . ActivityTypes [ activity . type ] ) {
let activityName = BDFDB . DiscordConstants . ActivityTypes [ activity . type ] . toLowerCase ( ) ;
if ( this . defaults . notificationstrings [ activityName ] && config [ activityName ] ) {
status = Object . assign ( { statusName : activityName , isActivity : true } , activity ) ;
if ( activityName == "listening" || activityName == "streaming" ) delete status . name ;
2020-02-09 14:51:48 +01:00
}
2019-09-19 16:02:12 +02:00
}
2020-04-13 19:58:23 +02:00
if ( status . statusName == "online" && BDFDB . LibraryModules . StatusMetaUtils . isMobileOnline ( id ) ) status . statusName = "mobile" ;
2020-02-09 14:51:48 +01:00
return status ;
2019-09-19 16:02:12 +02:00
}
2019-01-26 22:45:19 +01:00
2020-02-09 14:51:48 +01:00
startInterval ( ) {
2020-02-20 23:12:40 +01:00
BDFDB . TimeUtils . clear ( checkInterval ) ;
2020-04-13 19:58:49 +02:00
2020-06-08 21:35:34 +02:00
settings = BDFDB . DataUtils . get ( this , "settings" ) ;
amounts = BDFDB . DataUtils . get ( this , "amounts" ) ;
notificationStrings = BDFDB . DataUtils . get ( this , "notificationstrings" ) ;
notificationSounds = BDFDB . DataUtils . get ( this , "notificationsounds" ) ;
2020-04-13 19:58:49 +02:00
2020-06-08 21:35:34 +02:00
observedUsers = Object . assign ( { } , BDFDB . DataUtils . load ( this , "nonfriends" ) , BDFDB . DataUtils . load ( this , "friends" ) ) ;
2020-04-13 19:58:49 +02:00
2020-06-08 21:35:34 +02:00
for ( let id in observedUsers ) userStatusStore [ id ] = this . getStatusWithMobileAndActivity ( id , observedUsers [ id ] ) . statusName ;
2020-04-13 19:58:49 +02:00
let toastTime = ( amounts . toastTime > amounts . checkInterval ? amounts . checkInterval : amounts . toastTime ) * 1000 ;
let desktopTime = ( amounts . desktopTime > amounts . checkInterval ? amounts . checkInterval : amounts . desktopTime ) * 1000 ;
checkInterval = BDFDB . TimeUtils . interval ( _ => {
let amount = BDFDB . LibraryModules . StatusMetaUtils . getOnlineFriendCount ( ) ;
if ( friendCounter && friendCounter . props . amount != amount ) {
friendCounter . props . amount = amount ;
BDFDB . ReactUtils . forceUpdate ( friendCounter ) ;
}
2020-06-08 21:35:34 +02:00
for ( let id in observedUsers ) if ( ! observedUsers [ id ] . disabled ) {
2020-04-13 19:58:49 +02:00
let user = BDFDB . LibraryModules . UserStore . getUser ( id ) ;
2020-06-08 21:35:34 +02:00
let status = this . getStatusWithMobileAndActivity ( id , observedUsers [ id ] ) ;
if ( user && userStatusStore [ id ] != status . statusName && observedUsers [ id ] [ status . statusName ] ) {
2020-04-13 19:58:49 +02: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 ( ) ;
let libString = ( this . defaults . notificationstrings [ status . statusName ] . libString ? BDFDB . LanguageUtils . LanguageStrings [ this . defaults . notificationstrings [ status . statusName ] . libString ] : ( this . defaults . notificationstrings [ status . statusName ] . statusName || "" ) ) . toLowerCase ( ) ;
2020-06-08 21:35:34 +02:00
let string = notificationStrings [ status . statusName ] || "$user changed status to $status" ;
2020-04-13 19:58:49 +02: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> ` ) ;
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-07-06 22:32:02 +02:00
timeLog . unshift ( {
2020-04-13 19:58:49 +02:00
string : toaststring ,
avatar ,
name ,
status : BDFDB . UserUtils . getStatus ( user . id ) ,
timestring
} ) ;
if ( ! ( settings . muteOnDND && BDFDB . UserUtils . getStatus ( ) == BDFDB . DiscordConstants . StatusTypes . DND ) && ( ! lastTimes [ user . id ] || lastTimes [ user . id ] != timestring ) ) {
lastTimes [ user . id ] = timestring ;
let openChannel = _ => {
if ( settings . openOnClick ) {
let DMid = BDFDB . LibraryModules . ChannelStore . getDMFromUserId ( user . id )
if ( DMid ) BDFDB . LibraryModules . SelectChannelUtils . selectPrivateChannel ( DMid ) ;
else BDFDB . LibraryModules . DirectMessageUtils . openPrivateChannel ( BDFDB . UserUtils . me . id , user . id ) ;
BDFDB . LibraryRequires . electron . remote . getCurrentWindow ( ) . focus ( ) ;
}
} ;
2020-06-08 21:35:34 +02:00
if ( ! observedUsers [ id ] . desktop ) {
2020-04-13 19:58:49 +02:00
if ( ! document . querySelector ( ` .friendnotifications- ${ id } -toast ` ) ) {
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 ` } ) ;
toast . addEventListener ( "click" , openChannel ) ;
2020-06-08 21:35:34 +02:00
let notificationsound = notificationSounds [ "toast" + status . statusName ] || { } ;
2020-04-13 19:58:49 +02:00
if ( ! notificationsound . mute && notificationsound . song ) {
let audio = new Audio ( ) ;
audio . src = notificationsound . song ;
audio . play ( ) ;
}
}
}
else {
2020-06-08 21:35:34 +02:00
let desktopString = string . replace ( /\$user/g , name ) . replace ( /\$status/g , libString ) ;
if ( status . isActivity ) desktopString = desktopString . replace ( /\$song|\$game/g , status . name || status . details ) . replace ( /\$artist/g , status . state ) ;
let notificationsound = notificationSounds [ "desktop" + status . statusName ] || { } ;
BDFDB . NotificationUtils . desktop ( desktopString , { icon : avatar , timeout : desktopTime , click : openChannel , silent : notificationsound . mute , sound : notificationsound . song } ) ;
2020-02-09 14:51:48 +01:00
}
2019-08-22 16:17:21 +02:00
}
}
2020-04-13 19:58:23 +02:00
userStatusStore [ id ] = status . statusName ;
2019-08-22 16:17:21 +02:00
}
2020-02-09 14:51:48 +01:00
} , amounts . checkInterval * 1000 ) ;
}
2019-05-01 21:02:25 +02:00
2020-02-09 14:51:48 +01:00
showTimeLog ( ) {
2020-07-06 13:34:43 +02:00
if ( ! timeLog . length ) BDFDB . NotificationUtils . toast ( "No logs saved yet" , { type : "error" } ) ;
2020-02-09 14:51:48 +01:00
else BDFDB . ModalUtils . open ( this , {
size : "MEDIUM" ,
header : "LogIn/-Out Timelog" ,
subheader : "" ,
className : ` ${ this . name } -Log-modal ` ,
2020-07-06 13:34:43 +02:00
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . PaginatedList , {
2020-07-06 22:32:02 +02:00
items : timeLog ,
2020-07-06 13:34:43 +02:00
amount : 100 ,
copyToBottom : true ,
renderItem : ( log , i ) => {
return [
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 , {
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 , {
children : BDFDB . ReactUtils . elementToReact ( BDFDB . DOMUtils . create ( log . string ) )
} )
} )
]
2020-01-22 13:54:03 +01:00
} )
2020-02-09 14:51:48 +01:00
]
2020-07-06 13:34:43 +02:00
}
} )
2020-02-09 14:51:48 +01:00
} ) ;
}
2018-10-11 10:21:26 +02:00
}
2020-07-10 02:32:12 +02:00
} ) ( ) ;