-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bluetooth #84
base: main
Are you sure you want to change the base?
Bluetooth #84
Changes from 10 commits
357b11d
b22cf7b
2ba5e8f
e92fec4
925d678
507395b
ef7542c
f4f4395
6942cc2
7440dc5
8140c3b
befb4cb
957a1da
01a665c
13c28a5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
/node_modules | ||
/.pnp | ||
.pnp.js | ||
venv | ||
|
||
# testing | ||
/coverage | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,34 @@ | ||
PODS: | ||
- Capacitor (5.6.0): | ||
- CapacitorCordova | ||
- CapacitorCommunityBluetoothLe (3.1.1): | ||
- Capacitor | ||
- CapacitorCordova (5.6.0) | ||
- CapacitorPreferences (5.0.7): | ||
- Capacitor | ||
|
||
DEPENDENCIES: | ||
- "Capacitor (from `../../node_modules/@capacitor/ios`)" | ||
- "CapacitorCommunityBluetoothLe (from `../../node_modules/@capacitor-community/bluetooth-le`)" | ||
- "CapacitorCordova (from `../../node_modules/@capacitor/ios`)" | ||
- "CapacitorPreferences (from `../../node_modules/@capacitor/preferences`)" | ||
|
||
EXTERNAL SOURCES: | ||
Capacitor: | ||
:path: "../../node_modules/@capacitor/ios" | ||
CapacitorCommunityBluetoothLe: | ||
:path: "../../node_modules/@capacitor-community/bluetooth-le" | ||
CapacitorCordova: | ||
:path: "../../node_modules/@capacitor/ios" | ||
CapacitorPreferences: | ||
:path: "../../node_modules/@capacitor/preferences" | ||
|
||
SPEC CHECKSUMS: | ||
Capacitor: ebfc16cdb8116d04c101686b080342872da42d43 | ||
CapacitorCommunityBluetoothLe: 86ca83c89199336039bad94f45f8363114ae1464 | ||
CapacitorCordova: 931b48fcdbc9bc985fc2f16cec9f77c794a27729 | ||
CapacitorPreferences: 77ac427e98db83bace772455f8ba447430382c4c | ||
|
||
PODFILE CHECKSUM: 769e120bf4dfe4ef1095b83775e36bafeeeb3cdd | ||
PODFILE CHECKSUM: da5221e2db218790239ebdc591ce1525f4e8ad73 | ||
|
||
COCOAPODS: 1.15.2 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import { useEffect, useState } from 'react'; | ||
|
||
import LogoutButton from '@/components/LogoutButton'; | ||
import { NavMenu } from '@/components/NavMenu'; | ||
import { ThemeToggle } from '@/components/ThemeToggle'; | ||
import { Button } from '@/components/ui/button'; | ||
import { useSupabase, useSupabaseConfig } from '@/utils/useSupabaseConfig'; | ||
import { BleClient, ScanResult } from '@capacitor-community/bluetooth-le'; | ||
import { CapacitorHttp, HttpResponse } from '@capacitor/core'; | ||
import { Files } from 'lucide-react'; | ||
import { useRouter } from 'next/router'; | ||
|
||
// const SERVICE_ID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b"; | ||
// const CHARACTERISTIC_ID = "beb5483e-36e1-4688-b7f5-ea07361b26a8"; | ||
// const SAMPLE_RATE = 44100; | ||
// const FRAMES_PER_BUFFER = 512; | ||
// const RECORD_SECONDS = 10; | ||
|
||
export default function Index() { | ||
const [devices, setDevices] = useState<ScanResult[]>([]); | ||
const { supabaseUrl, supabaseToken } = useSupabaseConfig(); | ||
|
||
const connect = async (deviceId: string) => { | ||
const device = await BleClient.requestDevice({ | ||
services: ['4fafc201-1fb5-459e-8fcc-c5c9c331914b'], | ||
}); | ||
await BleClient.connect(device.deviceId); | ||
|
||
return device.deviceId; | ||
}; | ||
|
||
const router = useRouter(); | ||
const [loggedIn, setLoggedIn] = useState(false); | ||
const [data, setData] = useState<any>(null); | ||
const [connected, setConnected] = useState(false); | ||
|
||
const { user, supabaseClient } = useSupabase(); | ||
|
||
useEffect(() => { | ||
scan(); | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (user) { | ||
setLoggedIn(true); | ||
} else { | ||
setLoggedIn(false); | ||
} | ||
}, [user]); | ||
|
||
async function scan(): Promise<void> { | ||
try { | ||
await BleClient.initialize(); | ||
|
||
await BleClient.requestLEScan({}, (result: ScanResult) => { | ||
setDevices((prev) => { | ||
return [...prev, result]; | ||
}); | ||
}); | ||
|
||
setTimeout(async () => { | ||
await BleClient.stopLEScan(); | ||
console.log('stopped scanning'); | ||
}, 5000); | ||
} catch (error) { | ||
console.error(error); | ||
} | ||
} | ||
|
||
async function sendAudioData(audioData: Uint8Array) { | ||
const data = Buffer.from(audioData).toString('base64'); | ||
|
||
if (!supabaseUrl) { | ||
throw new Error('Supabase URL is not defined'); | ||
} | ||
|
||
const options = { | ||
url: supabaseUrl + '/functions/v1/process-audio', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
data: { data: data }, | ||
}; | ||
|
||
const response: HttpResponse = await CapacitorHttp.post(options); | ||
|
||
if (response.status !== 200) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
|
||
const result = await response.data; | ||
console.log('Response from the backend:', result); | ||
} | ||
|
||
return ( | ||
<> | ||
<div className="from-background fixed top-0 flex h-24 w-full items-center justify-between bg-gradient-to-b"></div> | ||
<div className="fixed right-4 top-4 flex space-x-4"> | ||
<NavMenu> | ||
<Button | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as other link |
||
size={'icon'} | ||
className="bg-muted/20 text-muted-foreground hover:bg-muted/40 rounded-full" | ||
onClick={() => router.push('/')} | ||
> | ||
<Files size={20} /> | ||
</Button> | ||
<ThemeToggle /> | ||
<LogoutButton supabaseClient={supabaseClient!} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
</NavMenu> | ||
</div> | ||
<div className="mt-40"> | ||
{devices.map((device, index) => { | ||
if (device.device.name?.includes('ESP32')) { | ||
return ( | ||
<Button | ||
onClick={async () => { | ||
const deviceId = await connect(device.device.deviceId); | ||
|
||
let bufferSize = 500000; | ||
let buffer = new Uint8Array(bufferSize); | ||
|
||
let count = 0; | ||
|
||
const result = await BleClient.startNotifications( | ||
deviceId, | ||
'4fafc201-1fb5-459e-8fcc-c5c9c331914b', | ||
'beb5483e-36e1-4688-b7f5-ea07361b26a8', | ||
async (value) => { | ||
for (let i = 0; i < value.byteLength; i++) { | ||
buffer[count] = value.getUint8(i); | ||
count++; | ||
if (count === bufferSize) { | ||
await sendAudioData(buffer); | ||
count = 0; | ||
} | ||
} | ||
} | ||
); | ||
|
||
await sendAudioData(buffer); | ||
}} | ||
key={index} | ||
> | ||
<h1>Device: {device.device.name + ''}</h1> | ||
<p>UUID: {device.uuids}</p> | ||
</Button> | ||
); | ||
} | ||
})} | ||
<Button onClick={scan}>Scan Again</Button> | ||
</div> | ||
</> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets make sure to use next/link
Link
for these. You can useasChild
onButton
so it renders just as the<a></a>
tag and not<button><a></a></button>
e.g.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh and then remove the useRouter if we arent needing it anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.