From d44d361514cfa50f35c57d22657e4990dad554f8 Mon Sep 17 00:00:00 2001
From: Rishi B
Date: Tue, 13 Jan 2026 17:00:37 -0500
Subject: [PATCH 1/2] use NEXT_PUBLIC_SAFE_SKIES_API
---
lib/api/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/api/index.ts b/lib/api/index.ts
index 60641f8..0c2da99 100644
--- a/lib/api/index.ts
+++ b/lib/api/index.ts
@@ -16,7 +16,7 @@ export async function fetchWithAuth(url: string, options: RequestInit = {}) {
Authorization: `Bearer ${token}`,
};
const response = await fetch(
- `${process.env.SAFE_SKIES_API}${url}`,
+ `${process.env.NEXT_PUBLIC_SAFE_SKIES_API}${url}`,
{ ...options, headers }
);
From 0125174048ec244400a23a52a19902dc68fa3713 Mon Sep 17 00:00:00 2001
From: Rishi B
Date: Tue, 13 Jan 2026 17:54:46 -0500
Subject: [PATCH 2/2] small UX changes
---
components/modals/user-moderation-modal.tsx | 99 ++++++++++++++++++++-
lib/constants/moderation.ts | 2 +
lib/types/moderation.ts | 2 +
3 files changed, 99 insertions(+), 4 deletions(-)
diff --git a/components/modals/user-moderation-modal.tsx b/components/modals/user-moderation-modal.tsx
index 827f3b1..a7008ee 100644
--- a/components/modals/user-moderation-modal.tsx
+++ b/components/modals/user-moderation-modal.tsx
@@ -10,6 +10,7 @@ import { ProfileViewBasic } from '@atproto/api/dist/client/types/app/bsky/actor/
import { checkUserBanStatus, banUser, unbanUser, BannedFromTV, checkUserMuteStatus, muteUser, unmuteUser, fetchProfileModerationData, emitModerationEvent } from '@/repos/moderation';
import { ToastContext } from '@/contexts/toast-context';
import { ProfileModerationResponse, ModerationEventType, EscalatedItem, EscalatedPostItem } from '@/lib/types/moderation';
+import { BLACKSKY_PDS_URL } from '@/lib/constants/moderation';
import { getPostUrl } from '@/components/post/utils';
type UserLike = {
@@ -410,6 +411,70 @@ export const UserModerationModal = ({
}
};
+ // Check if user is on blacksky.app PDS (required for takedown actions)
+ const isBlackskyUser = moderationData?.pdsEndpoint === BLACKSKY_PDS_URL;
+
+ // Quick action handlers
+ const handleQuickAcknowledge = async () => {
+ setOzoneAction(prev => ({ ...prev, type: 'acknowledge', loading: true }));
+
+ try {
+ const isEscalatedPost = 'type' in user && user.type === 'post';
+ const subjectUri = isEscalatedPost ? (user as EscalatedPostItem).postUri : undefined;
+ const subjectCid = isEscalatedPost ? (user as EscalatedPostItem).postCid : undefined;
+
+ const result = await emitModerationEvent(user.did, 'acknowledge', {}, subjectUri, subjectCid);
+
+ toastContext?.toast({
+ title: 'Success',
+ message: result.message || 'Successfully acknowledged',
+ intent: VisualIntent.Success,
+ });
+
+ resetOzoneAction();
+ await refreshModerationData();
+ } catch (error) {
+ console.error('Failed to acknowledge:', error);
+ toastContext?.toast({
+ title: 'Error',
+ message: error instanceof Error ? error.message : 'Failed to acknowledge',
+ intent: VisualIntent.Error,
+ });
+ } finally {
+ setOzoneAction(prev => ({ ...prev, loading: false }));
+ }
+ };
+
+ const handleQuickTakedown = async () => {
+ setOzoneAction(prev => ({ ...prev, type: 'takedown', loading: true }));
+
+ try {
+ const isEscalatedPost = 'type' in user && user.type === 'post';
+ const subjectUri = isEscalatedPost ? (user as EscalatedPostItem).postUri : undefined;
+ const subjectCid = isEscalatedPost ? (user as EscalatedPostItem).postCid : undefined;
+
+ const result = await emitModerationEvent(user.did, 'takedown', {}, subjectUri, subjectCid);
+
+ toastContext?.toast({
+ title: 'Success',
+ message: result.message || 'Successfully taken down',
+ intent: VisualIntent.Success,
+ });
+
+ resetOzoneAction();
+ await refreshModerationData();
+ } catch (error) {
+ console.error('Failed to takedown:', error);
+ toastContext?.toast({
+ title: 'Error',
+ message: error instanceof Error ? error.message : 'Failed to takedown',
+ intent: VisualIntent.Error,
+ });
+ } finally {
+ setOzoneAction(prev => ({ ...prev, loading: false }));
+ }
+ };
+
return (
{user.did}
+ {moderationData?.pdsEndpoint && (
+
+ {moderationData.pdsEndpoint}
+
+ )}
{'type' in user && user.type === 'post' && 'postUri' in user && (
- {muteStatus.isMuted ? 'Greenlist Unmute' : 'Greenlist Mute'}
+ {muteStatus.isMuted ? 'Ungreenlist' : 'Greenlist'}
@@ -576,7 +646,24 @@ export const UserModerationModal = ({
{/* Ozone Actions Section */}
Ozone Actions
-
+
+
+
+
diff --git a/lib/constants/moderation.ts b/lib/constants/moderation.ts
index 0a3d1f1..a26f6ee 100644
--- a/lib/constants/moderation.ts
+++ b/lib/constants/moderation.ts
@@ -6,3 +6,5 @@ export const ADMIN_ACTIONS: Partial[] = [
'user_unban',
'user_ban',
];
+
+export const BLACKSKY_PDS_URL = 'https://blacksky.app';
diff --git a/lib/types/moderation.ts b/lib/types/moderation.ts
index 41e6596..5dd6221 100644
--- a/lib/types/moderation.ts
+++ b/lib/types/moderation.ts
@@ -78,6 +78,8 @@ export interface ProfileModerationResponse {
displayName?: string;
avatar?: string;
};
+ pdsEndpoint?: string;
+ pdsError?: string;
error?: string;
}