23 Commits

Author SHA1 Message Date
Ai
b095d20852 feat: passwordless SMS-only auth (login + registration)
- Single unified flow: phone → SMS code → (if new: enter name)
- POST /api/auth/complete — verifies OTP, logs in or registers
- Removed password from login/register completely
- New users get random password_hash (not used for auth)
- Removed password change section from ProfileModal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 15:54:05 +03:00
Ai
dbf328b197 feat: remove global admin, open registration, clear DB seed
- All users are equal — no is_admin superuser
- Removed AdminPanel, Shield button from sidebar
- isOwnerOrAdmin checks only by chat role (owner/admin)
- Removed auto-seed of admin user on startup
- DB already cleared on server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 15:45:59 +03:00
Ai
2fd6b14e1a feat: SMS verification via SMSC.ru for registration
- POST /api/auth/send-code — generates 4-digit OTP, sends SMS via SMSC.ru
- Registration now requires SMS code verification (2-step flow)
- Cooldown 60s between resends, 5 min expiry, max 5 attempts
- Frontend: step 1 = enter phone → get code, step 2 = code + name + password
- Large code input with tracking, countdown timer, resend button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 15:17:49 +03:00
Ai
2c362c06cd feat: registration, phone mask, username change
- Registration form on login page (tab toggle login/register)
- POST /api/auth/register — creates account with phone+name+password
- Phone mask +7 (XXX) XXX-XX-XX on login and profile pages
- Username now editable in profile (latin/digits/_, 3-30 chars)
- PUT /api/auth/me now accepts username with uniqueness validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 15:09:32 +03:00
Ai
63f280f754 fix: message actions per-tap only, image sizing, notification sound
- Message action buttons now show per-message (tap on mobile, hover on desktop)
  via state instead of CSS group-hover — fixes all-at-once display on iOS
- Click on message list background closes active action menu
- Images: object-contain + max-w-[240px] so stickers display correctly
- Add Web Audio beep when new message arrives from others (respects mute)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 14:59:32 +03:00
Ai
f4a1187fdf fix: re-sort chat list after pin so pinned chats move to top
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:06:52 +03:00
Ai
3a8c5be1ae fix: swipe stays open for button tap, loading skeleton for chats
- Swipe left now snaps open and action buttons are tappable (onClick)
- Swipe right still executes pin immediately on release
- chatsLoading state in store: shows skeleton animation while loading
- "Нет чатов" only shown after chats have finished loading

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:02:23 +03:00
Ai
9262ece939 feat: swipe gestures, pin/mute, last seen, emoji fix, push/rename fixes
- Add swipe-to-reveal in mobile chat list (right=pin, left=mute/leave)
- Pin/mute API endpoints with is_pinned DB column migration
- Show pin icon on pinned chats, mute icon on muted chats
- Pinned chats sort to top of list
- Fix push notifications sent to message sender (filter uid)
- Remove debug console.log from WS handler
- Fix chat rename not updating in sidebar without reload
- Fix emoji picker z-index and positioning on mobile (z-50, bottom-full)
- Add last seen time in chat header for private chats

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 17:08:18 +03:00
Ai
20daa2ca2f fix: read receipts (single/double check), push notifications for all users
- Track when others read messages via messages_read WS event
- Show Check (single) for sent, CheckCheck (double) only when read
- Send push to all recipients, SW suppresses if app is focused

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:47:38 +03:00
Ai
c1cf15a67c fix: remove fullChat local state, use activeChat directly to prevent desync
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:58:26 +03:00
Ai
87c6d7f82f fix: message sending fallback + iOS zoom on input + openOrCreatePrivate
- MessageInput: HTTP fallback when WebSocket not OPEN (prevents silent failures)
- WsClient: add trySend() returning bool to detect WS availability
- Backend: POST /api/messages/chat/:chatId endpoint for HTTP message send
- openOrCreatePrivate: use openChat() for consistency after refreshing chat list
- iOS fix: inputs get font-size:16px on mobile to prevent Safari auto-zoom

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:44:42 +03:00
Ai
2a4b7d5abc fix: open private chat from sidebar search
- openOrCreatePrivate: load chat by ID directly (skip stale list lookup)
- GET /api/chats/🆔 resolve title/avatar/privateUserId for private chats
  (was returning null title, causing chat area to behave unexpectedly)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:32:06 +03:00
Ai
5d3be2a628 fix: private chat creation and search in NewChatModal
- Fix: onOpen now async, MainLayout fetches fresh chats before opening
  (was using stale closure, chat wasn't found after creation)
- Fix: search null-safety in user list filter (displayName/username could be undefined)
- Fix: search also matches by phone number

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:22:32 +03:00
Ai
8e5c4cd67d feat: phone login, position badge, logout in profile, global search, admin chats
- Login: by phone number instead of username
- Position field: shown as badge next to name in members list, search, admin panel
- Logout: moved from sidebar to profile modal settings
- Sidebar search: global — shows matching users with one-click private chat
- Admin panel: new Чаты tab showing all chats with delete, position/phone in user form
- Backend: /api/admin/chats endpoint, position column migration, phone login support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:17:46 +03:00
Ai
8993a9f6ce feat: diamond app icon + fix login page vertical centering on mobile
- New diamond gem icon (blue gradient background, white faceted gem)
- Replaces all PWA icons: icon-192.png, icon-512.png, apple-touch-icon.png
- Login page uses icon-192.png as logo
- Fix vertical centering with 100dvh to account for mobile browser chrome

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 12:03:27 +03:00
Ai
3f54dbf375 feat: avatar upload for profile/chats, fix session persistence on refresh
- Profile modal: upload/remove user avatar, edit name/bio/phone, change password
- Chat info panel: upload/remove chat photo (owner/admin only)
- Avatar component: render photo when available, fallback to initials
- Session fix: initialize Zustand store from localStorage to prevent redirect on refresh
- Backend: avatar upload endpoints for users and chats, migration adds avatar columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 11:55:11 +03:00
Ai
01331d0263 fix: error boundary, fix MessageInput import order, fix favicon SVG->PNG 2026-05-22 11:38:50 +03:00
Ai
4045d6b796 feat: add PWA icons (192px, 512px, apple-touch-icon) 2026-05-22 11:22:41 +03:00
Ai
7f80e0310c fix: vite-env.d.ts for import.meta.env types, fix isOnline boolean cast 2026-05-22 11:19:36 +03:00
Ai
f12f4a4b68 fix: TypeScript errors — declare authenticate, fix WebSocket types 2026-05-22 11:13:44 +03:00
Ai
941a526f3b fix: use relative API URLs — all traffic through janichat.ru nginx 2026-05-22 11:09:50 +03:00
Ai
3da9a5949d fix: pass VITE_API_URL as build arg in Dockerfile 2026-05-22 11:08:06 +03:00
Ai
1cabe9d04f feat: initial JaniChat messenger — PWA, WebSocket, admin panel 2026-05-22 11:06:43 +03:00