feat: update web client for unified API endpoints

- Use /state instead of /me for auth check
- Use /messages instead of /poll for message stream
- Use unified POST /messages with 'to' field for all sends
- Update part channel URL to DELETE /channels/{name}
This commit is contained in:
user
2026-02-10 10:20:09 -08:00
parent 74437b8372
commit aabf8e902c

View File

@@ -42,7 +42,7 @@ function LoginScreen({ onLogin }) {
// Check for saved token // Check for saved token
const saved = localStorage.getItem('chat_token'); const saved = localStorage.getItem('chat_token');
if (saved) { if (saved) {
api('/me').then(u => onLogin(u.nick, saved)).catch(() => localStorage.removeItem('chat_token')); api('/state').then(u => onLogin(u.nick, saved)).catch(() => localStorage.removeItem('chat_token'));
} }
inputRef.current?.focus(); inputRef.current?.focus();
}, []); }, []);
@@ -140,7 +140,7 @@ function App() {
let alive = true; let alive = true;
const poll = async () => { const poll = async () => {
try { try {
const msgs = await api(`/poll?after=${lastMsgId}`); const msgs = await api(`/messages?after=${lastMsgId}`);
if (!alive) return; if (!alive) return;
let maxId = lastMsgId; let maxId = lastMsgId;
for (const msg of msgs) { for (const msg of msgs) {
@@ -217,7 +217,7 @@ function App() {
const partChannel = async (name) => { const partChannel = async (name) => {
const chName = name.replace('#', ''); const chName = name.replace('#', '');
try { try {
await api(`/channels/${chName}/part`, { method: 'DELETE' }); await api(`/channels/${chName}`, { method: 'DELETE' });
} catch (err) { /* ignore */ } } catch (err) { /* ignore */ }
setTabs(prev => { setTabs(prev => {
const next = prev.filter(t => !(t.type === 'channel' && t.name === name)); const next = prev.filter(t => !(t.type === 'channel' && t.name === name));
@@ -267,7 +267,7 @@ function App() {
const target = parts[1]; const target = parts[1];
const msg = parts.slice(2).join(' '); const msg = parts.slice(2).join(' ');
try { try {
await api(`/dm/${target}/messages`, { method: 'POST', body: JSON.stringify({ content: msg }) }); await api('/messages', { method: 'POST', body: JSON.stringify({ to: target, content: msg }) });
openDM(target); openDM(target);
} catch (err) { } catch (err) {
addSystemMessage('server', `Failed to send DM: ${err.data?.error || 'error'}`); addSystemMessage('server', `Failed to send DM: ${err.data?.error || 'error'}`);
@@ -282,20 +282,12 @@ function App() {
return; return;
} }
if (tab.type === 'channel') { const to = tab.type === 'channel' ? tab.name : tab.name;
const chName = tab.name.replace('#', '');
try { try {
await api(`/channels/${chName}/messages`, { method: 'POST', body: JSON.stringify({ content: text }) }); await api('/messages', { method: 'POST', body: JSON.stringify({ to, content: text }) });
} catch (err) { } catch (err) {
addSystemMessage(tab.name, `Send failed: ${err.data?.error || 'error'}`); addSystemMessage(tab.name, `Send failed: ${err.data?.error || 'error'}`);
} }
} else if (tab.type === 'dm') {
try {
await api(`/dm/${tab.name}/messages`, { method: 'POST', body: JSON.stringify({ content: text }) });
} catch (err) {
addSystemMessage(tab.name, `Send failed: ${err.data?.error || 'error'}`);
}
}
}; };
if (!loggedIn) return <LoginScreen onLogin={onLogin} />; if (!loggedIn) return <LoginScreen onLogin={onLogin} />;