v0.12.41 New settings options for messages
This commit is contained in:
@@ -4,10 +4,17 @@ import { api } from '../utils/api.js';
|
||||
import { useToast } from '../contexts/ToastContext.jsx';
|
||||
import Avatar from './Avatar.jsx';
|
||||
|
||||
export default function NewChatModal({ onClose, onCreated }) {
|
||||
export default function NewChatModal({ onClose, onCreated, features = {} }) {
|
||||
const { user } = useAuth();
|
||||
const toast = useToast();
|
||||
const [tab, setTab] = useState('private'); // 'private' | 'public'
|
||||
|
||||
const msgPublic = features.msgPublic ?? true;
|
||||
const msgU2U = features.msgU2U ?? true;
|
||||
const msgPrivateGroup = features.msgPrivateGroup ?? true;
|
||||
|
||||
// Default to private if available, otherwise public
|
||||
const defaultTab = (msgU2U || msgPrivateGroup) ? 'private' : 'public';
|
||||
const [tab, setTab] = useState(defaultTab);
|
||||
const [name, setName] = useState('');
|
||||
const [isReadonly, setIsReadonly] = useState(false);
|
||||
const [search, setSearch] = useState('');
|
||||
@@ -15,8 +22,8 @@ export default function NewChatModal({ onClose, onCreated }) {
|
||||
const [selected, setSelected] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// True when exactly 1 user selected on private tab = direct message
|
||||
const isDirect = tab === 'private' && selected.length === 1;
|
||||
// True when exactly 1 user selected on private tab AND U2U messages are enabled
|
||||
const isDirect = tab === 'private' && selected.length === 1 && msgU2U;
|
||||
|
||||
useEffect(() => {
|
||||
api.searchUsers('').then(({ users }) => setUsers(users)).catch(() => {});
|
||||
@@ -30,12 +37,17 @@ export default function NewChatModal({ onClose, onCreated }) {
|
||||
|
||||
const toggle = (u) => {
|
||||
if (u.id === user.id) return;
|
||||
setSelected(prev => prev.find(p => p.id === u.id) ? prev.filter(p => p.id !== u.id) : [...prev, u]);
|
||||
// If private groups are disabled, cap selection at 1 (DM only)
|
||||
setSelected(prev => {
|
||||
if (prev.find(p => p.id === u.id)) return prev.filter(p => p.id !== u.id);
|
||||
if (!msgPrivateGroup && prev.length >= 1) return prev; // can't add more for DM-only
|
||||
return [...prev, u];
|
||||
});
|
||||
};
|
||||
|
||||
const handleCreate = async () => {
|
||||
if (tab === 'private' && selected.length === 0) return toast('Add at least one member', 'error');
|
||||
if (tab === 'private' && selected.length > 1 && !name.trim()) return toast('Name required', 'error');
|
||||
if (tab === 'private' && !isDirect && !name.trim()) return toast('Name required', 'error');
|
||||
if (tab === 'public' && !name.trim()) return toast('Name required', 'error');
|
||||
|
||||
setLoading(true);
|
||||
@@ -86,15 +98,15 @@ export default function NewChatModal({ onClose, onCreated }) {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{user.role === 'admin' && (
|
||||
{user.role === 'admin' && (msgU2U || msgPrivateGroup || msgPublic) && (
|
||||
<div className="flex gap-2" style={{ marginBottom: 20 }}>
|
||||
<button className={`btn ${tab === 'private' ? 'btn-primary' : 'btn-secondary'} btn-sm`} onClick={() => setTab('private')}>Direct Message</button>
|
||||
<button className={`btn ${tab === 'public' ? 'btn-primary' : 'btn-secondary'} btn-sm`} onClick={() => setTab('public')}>Public Message</button>
|
||||
{(msgU2U || msgPrivateGroup) && <button className={`btn ${tab === 'private' ? 'btn-primary' : 'btn-secondary'} btn-sm`} onClick={() => setTab('private')}>Direct Message</button>}
|
||||
{msgPublic && <button className={`btn ${tab === 'public' ? 'btn-primary' : 'btn-secondary'} btn-sm`} onClick={() => setTab('public')}>Public Message</button>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Message Name — only shown when needed: public always, private only when 2+ members selected */}
|
||||
{(tab === 'public' || (tab === 'private' && selected.length > 1)) && (
|
||||
{/* Message Name — public always, private when not a DM and at least 1 member selected */}
|
||||
{(tab === 'public' || (tab === 'private' && !isDirect && selected.length > 0)) && (
|
||||
<div className="flex-col gap-2" style={{ marginBottom: 16 }}>
|
||||
<label className="text-sm font-medium" style={{ color: 'var(--text-secondary)' }}>Message Name</label>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user