v06.8 various bug fixes

This commit is contained in:
2026-03-10 21:30:36 -04:00
parent 9da2f64f5e
commit 8fc7a01778
8 changed files with 53 additions and 30 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "jama-frontend",
"version": "0.6.7",
"version": "0.6.8",
"private": true,
"scripts": {
"dev": "vite",

View File

@@ -9,6 +9,7 @@ export default function ProfileModal({ onClose }) {
const toast = useToast();
const [displayName, setDisplayName] = useState(user?.display_name || '');
const [savedDisplayName, setSavedDisplayName] = useState(user?.display_name || '');
const [displayNameWarning, setDisplayNameWarning] = useState('');
const [aboutMe, setAboutMe] = useState(user?.about_me || '');
const [currentPw, setCurrentPw] = useState('');
@@ -24,6 +25,7 @@ export default function ProfileModal({ onClose }) {
try {
const { user: updated } = await api.updateProfile({ displayName, aboutMe, hideAdminTag });
updateUser(updated);
setSavedDisplayName(displayName);
toast('Profile updated', 'success');
} catch (e) {
toast(e.message, 'error');
@@ -100,24 +102,37 @@ export default function ProfileModal({ onClose }) {
<div className="flex-col gap-3">
<div className="flex-col gap-1">
<label className="text-sm font-medium" style={{ color: 'var(--text-secondary)' }}>Display Name</label>
<input
className="input"
value={displayName}
onChange={async e => {
const val = e.target.value;
setDisplayName(val);
setDisplayNameWarning('');
if (val && val !== user?.display_name) {
try {
const { taken } = await api.checkDisplayName(val);
if (taken) setDisplayNameWarning('Display name is already in use');
} catch {}
}
}}
placeholder={user?.name}
style={{ borderColor: displayNameWarning ? '#e53935' : undefined }}
/>
<div className="flex gap-2">
<input
className="input flex-1"
value={displayName}
onChange={async e => {
const val = e.target.value;
setDisplayName(val);
setDisplayNameWarning('');
if (val && val !== user?.display_name) {
try {
const { taken } = await api.checkDisplayName(val);
if (taken) setDisplayNameWarning('Display name is already in use');
} catch {}
}
}}
placeholder={user?.name}
style={{ borderColor: displayNameWarning ? '#e53935' : undefined }}
/>
{displayName !== savedDisplayName ? null : savedDisplayName ? (
<button
className="btn btn-sm"
style={{ background: 'var(--surface-variant)', color: 'var(--text-secondary)', flexShrink: 0 }}
onClick={() => setDisplayName('')}
type="button"
>
Remove
</button>
) : null}
</div>
{displayNameWarning && <span className="text-xs" style={{ color: '#e53935' }}>{displayNameWarning}</span>}
{savedDisplayName && <span className="text-xs" style={{ color: 'var(--text-tertiary)' }}>Username: {user?.name}</span>}
</div>
<div className="flex-col gap-1">
<label className="text-sm font-medium" style={{ color: 'var(--text-secondary)' }}>About Me</label>

View File

@@ -214,7 +214,7 @@ a { color: inherit; text-decoration: none; }
--border: #2e2e45;
--text-primary: #e2e2f0;
--text-secondary: #9898b8;
--text-tertiary: #6060808;
--text-tertiary: #606080;
--bubble-out: #4d8fd4;
--bubble-in: #252535;
}

View File

@@ -121,11 +121,18 @@ export default function Chat() {
// Update group preview text
setGroups(prev => {
const updateGroup = (g) => g.id === msg.group_id
? { ...g, last_message: msg.content || (msg.image_url ? '📷 Image' : ''), last_message_at: msg.created_at }
? { ...g, last_message: msg.content || (msg.image_url ? '📷 Image' : ''), last_message_at: msg.created_at, last_message_user_id: msg.user_id }
: g;
const updatedPrivate = prev.privateGroups.map(updateGroup)
.sort((a, b) => {
if (!a.last_message_at && !b.last_message_at) return 0;
if (!a.last_message_at) return 1;
if (!b.last_message_at) return -1;
return new Date(b.last_message_at) - new Date(a.last_message_at);
});
return {
publicGroups: prev.publicGroups.map(updateGroup),
privateGroups: prev.privateGroups.map(updateGroup),
privateGroups: updatedPrivate,
};
});
// Don't badge own messages