Web and mobile: - Follower/following lists (tap the counts), with Follow buttons and "Remove" on your own followers. - Profile ⋯ menu: block (with confirmation) / unblock, and report with a reason and optional note. "Follows you" label, "Follow back", and a banner on profiles you've blocked. - Blocked accounts list in Settings, with unblock. Web only: /admin for the admin account: stats, open/resolved reports, resolve, suspend/unsuspend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { Link } from 'expo-router';
|
||||
import { FlatList, StyleSheet, Text, View } from 'react-native';
|
||||
import useSWR from 'swr';
|
||||
import type { UserSummaryDTO } from '@musicshare/shared';
|
||||
import { Avatar } from '@/components/Avatar';
|
||||
import { Body, Button } from '@/components/ui';
|
||||
import { api } from '@/lib/api';
|
||||
import { showError } from '@/lib/errors';
|
||||
import { colors, space } from '@/lib/theme';
|
||||
|
||||
export default function BlockedScreen() {
|
||||
const { data: blocked = [], mutate, isLoading } = useSWR<UserSummaryDTO[]>('/me/blocks');
|
||||
const unblock = async (username: string) => {
|
||||
try {
|
||||
await api.unblock(username);
|
||||
await mutate();
|
||||
} catch (err) {
|
||||
showError(err);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<FlatList
|
||||
data={blocked}
|
||||
keyExtractor={(u) => u.id}
|
||||
contentContainerStyle={styles.list}
|
||||
ListEmptyComponent={isLoading ? null : <Body muted>You haven't blocked anyone. Block someone from the ⋯ menu on their profile.</Body>}
|
||||
renderItem={({ item: u }) => (
|
||||
<View style={styles.row}>
|
||||
<Link href={`/u/${u.username}`} style={{ flex: 1 }}>
|
||||
<View style={styles.person}>
|
||||
<Avatar user={u} size={40} />
|
||||
<Text style={styles.name} numberOfLines={1}>
|
||||
{u.displayName ?? u.username}
|
||||
</Text>
|
||||
</View>
|
||||
</Link>
|
||||
<Button small title="Unblock" onPress={() => unblock(u.username)} />
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
list: { padding: space.lg, gap: space.md },
|
||||
row: { flexDirection: 'row', alignItems: 'center', gap: space.md },
|
||||
person: { flexDirection: 'row', alignItems: 'center', gap: space.md },
|
||||
name: { color: colors.text, fontSize: 15, fontWeight: '600', flexShrink: 1 },
|
||||
});
|
||||
Reference in New Issue
Block a user