This commit is contained in:
@@ -39,7 +39,10 @@
|
|||||||
"WebFetch(domain:getstream.io)",
|
"WebFetch(domain:getstream.io)",
|
||||||
"WebFetch(domain:blog.logrocket.com)",
|
"WebFetch(domain:blog.logrocket.com)",
|
||||||
"WebFetch(domain:virtuoso.dev)",
|
"WebFetch(domain:virtuoso.dev)",
|
||||||
"WebFetch(domain:medium.com)"
|
"WebFetch(domain:medium.com)",
|
||||||
|
"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\\(\\)\\)\")"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,36 @@ jobs:
|
|||||||
VITE_LIVEKIT_URL: ${{ secrets.VITE_LIVEKIT_URL }}
|
VITE_LIVEKIT_URL: ${{ secrets.VITE_LIVEKIT_URL }}
|
||||||
CUSTOM_APP_BUILDER_PATH: /tmp/app-builder
|
CUSTOM_APP_BUILDER_PATH: /tmp/app-builder
|
||||||
|
|
||||||
|
- name: Decode Android keystore
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.ANDROID_KEYSTORE_BASE64 }}" | base64 -d > /tmp/discord-clone-release.keystore
|
||||||
|
echo "ANDROID_KEYSTORE_FILE=/tmp/discord-clone-release.keystore" >> $GITHUB_ENV
|
||||||
|
echo "ANDROID_KEYSTORE_PASSWORD=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
|
||||||
|
echo "ANDROID_KEY_ALIAS=${{ secrets.ANDROID_KEY_ALIAS }}" >> $GITHUB_ENV
|
||||||
|
echo "ANDROID_KEY_PASSWORD=${{ secrets.ANDROID_KEY_PASSWORD }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build web app for Android
|
||||||
|
run: npm run build -w apps/web
|
||||||
|
env:
|
||||||
|
VITE_CONVEX_URL: ${{ secrets.VITE_CONVEX_URL }}
|
||||||
|
VITE_LIVEKIT_URL: ${{ secrets.VITE_LIVEKIT_URL }}
|
||||||
|
|
||||||
|
- name: Capacitor sync
|
||||||
|
run: npx cap sync
|
||||||
|
working-directory: apps/android
|
||||||
|
|
||||||
|
- name: Build Android APK
|
||||||
|
run: |
|
||||||
|
cd apps/android/android
|
||||||
|
chmod +x gradlew
|
||||||
|
./gradlew assembleRelease --no-daemon
|
||||||
|
|
||||||
|
- name: Copy APK to dist
|
||||||
|
run: |
|
||||||
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
cp apps/android/android/app/build/outputs/apk/release/app-release.apk \
|
||||||
|
apps/electron/dist/DiscordClone-v${VERSION}.apk
|
||||||
|
|
||||||
- name: List build artifacts
|
- name: List build artifacts
|
||||||
run: ls -la apps/electron/dist/
|
run: ls -la apps/electron/dist/
|
||||||
|
|
||||||
@@ -126,7 +156,8 @@ jobs:
|
|||||||
apps/electron/dist/*.exe \
|
apps/electron/dist/*.exe \
|
||||||
apps/electron/dist/*.exe.blockmap \
|
apps/electron/dist/*.exe.blockmap \
|
||||||
apps/electron/dist/*.AppImage \
|
apps/electron/dist/*.AppImage \
|
||||||
apps/electron/dist/*.flatpak; do
|
apps/electron/dist/*.flatpak \
|
||||||
|
apps/electron/dist/*.apk; do
|
||||||
[ -f "$file" ] || continue
|
[ -f "$file" ] || continue
|
||||||
FILENAME=$(basename "$file")
|
FILENAME=$(basename "$file")
|
||||||
ENCODED_NAME=$(echo -n "$FILENAME" | jq -sRr @uri)
|
ENCODED_NAME=$(echo -n "$FILENAME" | jq -sRr @uri)
|
||||||
|
|||||||
18
TODO.md
18
TODO.md
@@ -7,10 +7,16 @@
|
|||||||
- Add photo / video albums like Commit https://commet.chat/
|
- Add photo / video albums like Commit https://commet.chat/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- - When resiszing the window and if im already at the bottom of the channel, i want to make sure i stay at the bottom of the channel.
|
|
||||||
|
|
||||||
- So right now in our search we can search and jump to messages. We can only jump to messages loaded in our chat already. How can we make it so we can jump to older messages not loaded in our chat at the moment? -->
|
|
||||||
|
|
||||||
|
|
||||||
- Are we using the encryped sql database to help load messages faster?
|
- Are we using the encryped sql database to help load messages faster?
|
||||||
|
|
||||||
|
|
||||||
|
- Notification on taskbar for windows
|
||||||
|
- Notification popup for windows for discord
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Android
|
||||||
|
|
||||||
|
- On android lets make sure we can save the user login like we do on electron so they dont have to login everytime.
|
||||||
|
|
||||||
|
- On android why does my app not reach the bottom of the screen that its allowed?
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@discord-clone/android",
|
"name": "@discord-clone/android",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "1.0.25",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"cap:sync": "npx cap sync",
|
"cap:sync": "npx cap sync",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@discord-clone/electron",
|
"name": "@discord-clone/electron",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.24",
|
"version": "1.0.25",
|
||||||
"description": "Discord Clone - Electron app",
|
"description": "Discord Clone - Electron app",
|
||||||
"author": "Moyettes",
|
"author": "Moyettes",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@discord-clone/web",
|
"name": "@discord-clone/web",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "1.0.25",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ rtc:
|
|||||||
port_range_start: 50000
|
port_range_start: 50000
|
||||||
port_range_end: 50100
|
port_range_end: 50100
|
||||||
use_external_ip: false # false for local dev; set true for production
|
use_external_ip: false # false for local dev; set true for production
|
||||||
|
node_ip: 72.26.56.3 # advertise LAN IP so Android/other-network clients can reach
|
||||||
|
tcp_port: 7881 # ICE-over-TCP fallback (Android emulator blocks UDP high ports)
|
||||||
|
|
||||||
# API credentials (must match LIVEKIT_API_KEY / LIVEKIT_API_SECRET env vars)
|
# API credentials (must match LIVEKIT_API_KEY / LIVEKIT_API_SECRET env vars)
|
||||||
keys:
|
keys:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@discord-clone/shared",
|
"name": "@discord-clone/shared",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.24",
|
"version": "1.0.25",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/App.jsx",
|
"main": "src/App.jsx",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -240,6 +240,17 @@ export const VoiceProvider = ({ children }) => {
|
|||||||
setConnectionState('connecting');
|
setConnectionState('connecting');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Request microphone permission (triggers Android runtime prompt)
|
||||||
|
try {
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
stream.getTracks().forEach(t => t.stop());
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Microphone permission denied:', e);
|
||||||
|
setConnectionState('error');
|
||||||
|
setActiveChannelId(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { token: lkToken } = await convex.action(api.voice.getToken, {
|
const { token: lkToken } = await convex.action(api.voice.getToken, {
|
||||||
channelId,
|
channelId,
|
||||||
userId,
|
userId,
|
||||||
@@ -255,10 +266,18 @@ export const VoiceProvider = ({ children }) => {
|
|||||||
|
|
||||||
const noiseSuppression = localStorage.getItem('voiceNoiseSuppression') !== 'false'; // default true
|
const noiseSuppression = localStorage.getItem('voiceNoiseSuppression') !== 'false'; // default true
|
||||||
|
|
||||||
|
const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
|
||||||
|
|
||||||
const newRoom = new Room({
|
const newRoom = new Room({
|
||||||
adaptiveStream: true,
|
adaptiveStream: true,
|
||||||
dynacast: true,
|
dynacast: true,
|
||||||
autoSubscribe: true,
|
autoSubscribe: true,
|
||||||
|
rtcConfig: {
|
||||||
|
iceServers: [
|
||||||
|
{ urls: 'stun:stun.l.google.com:19302' },
|
||||||
|
{ urls: 'stun:stun1.l.google.com:19302' },
|
||||||
|
],
|
||||||
|
},
|
||||||
audioCaptureDefaults: {
|
audioCaptureDefaults: {
|
||||||
autoGainControl: true,
|
autoGainControl: true,
|
||||||
echoCancellation: true,
|
echoCancellation: true,
|
||||||
@@ -275,7 +294,7 @@ export const VoiceProvider = ({ children }) => {
|
|||||||
dtx: false,
|
dtx: false,
|
||||||
red: true,
|
red: true,
|
||||||
videoEncoding: VideoPresets.h720.encoding,
|
videoEncoding: VideoPresets.h720.encoding,
|
||||||
videoCodec: 'vp9',
|
videoCodec: isMobile ? 'vp8' : 'vp9',
|
||||||
screenShareEncoding: {
|
screenShareEncoding: {
|
||||||
maxBitrate: 10_000_000,
|
maxBitrate: 10_000_000,
|
||||||
maxFramerate: 60,
|
maxFramerate: 60,
|
||||||
|
|||||||
@@ -422,7 +422,6 @@ body {
|
|||||||
|
|
||||||
.chat-input-form {
|
.chat-input-form {
|
||||||
padding: 0 8px 8px;
|
padding: 0 8px 8px;
|
||||||
margin-top: 24px;
|
|
||||||
background-color: var(--bg-primary);
|
background-color: var(--bg-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user