chore(git): merge pull request #197 from extra/154-blocked-warning into staging
All checks were successful
Release to Staging / build_and_release (push) Successful in 1m4s

Reviewed-on: #197
This commit is contained in:
enes 2025-01-16 12:07:46 +00:00
commit e85b33d95d
8 changed files with 77 additions and 9 deletions

View File

@ -0,0 +1,22 @@
interface PostWarningsProps {
type: 'user' | 'admin'
}
export const PostWarnings = ({ type }: PostWarningsProps) => (
<div className='IBMSMSMBSSWarning'>
<p>
{type === 'admin' ? (
<>
Warning: This post has been blocked/hidden by the site for one of the
following reasons:
<br />
Malware, Not a Mod, Illegal, Spam, Verified Report of Unauthorized
Repost.
<br />
</>
) : (
<>Notice: You have blocked this post</>
)}
</p>
</div>
)

View File

@ -3,7 +3,7 @@ import {
launch as launchNostrLoginDialog launch as launchNostrLoginDialog
} from 'nostr-login' } from 'nostr-login'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom' import { Link, useRevalidator } from 'react-router-dom'
import { Banner } from '../components/Banner' import { Banner } from '../components/Banner'
import { ZapPopUp } from '../components/Zap' import { ZapPopUp } from '../components/Zap'
import { import {
@ -27,7 +27,7 @@ export const Header = () => {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const { findMetadata } = useNDKContext() const { findMetadata } = useNDKContext()
const userState = useAppSelector((state) => state.user) const userState = useAppSelector((state) => state.user)
const revalidator = useRevalidator()
// Track nostr-login extension modal open state // Track nostr-login extension modal open state
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
const handleOpen = () => setIsOpen(true) const handleOpen = () => setIsOpen(true)
@ -75,8 +75,12 @@ export const Header = () => {
} }
}) })
} }
// React router - revalidate loader states on auth changes
revalidator.revalidate()
} }
}) })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dispatch, findMetadata]) }, [dispatch, findMetadata])
const handleLogin = () => { const handleLogin = () => {
@ -447,7 +451,9 @@ const RegisterButtonWithDialog = () => {
color: '#ffffffbf' color: '#ffffffbf'
}} }}
> >
Warning:&nbsp;Make sure you backup your private key somewhere safe. If you lose it or it gets leaked, we actually can't help you. Warning:&nbsp;Make sure you backup your private key
somewhere safe. If you lose it or it gets leaked, we
actually can't help you.
</p> </p>
<p <p
className='labelDescriptionMain' className='labelDescriptionMain'

View File

