-
-
Notifications
You must be signed in to change notification settings - Fork 775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added more moderation UI complete with user blocking/ignoring #3119
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import log from '@converse/headless/log.js'; | ||
import { _converse, api, converse } from "@converse/headless/core.js"; | ||
|
||
const { Strophe, $iq, sizzle, u } = converse.env; | ||
|
||
export default { | ||
/** | ||
* Retrieves the blocklist held by the logged in user at a JID by sending an IQ stanza. | ||
* Saves the model variable _converse.blocked.set | ||
* @private | ||
* @method api.refreshBlocklist | ||
*/ | ||
async refreshBlocklist () { | ||
const features = await api.disco.getFeatures(_converse.domain); | ||
if (!features?.findWhere({'var': Strophe.NS.BLOCKING})) { | ||
return false; | ||
} | ||
if (!_converse.connection) { | ||
return false; | ||
} | ||
|
||
const iq = $iq({ | ||
'type': 'get', | ||
'id': u.getUniqueId('blocklist') | ||
}).c('blocklist', {'xmlns': Strophe.NS.BLOCKING}); | ||
|
||
const result = await api.sendIQ(iq).catch(e => { log.fatal(e); return null }); | ||
if (result === null) { | ||
const err_msg = `An error occured while fetching the blocklist`; | ||
api.alert('error', __('Error'), err_msg); | ||
log(err_msg, Strophe.LogLevel.WARN); | ||
return false; | ||
} else if (u.isErrorStanza(result)) { | ||
log.error(`Error while fetching blocklist from ${jid}`); | ||
log.error(result); | ||
return false; | ||
} | ||
|
||
const blocklist = sizzle('item', result).map(item => item.getAttribute('jid')); | ||
_converse.blocked.set({'set': new Set(blocklist)}); | ||
return true; | ||
}, | ||
|
||
/** | ||
* Handle incoming iq stanzas in the BLOCKING namespace. Adjusts the global blocked_set. | ||
* @private | ||
* @method api.handleBlockingStanza | ||
* @param { Object } [stanza] - The incoming stanza to handle | ||
*/ | ||
async handleBlockingStanza ( stanza ) { | ||
if (stanza.firstElementChild.tagName === 'block') { | ||
const users_to_block = sizzle('item', stanza).map(item => item.getAttribute('jid')); | ||
users_to_block.forEach(_converse.blocked.get('set').add, _converse.blocked.get('set')); | ||
} else if (stanza.firstElementChild.tagName === 'unblock') { | ||
const users_to_unblock = sizzle('item', stanza).map(item => item.getAttribute('jid')); | ||
users_to_unblock.forEach(_converse.blocked.get('set').delete, _converse.blocked.get('set')); | ||
} else { | ||
log.error("Received blocklist push update but could not interpret it."); | ||
} | ||
// TODO: Fix this to not use the length as an update key, and | ||
// use a more accurate update method, like a length-extendable hash | ||
_converse.blocked.set({ 'len': _converse.blocked.get('set').size }); | ||
}, | ||
|
||
/** | ||
* Blocks JIDs by sending an IQ stanza | ||
* @method api.blockUser | ||
* | ||
* @param { Array } [jid_list] - The list of JIDs to block | ||
*/ | ||
async blockUser ( jid_list ) { | ||
if (!_converse.disco_entities.get(_converse.domain)?.features?.findWhere({'var': Strophe.NS.BLOCKING})) { | ||
return false; | ||
} | ||
if (!_converse.connection) { | ||
return false; | ||
} | ||
|
||
const block_items = jid_list.map(jid => Strophe.xmlElement('item', { 'jid': jid })); | ||
const block_element = Strophe.xmlElement('block', {'xmlns': Strophe.NS.BLOCKING }); | ||
|
||
block_items.forEach(block_element.appendChild, block_element); | ||
|
||
const iq = $iq({ | ||
'type': 'set', | ||
'id': u.getUniqueId('block') | ||
}).cnode(block_element); | ||
|
||
const result = await api.sendIQ(iq).catch(e => { log.fatal(e); return false }); | ||
const err_msg = `An error occured while trying to block user(s) ${jid_list}`; | ||
if (result === null) { | ||
api.alert('error', __('Error'), err_msg); | ||
log(err_msg, Strophe.LogLevel.WARN); | ||
return false; | ||
} else if (u.isErrorStanza(result)) { | ||
log.error(err_msg); | ||
log.error(result); | ||
return false; | ||
} | ||
return true; | ||
}, | ||
|
||
/** | ||
* Unblocks JIDs by sending an IQ stanza to the server JID specified | ||
* @method api.unblockUser | ||
* @param { Array } [jid_list] - The list of JIDs to unblock | ||
*/ | ||
async unblockUser ( jid_list ) { | ||
if (!_converse.disco_entities.get(_converse.domain)?.features?.findWhere({'var': Strophe.NS.BLOCKING})) { | ||
return false; | ||
} | ||
if (!_converse.connection) { | ||
return false; | ||
} | ||
|
||
const unblock_items = jid_list.map(jid => Strophe.xmlElement('item', { 'jid': jid })); | ||
const unblock_element = Strophe.xmlElement('unblock', {'xmlns': Strophe.NS.BLOCKING}); | ||
|
||
unblock_items.forEach(unblock_element.append, unblock_element); | ||
|
||
const iq = $iq({ | ||
'type': 'set', | ||
'id': u.getUniqueId('block') | ||
}).cnode(unblock_element); | ||
|
||
const result = await api.sendIQ(iq).catch(e => { log.fatal(e); return false }); | ||
const err_msg = `An error occured while trying to unblock user(s) ${jid_list}`; | ||
if (result === null) { | ||
api.alert('error', __('Error'), err_msg); | ||
log(err_msg, Strophe.LogLevel.WARN); | ||
return false; | ||
} else if (u.isErrorStanza(result)) { | ||
log.error(err_msg); | ||
log.error(result); | ||
return false; | ||
} | ||
return true; | ||
}, | ||
|
||
/** | ||
* Retrieved the blocked set | ||
* @method api.blockedUsers | ||
*/ | ||
blockedUsers () { | ||
return _converse.blocked.get('set'); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* @description | ||
* Converse.js plugin which adds support for XEP-0191: Blocking | ||
* Allows users to block other users, which hides their messages | ||
*/ | ||
import blocking_api from './api.js'; | ||
import { _converse, api, converse } from "@converse/headless/core.js"; | ||
import { onConnected } from './utils.js'; | ||
import { Model } from '@converse/skeletor/src/model.js'; | ||
|
||
const { Strophe } = converse.env; | ||
|
||
const SetModel = Model.extend({ | ||
defaults: { | ||
'set': new Set(), | ||
'len': 0, | ||
} | ||
}); | ||
|
||
Strophe.addNamespace('BLOCKING', "urn:xmpp:blocking"); | ||
|
||
converse.plugins.add('converse-blocking', { | ||
enabled (_converse) { | ||
return ( | ||
!_converse.api.settings.get('blacklisted_plugins').includes('converse-blocking') | ||
); | ||
}, | ||
|
||
|
||
dependencies: ["converse-disco"], | ||
|
||
initialize () { | ||
_converse.blocked = new SetModel(); | ||
Object.assign(api, blocking_api); | ||
|
||
api.listen.on('discoInitialized', onConnected); | ||
api.listen.on('reconnected', onConnected); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { _converse, api, converse } from "@converse/headless/core.js"; | ||
|
||
const { Strophe, $iq } = converse.env; | ||
|
||
export async function onConnected () { | ||
api.refreshBlocklist(); | ||
_converse.connection.addHandler(api.handleBlockingStanza, Strophe.NS.BLOCKING, 'iq', 'set', null, null); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Check notice
Code scanning / CodeQL
Unused variable, import, function or class