diff --git a/.claude/settings.local.json b/.claude/settings.local.json index df80065..8a9fd2a 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -43,7 +43,8 @@ "Bash(keytool:*)", "Bash(echo:*)", "Bash(python -c \"import base64; print\\(base64.b64encode\\(open\\(r''C:\\\\Users\\\\bryan\\\\Desktop\\\\Discord Clone\\\\discord-clone-release.keystore'',''rb''\\).read\\(\\)\\).decode\\(\\)\\)\")", - "WebFetch(domain:gitea.moyettes.com)" + "WebFetch(domain:gitea.moyettes.com)", + "Bash(grep:*)" ] } } diff --git a/apps/android/package.json b/apps/android/package.json index 63787ec..929ef2a 100644 --- a/apps/android/package.json +++ b/apps/android/package.json @@ -1,7 +1,7 @@ { "name": "@discord-clone/android", "private": true, - "version": "1.0.28", + "version": "1.0.29", "type": "module", "scripts": { "cap:sync": "npx cap sync", diff --git a/apps/electron/package.json b/apps/electron/package.json index 8a79d19..0c12c88 100644 --- a/apps/electron/package.json +++ b/apps/electron/package.json @@ -1,7 +1,7 @@ { "name": "@discord-clone/electron", "private": true, - "version": "1.0.28", + "version": "1.0.29", "description": "Discord Clone - Electron app", "author": "Moyettes", "type": "module", diff --git a/apps/electron/src/platform/index.js b/apps/electron/src/platform/index.js index 888b7ab..3643542 100644 --- a/apps/electron/src/platform/index.js +++ b/apps/electron/src/platform/index.js @@ -56,12 +56,14 @@ const electronPlatform = { updates: { checkUpdate: () => window.updateAPI.checkFlatpakUpdate(), }, + systemBars: null, searchDB, features: { hasWindowControls: true, hasScreenCapture: true, hasNativeUpdates: true, hasSearch: true, + hasSystemBars: false, }, }; diff --git a/apps/web/package.json b/apps/web/package.json index 13270be..37c0a3f 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,7 +1,7 @@ { "name": "@discord-clone/web", "private": true, - "version": "1.0.28", + "version": "1.0.29", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/platform-web/src/index.js b/packages/platform-web/src/index.js index b766ed0..c6f8f3b 100644 --- a/packages/platform-web/src/index.js +++ b/packages/platform-web/src/index.js @@ -35,12 +35,16 @@ const webPlatform = { }, windowControls: null, updates: null, + voiceService: null, + systemBars: null, searchDB, features: { hasWindowControls: false, hasScreenCapture: true, hasNativeUpdates: false, hasSearch: true, + hasVoiceService: false, + hasSystemBars: false, }, }; @@ -104,6 +108,34 @@ if (window.Capacitor?.isNativePlatform?.()) { }, }; webPlatform.features.hasNativeUpdates = true; + webPlatform.features.hasScreenCapture = false; + + // Native voice foreground service + const VoiceService = window.Capacitor.Plugins.VoiceService; + if (VoiceService) { + webPlatform.voiceService = { + async startService({ channelName, isMuted, isDeafened }) { + await VoiceService.startService({ channelName, isMuted, isDeafened }); + }, + async stopService() { + await VoiceService.stopService(); + }, + async updateNotification(opts) { + await VoiceService.updateNotification(opts); + }, + addNotificationActionListener(callback) { + return VoiceService.addListener('voiceNotificationAction', callback); + }, + }; + webPlatform.features.hasVoiceService = true; + } + + // Native system bar coloring + const SystemBars = window.Capacitor.Plugins.SystemBars; + if (SystemBars) { + webPlatform.systemBars = { setColors: (opts) => SystemBars.setColors(opts) }; + webPlatform.features.hasSystemBars = true; + } } export default webPlatform; diff --git a/packages/shared/src/App.jsx b/packages/shared/src/App.jsx index bc47c91..fc7fecb 100644 --- a/packages/shared/src/App.jsx +++ b/packages/shared/src/App.jsx @@ -6,6 +6,7 @@ import Recovery from './pages/Recovery'; import Chat from './pages/Chat'; import { usePlatform } from './platform'; import { useSearch } from './contexts/SearchContext'; +import { useSystemBars } from './hooks/useSystemBars'; const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000; @@ -15,6 +16,7 @@ function AuthGuard({ children }) { const navigate = useNavigate(); const { session, settings } = usePlatform(); const searchCtx = useSearch(); + useSystemBars(null); useEffect(() => { let cancelled = false; diff --git a/packages/shared/src/assets/sounds/camera_off.mp3 b/packages/shared/src/assets/sounds/camera_off.mp3 new file mode 100644 index 0000000..f6731fb Binary files /dev/null and b/packages/shared/src/assets/sounds/camera_off.mp3 differ diff --git a/packages/shared/src/assets/sounds/camera_on.mp3 b/packages/shared/src/assets/sounds/camera_on.mp3 new file mode 100644 index 0000000..65ad834 Binary files /dev/null and b/packages/shared/src/assets/sounds/camera_on.mp3 differ diff --git a/packages/shared/src/assets/sounds/deafen.mp3 b/packages/shared/src/assets/sounds/deafen.mp3 index 8e732e1..8168123 100644 Binary files a/packages/shared/src/assets/sounds/deafen.mp3 and b/packages/shared/src/assets/sounds/deafen.mp3 differ diff --git a/packages/shared/src/assets/sounds/join_call.mp3 b/packages/shared/src/assets/sounds/join_call.mp3 index 8a7b92f..3e030fa 100644 Binary files a/packages/shared/src/assets/sounds/join_call.mp3 and b/packages/shared/src/assets/sounds/join_call.mp3 differ diff --git a/packages/shared/src/assets/sounds/leave_call.mp3 b/packages/shared/src/assets/sounds/leave_call.mp3 index 491d03d..c58e9ed 100644 Binary files a/packages/shared/src/assets/sounds/leave_call.mp3 and b/packages/shared/src/assets/sounds/leave_call.mp3 differ diff --git a/packages/shared/src/assets/sounds/mute.mp3 b/packages/shared/src/assets/sounds/mute.mp3 index d80ae37..b87de43 100644 Binary files a/packages/shared/src/assets/sounds/mute.mp3 and b/packages/shared/src/assets/sounds/mute.mp3 differ diff --git a/packages/shared/src/assets/sounds/outgoing_ring.mp3 b/packages/shared/src/assets/sounds/outgoing_ring.mp3 new file mode 100644 index 0000000..5a00cd0 Binary files /dev/null and b/packages/shared/src/assets/sounds/outgoing_ring.mp3 differ diff --git a/packages/shared/src/assets/sounds/screenshare_start.mp3 b/packages/shared/src/assets/sounds/screenshare_start.mp3 index 36e4604..444fce8 100644 Binary files a/packages/shared/src/assets/sounds/screenshare_start.mp3 and b/packages/shared/src/assets/sounds/screenshare_start.mp3 differ diff --git a/packages/shared/src/assets/sounds/undeafen.mp3 b/packages/shared/src/assets/sounds/undeafen.mp3 index 8459628..797c56e 100644 Binary files a/packages/shared/src/assets/sounds/undeafen.mp3 and b/packages/shared/src/assets/sounds/undeafen.mp3 differ diff --git a/packages/shared/src/assets/sounds/unmute.mp3 b/packages/shared/src/assets/sounds/unmute.mp3 index 7d386a6..fd78422 100644 Binary files a/packages/shared/src/assets/sounds/unmute.mp3 and b/packages/shared/src/assets/sounds/unmute.mp3 differ diff --git a/packages/shared/src/assets/sounds/user_moved.mp3 b/packages/shared/src/assets/sounds/user_moved.mp3 new file mode 100644 index 0000000..1dfb081 Binary files /dev/null and b/packages/shared/src/assets/sounds/user_moved.mp3 differ diff --git a/packages/shared/src/components/ChatArea.jsx b/packages/shared/src/components/ChatArea.jsx index 2593d0a..8234829 100644 --- a/packages/shared/src/components/ChatArea.jsx +++ b/packages/shared/src/components/ChatArea.jsx @@ -1,4 +1,5 @@ import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'; +import ReactDOM from 'react-dom'; import { Virtuoso } from 'react-virtuoso'; import { useQuery, usePaginatedQuery, useMutation, useConvex } from 'convex/react'; import { api } from '../../../../convex/_generated/api'; @@ -30,6 +31,7 @@ import ColoredIcon from './ColoredIcon'; import { usePlatform } from '../platform'; import { useVoice } from '../contexts/VoiceContext'; import { useSearch } from '../contexts/SearchContext'; +import { useIsMobile } from '../hooks/useIsMobile'; import { generateUniqueMessage } from '../utils/floodMessages'; const SCROLL_DEBUG = true; @@ -340,7 +342,7 @@ const Attachment = ({ metadata, onLoad, onImageClick }) => { if (error) return