@ -18,6 +18,7 @@ import { toast } from 'react-toastify'
import { useAppSelector, useBodyScrollDisable } from 'hooks' import { useAppSelector, useBodyScrollDisable } from 'hooks'
import { ReportPopup } from 'components/ReportPopup' import { ReportPopup } from 'components/ReportPopup'
import { Viewer } from 'components/Markdown/Viewer' import { Viewer } from 'components/Markdown/Viewer'
import { PostWarnings } from 'components/PostWarning'
const BLOG_REPORT_REASONS = [ const BLOG_REPORT_REASONS = [
{ label: 'Actually CP', key: 'actuallyCP' }, { label: 'Actually CP', key: 'actuallyCP' },
@ -29,7 +30,7 @@ const BLOG_REPORT_REASONS = [
] ]
export const BlogPage = () => { export const BlogPage = () => {
const { blog, latest, isAddedToNSFW, isBlocked } = const { blog, latest, isAddedToNSFW, isBlocked, postWarning } =
useLoaderData() as BlogPageLoaderResult useLoaderData() as BlogPageLoaderResult
const userState = useAppSelector((state) => state.user) const userState = useAppSelector((state) => state.user)
const isAdmin = const isAdmin =
@ -84,6 +85,7 @@ export const BlogPage = () => {
<> <>
<div className='IBMSMSplitMainBigSide'> <div className='IBMSMSplitMainBigSide'>
<div className='IBMSMSplitMainBigSideSec'> <div className='IBMSMSplitMainBigSideSec'>
{postWarning && <PostWarnings type={postWarning} />}
<div className='IBMSMSMBSSPost'> <div className='IBMSMSMBSSPost'>
<div <div
className='dropdown dropdownMain dropdownMainBlogpost' className='dropdown dropdownMain dropdownMainBlogpost'

View File

@ -44,6 +44,7 @@ export const blogRouteLoader =
const userState = store.getState().user const userState = store.getState().user
const loggedInUserPubkey = const loggedInUserPubkey =
(userState?.user?.pubkey as string | undefined) || getFallbackPubkey() (userState?.user?.pubkey as string | undefined) || getFallbackPubkey()
const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
// Check if editing and the user is the original author // Check if editing and the user is the original author
// Redirect if NOT // Redirect if NOT
@ -138,10 +139,28 @@ export const blogRouteLoader =
if (muteLists.status === 'fulfilled' && muteLists.value) { if (muteLists.status === 'fulfilled' && muteLists.value) {
if (muteLists && muteLists.value) { if (muteLists && muteLists.value) {
if (result.blog && result.blog.aTag) { if (result.blog && result.blog.aTag) {
// Show user or admin post warning if any mute list includes either post or author
if (
muteLists.value.user.replaceableEvents.includes(
result.blog.aTag
) ||
(result.blog.author &&
muteLists.value.user.authors.includes(result.blog.author))
) {
result.postWarning = 'user'
}
if ( if (
muteLists.value.admin.replaceableEvents.includes( muteLists.value.admin.replaceableEvents.includes(
result.blog.aTag result.blog.aTag
) || ) ||
(result.blog.author &&
muteLists.value.admin.authors.includes(result.blog.author))
) {
result.postWarning = 'admin'
}
if (
muteLists.value.user.replaceableEvents.includes(result.blog.aTag) muteLists.value.user.replaceableEvents.includes(result.blog.aTag)
) { ) {
result.isBlocked = true result.isBlocked = true
@ -149,8 +168,6 @@ export const blogRouteLoader =
} }
// Moderate the latest // Moderate the latest
const isAdmin =
userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
const isOwner = const isOwner =
userState.user?.pubkey && userState.user.pubkey === pubkey userState.user?.pubkey && userState.user.pubkey === pubkey
const isUnmoderatedFully = const isUnmoderatedFully =

View File

@ -38,6 +38,7 @@ import { Spinner } from 'components/Spinner'
import { RouterLoadingSpinner } from 'components/LoadingSpinner' import { RouterLoadingSpinner } from 'components/LoadingSpinner'
import { OriginalAuthor } from 'components/OriginalAuthor' import { OriginalAuthor } from 'components/OriginalAuthor'
import { Viewer } from 'components/Markdown/Viewer' import { Viewer } from 'components/Markdown/Viewer'
import { PostWarnings } from 'components/PostWarning'
const MOD_REPORT_REASONS = [ const MOD_REPORT_REASONS = [
{ label: 'Actually CP', key: 'actuallyCP' }, { label: 'Actually CP', key: 'actuallyCP' },
@ -51,7 +52,7 @@ const MOD_REPORT_REASONS = [
] ]
export const ModPage = () => { export const ModPage = () => {
const { mod } = useLoaderData() as ModPageLoaderResult const { mod, postWarning } = useLoaderData() as ModPageLoaderResult
// We can get author right away from naddr, no need to wait for mod data // We can get author right away from naddr, no need to wait for mod data
const { naddr } = useParams() const { naddr } = useParams()
@ -98,6 +99,7 @@ export const ModPage = () => {
<> <>
<div className='IBMSMSplitMainBigSideSec'> <div className='IBMSMSplitMainBigSideSec'>
<Game /> <Game />
{postWarning && <PostWarnings type={postWarning} />}
<Body <Body
featuredImageUrl={mod.featuredImageUrl} featuredImageUrl={mod.featuredImageUrl}
title={mod.title} title={mod.title}
@ -125,6 +127,7 @@ export const ModPage = () => {
<h4 className='IBMSMSMBSSDownloadsTitle'> <h4 className='IBMSMSMBSSDownloadsTitle'>
Mod Download Mod Download
</h4> </h4>
{postWarning && <PostWarnings type={postWarning} />}
{mod.downloadUrls.length > 0 && ( {mod.downloadUrls.length > 0 && (
<div className='IBMSMSMBSSDownloadsPrime'> <div className='IBMSMSMBSSDownloadsPrime'>
<Download {...mod.downloadUrls[0]} /> <Download {...mod.downloadUrls[0]} />

View File

@ -50,6 +50,7 @@ export const modRouteLoader =
const userState = store.getState().user const userState = store.getState().user
const loggedInUserPubkey = const loggedInUserPubkey =
(userState?.user?.pubkey as string | undefined) || getFallbackPubkey() (userState?.user?.pubkey as string | undefined) || getFallbackPubkey()
const isAdmin = userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
// Check if editing and the user is the original author // Check if editing and the user is the original author
// Redirect if NOT // Redirect if NOT
@ -146,10 +147,27 @@ export const modRouteLoader =
if (muteLists.status === 'fulfilled' && muteLists.value) { if (muteLists.status === 'fulfilled' && muteLists.value) {
if (muteLists && muteLists.value) { if (muteLists && muteLists.value) {
if (result.mod && result.mod.aTag) { if (result.mod && result.mod.aTag) {
// Show user or admin post warning if any mute list includes either post or author
if (
muteLists.value.user.replaceableEvents.includes(
result.mod.aTag
) ||
muteLists.value.user.authors.includes(result.mod.author)
) {
result.postWarning = 'user'
}
if ( if (
muteLists.value.admin.replaceableEvents.includes( muteLists.value.admin.replaceableEvents.includes(
result.mod.aTag result.mod.aTag
) || ) ||
muteLists.value.admin.authors.includes(result.mod.author)
) {
result.postWarning = 'admin'
}
// Check if user has blocked this profile
if (
muteLists.value.user.replaceableEvents.includes(result.mod.aTag) muteLists.value.user.replaceableEvents.includes(result.mod.aTag)
) { ) {
result.isBlocked = true result.isBlocked = true
@ -157,8 +175,6 @@ export const modRouteLoader =
} }
// Moderate the latest // Moderate the latest
const isAdmin =
userState.user?.npub === import.meta.env.VITE_REPORTING_NPUB
const isOwner = const isOwner =
userState.user?.pubkey && userState.user.pubkey === pubkey userState.user?.pubkey && userState.user.pubkey === pubkey
const isUnmoderatedFully = const isUnmoderatedFully =

View File

@ -39,6 +39,7 @@ export interface BlogPageLoaderResult {
latest: Partial<BlogDetails>[] latest: Partial<BlogDetails>[]
isAddedToNSFW: boolean isAddedToNSFW: boolean
isBlocked: boolean isBlocked: boolean
postWarning?: 'user' | 'admin'
} }
export interface BlogsFilterOptions { export interface BlogsFilterOptions {

View File

@ -66,6 +66,7 @@ export interface ModPageLoaderResult {
isAddedToNSFW: boolean isAddedToNSFW: boolean
isBlocked: boolean isBlocked: boolean
isRepost: boolean isRepost: boolean
postWarning?: 'user' | 'admin'
} }
export type SubmitModActionResult = export type SubmitModActionResult =