feat(platform): contributeGuildBoost for members + myBoostSlots view
Any guild member may contribute boosts via personal slots (not Manage Guild). Extract _gossipGuildBoostState for shared gossip after add/contribute. Expose myBoostSlots on view for server settings UI (used, remaining, canContribute). Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -31,7 +31,7 @@ const {
|
|||||||
PearcordAnnouncements,
|
PearcordAnnouncements,
|
||||||
formatCrosspostBody
|
formatCrosspostBody
|
||||||
} = require('pearcord-announcements')
|
} = require('pearcord-announcements')
|
||||||
const { PearcordBoosts } = require('pearcord-boosts')
|
const { PearcordBoosts, MAX_BOOSTS, MAX_SLOTS_PER_USER } = require('pearcord-boosts')
|
||||||
const { PearcordStickerRegistry } = require('pearcord-stickers')
|
const { PearcordStickerRegistry } = require('pearcord-stickers')
|
||||||
const {
|
const {
|
||||||
PearcordAnnouncementHub,
|
PearcordAnnouncementHub,
|
||||||
@@ -2689,18 +2689,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
return row
|
return row
|
||||||
}
|
}
|
||||||
|
|
||||||
async addGuildBoost (amount = 1) {
|
async _gossipGuildBoostState (row, attribution) {
|
||||||
if (!this.guild?.guild) throw new Error('no guild')
|
|
||||||
const roles = await this._memberRoles()
|
|
||||||
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) {
|
|
||||||
throw new Error('no permission to boost guild')
|
|
||||||
}
|
|
||||||
await this._ensureGuildModules()
|
|
||||||
const user = this.identity?.user
|
|
||||||
const attribution = user
|
|
||||||
? { userId: user.id, username: user.username, displayName: user.displayName }
|
|
||||||
: null
|
|
||||||
const row = await this.boosts.addBoost(this.guild.guild.id, amount, attribution)
|
|
||||||
this.guild.gossipGuildBoost({
|
this.guild.gossipGuildBoost({
|
||||||
guildId: row.guildId,
|
guildId: row.guildId,
|
||||||
boostCount: row.boostCount,
|
boostCount: row.boostCount,
|
||||||
@@ -2718,6 +2707,48 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
updatedAt: Date.now()
|
updatedAt: Date.now()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async contributeGuildBoost (amount = 1) {
|
||||||
|
if (!this.guild?.guild) throw new Error('no guild')
|
||||||
|
const user = this.identity?.user
|
||||||
|
if (!user) throw new Error('register first')
|
||||||
|
const roles = await this._memberRoles()
|
||||||
|
if (!roles) throw new Error('not a guild member')
|
||||||
|
await this._ensureGuildModules()
|
||||||
|
const attribution = {
|
||||||
|
userId: user.id,
|
||||||
|
username: user.username,
|
||||||
|
displayName: user.displayName
|
||||||
|
}
|
||||||
|
const row = await this.boosts.contributeBoost(
|
||||||
|
this.guild.guild.id,
|
||||||
|
attribution,
|
||||||
|
amount
|
||||||
|
)
|
||||||
|
this._gossipGuildBoostState(row, attribution)
|
||||||
|
await this._audit('guild.boost.contribute', {
|
||||||
|
guildId: row.guildId,
|
||||||
|
targetId: String(row.boostCount),
|
||||||
|
meta: { userId: attribution.userId, slots: (row.ledger || []).find((e) => e.userId === attribution.userId)?.slots }
|
||||||
|
})
|
||||||
|
this.emit('guild-boost', row)
|
||||||
|
return row
|
||||||
|
}
|
||||||
|
|
||||||
|
async addGuildBoost (amount = 1) {
|
||||||
|
if (!this.guild?.guild) throw new Error('no guild')
|
||||||
|
const roles = await this._memberRoles()
|
||||||
|
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) {
|
||||||
|
throw new Error('no permission to boost guild')
|
||||||
|
}
|
||||||
|
await this._ensureGuildModules()
|
||||||
|
const user = this.identity?.user
|
||||||
|
const attribution = user
|
||||||
|
? { userId: user.id, username: user.username, displayName: user.displayName }
|
||||||
|
: null
|
||||||
|
const row = await this.boosts.addBoost(this.guild.guild.id, amount, attribution)
|
||||||
|
this._gossipGuildBoostState(row, attribution)
|
||||||
await this._audit('guild.boost', {
|
await this._audit('guild.boost', {
|
||||||
guildId: row.guildId,
|
guildId: row.guildId,
|
||||||
targetId: String(row.boostCount),
|
targetId: String(row.boostCount),
|
||||||
@@ -3517,8 +3548,20 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
remoteAnnouncementHubSubs = await this.announcementHub.listSubscriptions(guild.id)
|
remoteAnnouncementHubSubs = await this.announcementHub.listSubscriptions(guild.id)
|
||||||
}
|
}
|
||||||
let guildBoost = null
|
let guildBoost = null
|
||||||
|
let myBoostSlots = null
|
||||||
if (guild && this.boosts) {
|
if (guild && this.boosts) {
|
||||||
guildBoost = await this.boosts.get(guild.id)
|
guildBoost = await this.boosts.get(guild.id)
|
||||||
|
if (user?.id) {
|
||||||
|
const used = await this.boosts.getUserSlots(guild.id, user.id)
|
||||||
|
const remaining = Math.max(0, MAX_SLOTS_PER_USER - used)
|
||||||
|
const guildFull = (guildBoost.boostCount || 0) >= MAX_BOOSTS
|
||||||
|
myBoostSlots = {
|
||||||
|
used,
|
||||||
|
max: MAX_SLOTS_PER_USER,
|
||||||
|
remaining,
|
||||||
|
canContribute: remaining > 0 && !guildFull
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
onboarded: this.onboarded,
|
onboarded: this.onboarded,
|
||||||
@@ -3569,6 +3612,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
announcementHubPublishers,
|
announcementHubPublishers,
|
||||||
remoteAnnouncementHubSubs,
|
remoteAnnouncementHubSubs,
|
||||||
guildBoost,
|
guildBoost,
|
||||||
|
myBoostSlots,
|
||||||
myVoiceChannelId,
|
myVoiceChannelId,
|
||||||
voiceMedia: this.voiceMedia?.snapshot() || null,
|
voiceMedia: this.voiceMedia?.snapshot() || null,
|
||||||
screenShare: this.screenShare?.snapshot() || null,
|
screenShare: this.screenShare?.snapshot() || null,
|
||||||
|
|||||||
Reference in New Issue
Block a user