fix: DM message ordering, consolidate input toolbar, add rich text/WYSIWYG, file upload with drag-drop

- Fix DM backend ListMessages to use DESC + reverse (match channel handler)
- Remove spurious .reverse() from frontend message/conversation stores
- Create shared MessageInput component with Slack-style single toolbar row
- Add file upload via + button with progress bar and drag-and-drop
- Add markdown/rich text toggle with full WYSIWYG block formatting
  (lists, blockquotes, links, headings, code blocks)
- Add frontend+backend security for file uploads (extension + content-type guards)
This commit is contained in:
2026-07-06 17:33:20 +00:00
parent 9512dedec1
commit b3b5ff495d
19 changed files with 1369 additions and 301 deletions
+9
View File
@@ -12,6 +12,7 @@ import { DMChat } from './components/DMChat.tsx';
import { ForgotPasswordPage } from './components/ForgotPasswordPage.tsx';
import { ResetPasswordPage } from './components/ResetPasswordPage.tsx';
import { useAuthStore } from './stores/auth.ts';
import { useWebSocketStore } from './stores/ws.ts';
import { InstallBanner } from './components/InstallBanner.tsx';
import { ConnectionStatus } from './components/ConnectionStatus.tsx';
@@ -22,12 +23,20 @@ function ProtectedRoute({ children }: { children: React.ReactNode }) {
function App() {
const fetchMe = useAuthStore((state) => state.fetchMe);
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
const [init, setInit] = useState(false);
useEffect(() => {
fetchMe().finally(() => setInit(true));
}, [fetchMe]);
// Connect WebSocket for real-time messages once authenticated
useEffect(() => {
if (isAuthenticated) {
useWebSocketStore.getState().connect();
}
}, [isAuthenticated]);
if (!init) {
return <div className="h-screen w-screen bg-gb-bg flex items-center justify-center text-gb-fg-s font-mono text-xs">Loading...</div>;
}