all filters fully functional. reporting system added. multiple fixes. #27
@ -131,24 +131,21 @@ export class MetadataController {
|
||||
return ndkRelayList[userRelaysType]
|
||||
}
|
||||
|
||||
public getMuteLists = async (pubkey?: string): Promise<MuteLists> => {
|
||||
// Create sets to collect all unique muted authors and replaceable event Identifiers
|
||||
const mutedAuthors = new Set<string>()
|
||||
const mutedEvents = new Set<string>()
|
||||
public getMuteLists = async (
|
||||
pubkey?: string
|
||||
): Promise<{
|
||||
admin: MuteLists
|
||||
user: MuteLists
|
||||
}> => {
|
||||
const adminMutedAuthors = new Set<string>()
|
||||
const adminMutedPosts = new Set<string>()
|
||||
|
||||
// construct an array of npubs with dedicated reporting npub and provided pubkey
|
||||
const npubs = [this.reportingNpub]
|
||||
|
||||
if (pubkey) npubs.push(pubkey)
|
||||
|
||||
// Create an array of promises to fetch mute lists for each npub
|
||||
const promises = npubs.map(async (npub) => {
|
||||
const hexKey = npubToHex(npub)
|
||||
if (!hexKey) return
|
||||
const adminHexKey = npubToHex(this.reportingNpub)
|
||||
|
||||
if (adminHexKey) {
|
||||
const muteListEvent = await this.ndk.fetchEvent({
|
||||
kinds: [kinds.Mutelist],
|
||||
authors: [hexKey]
|
||||
authors: [adminHexKey]
|
||||
})
|
||||
|
||||
if (muteListEvent) {
|
||||
@ -156,19 +153,49 @@ export class MetadataController {
|
||||
|
||||
list.items.forEach((item) => {
|
||||
if (item[0] === 'p') {
|
||||
mutedAuthors.add(item[1])
|
||||
adminMutedAuthors.add(item[1])
|
||||
} else if (item[0] === 'a') {
|
||||
mutedEvents.add(item[1])
|
||||
adminMutedPosts.add(item[1])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const userMutedAuthors = new Set<string>()
|
||||
const userMutedPosts = new Set<string>()
|
||||
|
||||
if (pubkey) {
|
||||
const userHexKey = npubToHex(pubkey)
|
||||
|
||||
if (userHexKey) {
|
||||
const muteListEvent = await this.ndk.fetchEvent({
|
||||
kinds: [kinds.Mutelist],
|
||||
authors: [userHexKey]
|
||||
})
|
||||
|
||||
await Promise.allSettled(promises)
|
||||
if (muteListEvent) {
|
||||
const list = NDKList.from(muteListEvent)
|
||||
|
||||
list.items.forEach((item) => {
|
||||
if (item[0] === 'p') {
|
||||
userMutedAuthors.add(item[1])
|
||||
} else if (item[0] === 'a') {
|
||||
userMutedPosts.add(item[1])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
authors: Array.from(mutedAuthors),
|
||||
replaceableEvents: Array.from(mutedEvents)
|
||||
admin: {
|
||||
authors: Array.from(adminMutedAuthors),
|
||||
replaceableEvents: Array.from(adminMutedPosts)
|
||||
},
|
||||
user: {
|
||||
authors: Array.from(userMutedAuthors),
|
||||
replaceableEvents: Array.from(userMutedPosts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,8 @@ enum NSFWFilter {
|
||||
|
||||
enum ModeratedFilter {
|
||||
Moderated = 'Moderated',
|
||||
Unmoderated = 'Unmoderated'
|
||||
Unmoderated = 'Unmoderated',
|
||||
Unmoderated_Fully = 'Unmoderated Fully'
|
||||
}
|
||||
|
||||
interface FilterOptions {
|
||||
@ -56,9 +57,18 @@ export const ModsPage = () => {
|
||||
source: window.location.host,
|
||||
moderated: ModeratedFilter.Moderated
|
||||
})
|
||||
const [muteLists, setMuteLists] = useState<MuteLists>({
|
||||
const [muteLists, setMuteLists] = useState<{
|
||||
admin: MuteLists
|
||||
user: MuteLists
|
||||
}>({
|
||||
admin: {
|
||||
authors: [],
|
||||
replaceableEvents: []
|
||||
},
|
||||
user: {
|
||||
authors: [],
|
||||
replaceableEvents: []
|
||||
}
|
||||
})
|
||||
const [nsfwList, setNSFWList] = useState<string[]>([])
|
||||
|
||||
@ -139,11 +149,24 @@ export const ModsPage = () => {
|
||||
|
||||
let filtered = nsfwFilter(mods)
|
||||
|
||||
const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
|
||||
const isUnmoderatedFully =
|
||||
filterOptions.moderated === ModeratedFilter.Unmoderated_Fully
|
||||
|
||||
// Only apply filtering if the user is not an admin or the admin has not selected "Unmoderated Fully"
|
||||
if (!(isAdmin && isUnmoderatedFully)) {
|
||||
filtered = filtered.filter(
|
||||
(mod) =>
|
||||
!muteLists.admin.authors.includes(mod.author) &&
|
||||
!muteLists.admin.replaceableEvents.includes(mod.aTag)
|
||||
)
|
||||
}
|
||||
|
||||
if (filterOptions.moderated === ModeratedFilter.Moderated) {
|
||||
filtered = filtered.filter(
|
||||
(mod) =>
|
||||
!muteLists.authors.includes(mod.author) &&
|
||||
!muteLists.replaceableEvents.includes(mod.aTag)
|
||||
!muteLists.user.authors.includes(mod.author) &&
|
||||
!muteLists.user.replaceableEvents.includes(mod.aTag)
|
||||
)
|
||||
}
|
||||
|
||||
@ -155,6 +178,7 @@ export const ModsPage = () => {
|
||||
|
||||
return filtered
|
||||
}, [
|
||||
userState.user?.npub,
|
||||
filterOptions.sort,
|
||||
filterOptions.moderated,
|
||||
filterOptions.nsfw,
|
||||
@ -250,6 +274,8 @@ type FiltersProps = {
|
||||
|
||||
const Filters = React.memo(
|
||||
({ filterOptions, setFilterOptions }: FiltersProps) => {
|
||||
const userState = useAppSelector((state) => state.user)
|
||||
|
||||
return (
|
||||
<div className='IBMSecMain'>
|
||||
<div className='FiltersMain'>
|
||||
@ -293,7 +319,16 @@ const Filters = React.memo(
|
||||
{filterOptions.moderated}
|
||||
</button>
|
||||
<div className='dropdown-menu dropdownMainMenu'>
|
||||
{Object.values(ModeratedFilter).map((item, index) => (
|
||||
{Object.values(ModeratedFilter).map((item, index) => {
|
||||
if (item === ModeratedFilter.Unmoderated_Fully) {
|
||||
const isAdmin =
|
||||
userState.user?.npub ===
|
||||
import.meta.env.VITE_REPORTING_NPUB
|
||||
|
||||
if (!isAdmin) return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
key={`moderatedFilterItem-${index}`}
|
||||
className='dropdown-item dropdownMainMenuItem'
|
||||
@ -306,7 +341,8 @@ const Filters = React.memo(
|
||||
>
|
||||
{item}
|
||||
</div>
|
||||
))}
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user