Skip to content

Commit

Permalink
feat(ux): make iceServers configurable (#26)
Browse files Browse the repository at this point in the history
closes #8
  • Loading branch information
gorillamoe authored Dec 1, 2024
1 parent 3386c4d commit 278bec7
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 17 deletions.
16 changes: 14 additions & 2 deletions src/main/stateKeeper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import settings from 'electron-settings'
export type SettingsData = {
username: string
color: string
punchHoleServers: string[]
}

type Settings = {
Expand All @@ -24,15 +25,26 @@ type WindowStateKeeper = WindowState & {
}

export const settingsKeeper = async (): Promise<Settings> => {
const defaultSettings: SettingsData = {
username: 'Banana Joe',
color: '#ffffff',
punchHoleServers: ['stun:stun.l.google.com:19302']
}
const hasSettings = await settings.has('settings')
if (hasSettings) {
const data = (await settings.get('settings')) as unknown as SettingsData
return {
get: (): SettingsData => settings.get('settings') as unknown as SettingsData,
get: (): SettingsData => {
return {
...defaultSettings,
...data
}
},
set: (data: SettingsData) => settings.set('settings', data)
}
}
return {
get: (): SettingsData => ({ username: 'Banana Joe', color: '#ffffff' }),
get: (): SettingsData => defaultSettings,
set: (data: SettingsData) => settings.set('settings', data)
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,18 @@ const BananasApi = {
if (state) HANDLE_URL_CLICKS = state
return HANDLE_URL_CLICKS
},
getSettings: async (): Promise<{ username: string; color: string }> => {
getSettings: async (): Promise<{
username: string
color: string
punchHoleServers: string[]
}> => {
return await ipcRenderer.invoke('getSettings')
},
updateSettings: async (settings: { username: string; color: string }): Promise<void> => {
updateSettings: async (settings: {
username: string
color: string
punchHoleServers: string[]
}): Promise<void> => {
ipcRenderer.invoke('updateSettings', settings)
},
toggleRemoteCursors: async (state: boolean): Promise<void> => {
Expand Down
10 changes: 6 additions & 4 deletions src/renderer/src/Config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export const RTCPeerConnectionConfig = {
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
offerToReceiveAudio: true,
offerToReceiveVideo: true
export const getRTCPeerConnectionConfig = async (): Promise<RTCConfiguration> => {
const settings = await window.BananasApi.getSettings()
const iceServers = settings.punchHoleServers.map((url) => ({ urls: url }))
return {
iceServers
}
}
45 changes: 40 additions & 5 deletions src/renderer/src/Settings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,31 @@
import ColorPicker from 'svelte-awesome-color-picker'
let colorPreviewIcon: HTMLElement
let colorValue: string = '#ffffff'
let usernameValue: string = 'Banana Joe'
let isColorValid = false
let colorValue: string = '#ffffff'
let punchHoleServersValue: string = 'stun:stun.l.google.com:19302'
let isUsernameValid = false
let isColorValid = false
let isPunchHoleServersValid = true
let modalSuccessIsActive = false
let modalFailureIsActive = false
$: colorValue, checkColor()
$: usernameValue, checkUsername()
$: punchHoleServersValue, checkPunchHoleServers()
const checkPunchHoleServers = (): void => {
const servers = punchHoleServersValue.split('\n')
isPunchHoleServersValid = servers.every((server) => {
const [protocol, host, port] = server.split(':')
if (protocol === 'stun' || protocol === 'turn') {
if (host && port) {
return true
}
}
return false
})
}
const checkIsValidHexColor = (color: string): boolean => {
return /^#[0-9A-F]{6}$/i.test(color)
}
Expand All @@ -33,8 +48,12 @@
}
async function onSubmit(evt: Event): Promise<void> {
evt.preventDefault()
if (checkIsValidHexColor(colorValue) && usernameValue.length > 0 && usernameValue.length < 32) {
await window.BananasApi.updateSettings({ username: usernameValue, color: colorValue })
if (isUsernameValid && isColorValid && isPunchHoleServersValid) {
await window.BananasApi.updateSettings({
username: usernameValue,
color: colorValue,
punchHoleServers: punchHoleServersValue.split('\n')
})
modalSuccessIsActive = true
setTimeout(() => {
modalSuccessIsActive = false
Expand All @@ -50,6 +69,7 @@
const settings = await window.BananasApi.getSettings()
usernameValue = settings.username
colorValue = settings.color
punchHoleServersValue = settings.punchHoleServers.join('\n')
})
</script>

Expand All @@ -73,8 +93,9 @@
</div>
</div>

<div class="container p-5">
<div class="container p-5 content">
<h1 class="title">Settings</h1>
<h2>Basic</h2>
<form class="form" on:submit={onSubmit}>
<div class="field">
<label class="label" for="username">Username</label>
Expand Down Expand Up @@ -109,6 +130,20 @@
</div>
</div>

<h2>Advanced</h2>

<div class="field">
<label class="label" for="color">STUN/TURN Servers (separated by new lines)</label>
<div class="control has-icons-left has-icons-right">
<textarea
bind:value={punchHoleServersValue}
class="textarea {isPunchHoleServersValid ? 'is-success' : 'is-danger'}"
id="color"
placeholder="stun:stun.l.google.com:19302"
/>
</div>
</div>

<div class="field">
<div class="control">
<button class="button is-link">Save</button>
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/src/WebRTC.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { RTCSessionDescriptionOptions } from './Utils'
import type { BananasRemoteCursorData } from './BananasTypes'
import { getConnectionString, ConnectionType } from './Utils'
import { RTCPeerConnectionConfig } from './Config'
import { getRTCPeerConnectionConfig } from './Config'
const errorHander = (e: ErrorEvent): void => {
console.error(e)
Expand Down Expand Up @@ -76,7 +76,7 @@
pc.close()
pc = null
}
pc = new RTCPeerConnection(RTCPeerConnectionConfig)
pc = new RTCPeerConnection(await getRTCPeerConnectionConfig())
pc.ondatachannel = (e: RTCDataChannelEvent): void => {
if (e.channel.label === 'remoteMouseCursorPositions') {
setupDataChannel(e.channel)
Expand Down
8 changes: 6 additions & 2 deletions src/renderer/src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ declare global {
x: number
y: number
}) => Promise<void>
updateSettings: (settings: { username: string; color: string }) => Promise<void>
getSettings: () => Promise<{ username: string; color: string }>
updateSettings: (settings: {
username: string
color: string
punchHoleServers: string[]
}) => Promise<void>
getSettings: () => Promise<{ username: string; color: string; punchHoleServers: string[] }>
}
}
}

0 comments on commit 278bec7

Please sign in to comment.