@live-change/peer-connection-frontend 0.9.46 → 0.9.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -63,12 +63,12 @@
63
63
 
64
64
  </div>
65
65
  <div class="flex flex-row gap-2 pt-2 justify-around">
66
- <div v-if="audioInputRequest !== 'none' && audioInputs.length > 0"
66
+ <div v-if="audioInputRequest !== 'none' && model.audioInputs?.length > 0"
67
67
  class="flex flex-col items-stretch grow">
68
68
  <div class="text-sm mb-1 pl-1">Microphone</div>
69
69
  <Dropdown :modelValue="model.audioInput"
70
70
  @update:modelValue="value => updateAudioInput(value)"
71
- :options="audioInputs"
71
+ :options="model.audioInputs"
72
72
  optionLabel="label"
73
73
  placeholder="Select">
74
74
  <template #value="slotProps">
@@ -82,12 +82,12 @@
82
82
  </template>
83
83
  </Dropdown>
84
84
  </div>
85
- <div v-if="audioOutputRequest !== 'none' && audioOutputs.length > 0"
85
+ <div v-if="audioOutputRequest !== 'none' && model.audioOutputs?.length > 0"
86
86
  class="flex flex-col items-stretch grow">
87
87
  <div class="text-sm mb-1 pl-1">Audio output</div>
88
88
  <Dropdown :modelValue="model.audioOutput"
89
89
  @update:modelValue="value => updateAudioOutput(value)"
90
- :options="audioOutputs" optionLabel="label"
90
+ :options="model.audioOutputs" optionLabel="label"
91
91
  placeholder="Select">
92
92
  <template #value="slotProps">
93
93
  <div class="flex flex-row items-center">
@@ -101,12 +101,12 @@
101
101
  </Dropdown>
102
102
  </div>
103
103
 
104
- <div v-if="videoInputRequest !== 'none' && videoInputs.length > 0"
104
+ <div v-if="videoInputRequest !== 'none' && model.videoInputs?.length > 0"
105
105
  class="flex flex-col items-stretch grow">
106
106
  <div class="text-sm mb-1 pl-1">Camera</div>
107
107
  <Dropdown :modelValue="model.videoInput"
108
108
  @update:modelValue="value => updateVideoInput(value)"
109
- :options="videoInputs" optionLabel="label"
109
+ :options="model.videoInputs" optionLabel="label"
110
110
  placeholder="Select">
111
111
  <template #value="slotProps">
112
112
  <div class="flex flex-row items-center">
@@ -240,11 +240,45 @@
240
240
 
241
241
  globalThis.deviceSelectModel = model
242
242
 
243
+ function restoreSavedDevice(model, deviceType) {
244
+ const saved = localStorage.getItem(deviceType)
245
+ const devices = model[deviceType+'s']
246
+ if(!devices || devices.length === 0) {
247
+ model[deviceType] = null
248
+ return
249
+ }
250
+ if(saved) {
251
+ const parsed = JSON.parse(saved)
252
+ const exists = devices.find(device => device.deviceId === parsed.deviceId)
253
+ || devices[deviceType].find(device => device.label === parsed.label)
254
+ if(exists) {
255
+ model[deviceType] = exists
256
+ }
257
+ } else {
258
+ if(model[deviceType]) {
259
+ const exists = devices.find(device => device.deviceId === model[deviceType].deviceId)
260
+ if(exists) return
261
+ }
262
+ model[deviceType] = devices[0]
263
+ }
264
+ }
265
+
243
266
  const devices = ref([])
244
267
  async function updateDevices() {
245
268
  console.log("UPDATE DEVICES")
246
269
  devices.value = await navigator.mediaDevices.enumerateDevices()
247
270
  console.log("DEVICES", JSON.stringify(devices.value))
271
+ const newModel = {
272
+ ...model.value,
273
+ audioInputs: devices.value.filter(device => device.kind === 'audioinput').map(fixLabel),
274
+ audioOutputs: devices.value.filter(device => device.kind === 'audiooutput').map(fixLabel),
275
+ videoInputs: devices.value.filter(device => device.kind === 'videoinput').map(fixLabel)
276
+ }
277
+ console.log("NEW MODEL", newModel)
278
+ restoreSavedDevice(newModel, 'audioInput')
279
+ restoreSavedDevice(newModel, 'audioOutput')
280
+ restoreSavedDevice(newModel, 'videoInput')
281
+ model.value = newModel
248
282
  }
249
283
  if(typeof window !== 'undefined') {
250
284
  useEventListener(navigator.mediaDevices, 'devicechange', updateDevices)
@@ -264,44 +298,6 @@
264
298
  return device
265
299
  }
266
300
 
267
- const audioInputs = computed(() => devices.value.filter(device => device.kind === 'audioinput').map(fixLabel))
268
- const audioOutputs = computed(() => devices.value.filter(device => device.kind === 'audiooutput').map(fixLabel))
269
- const videoInputs = computed(() => devices.value.filter(device => device.kind === 'videoinput').map(fixLabel))
270
-
271
- watch(audioInputs, (value) => {
272
- if(value.length === 0) return
273
- if(model.value?.audioInput) {
274
- const exists = value.find(device => device.deviceId === model.value.audioInput.deviceId)
275
- if(exists) return
276
- }
277
- model.value = {
278
- ...model.value,
279
- audioInput: value[0]
280
- }
281
- }, { immediate: true })
282
- watch(audioOutputs, (value) => {
283
- if(value.length === 0) return
284
- if(model.value?.audioOutput) {
285
- const exists = value.find(device => device.deviceId === model.value.audioOutput.deviceId)
286
- if(exists) return
287
- }
288
- model.value = {
289
- ...model.value,
290
- audioOutput: value[0]
291
- }
292
- }, { immediate: true })
293
- watch(videoInputs, (value) => {
294
- if(value.length === 0) return
295
- if(model.value?.videoInput) {
296
- const exists = value.find(device => device.deviceId === model.value.videoInput.deviceId)
297
- if(exists) return
298
- }
299
- model.value = {
300
- ...model.value,
301
- videoInput: value[0]
302
- }
303
- }, { immediate: true })
304
-
305
301
  /* watch(model.value, (v) => {
306
302
  console.trace("MODEL CHANGED", v)
307
303
  if(typeof v.audioInput === 'string') throw new Error("AUDIO INPUT IS STRING")
@@ -600,92 +596,37 @@
600
596
  ...model.value,
601
597
  audioInput: value,
602
598
  }
603
- console.log("UPDATE AUDIO INPUT", value)
604
- if(value && value.deviceId === audioInputs?.value?.[0]?.deviceId) {
605
- localStorage.removeItem('audioInput')
606
- } else if(value) localStorage.setItem('audioInput', JSON.stringify(value))
607
599
  }
608
600
  function updateAudioOutput(value) {
609
601
  model.value = {
610
602
  ...model.value,
611
603
  audioOutput: value
612
604
  }
613
- console.log("UPDATE AUDIO OUTPUT", value)
614
- if(value && value.deviceId === audioOutputs?.value?.[0]?.deviceId) {
615
- localStorage.removeItem('audioOutput')
616
- } else if(value) localStorage.setItem('audioOutput', JSON.stringify(value))
617
605
  }
618
606
  function updateVideoInput(value) {
619
607
  model.value = {
620
608
  ...model.value,
621
609
  videoInput: value
622
610
  }
623
- if(value && value.deviceId === videoInputs?.value?.[0]?.deviceId) {
624
- localStorage.removeItem('videoInput')
625
- } else if(value) localStorage.setItem('videoInput', JSON.stringify(value))
626
611
  }
627
612
 
628
- watch(() => audioInputs.value, value => {
629
- const saved = localStorage.getItem('audioInput')
630
- if(saved) {
631
- const parsed = JSON.parse(saved)
632
- const exists = value.find(device => device.deviceId === parsed.deviceId)
633
- || value.find(device => device.label === parsed.label)
634
- if(exists) {
635
- model.value = {
636
- ...model.value,
637
- audioInput: exists
638
- }
639
- setTimeout(() => {
640
- model.value = {
641
- ...model.value,
642
- audioInput: exists
643
- }
644
- }, 23)
645
- }
646
- }
613
+ watch(() => model.value.audioInput, (value) => {
614
+ if(value && value.deviceId === model.audioInputs?.value?.[0]?.deviceId) {
615
+ localStorage.removeItem('audioInput')
616
+ } else if(value) localStorage.setItem('audioInput', JSON.stringify(value))
647
617
  })
648
- watch(() => audioOutputs.value, value => {
649
- const saved = localStorage.getItem('audioOutput')
650
- if(saved) {
651
- const parsed = JSON.parse(saved)
652
- const exists = value.find(device => device.deviceId === parsed.deviceId)
653
- || value.find(device => device.label === parsed.label)
654
- if(exists) {
655
- console.log("SET AUDIO OUTPUT", exists)
656
- model.value = {
657
- ...model.value,
658
- audioOutput: exists,
659
- }
660
- setTimeout(() => {
661
- model.value = {
662
- ...model.value,
663
- audioOutput: exists,
664
- }
665
- }, 23)
666
- }
667
- }
618
+ watch(() => model.value.audioOutput, (value) => {
619
+ if(value && value.deviceId === model.audioOutputs?.value?.[0]?.deviceId) {
620
+ localStorage.removeItem('audioOutput')
621
+ } else if(value) localStorage.setItem('audioOutput', JSON.stringify(value))
668
622
  })
669
- watch(() => videoInputs.value, value => {
670
- const saved = localStorage.getItem('videoInput')
671
- if(saved) {
672
- const parsed = JSON.parse(saved)
673
- const exists = value.find(device => device.deviceId === parsed.deviceId)
674
- || value.find(device => device.label === parsed.label)
675
- if(exists) {
676
- model.value = {
677
- ...model.value,
678
- videoInput: exists
679
- }
680
- setTimeout(() => {
681
- model.value = {
682
- ...model.value,
683
- videoInput: exists
684
- }
685
- }, 23)
686
- }
687
- }
623
+ watch(() => model.value.videoInput, (value) => {
624
+ if(value && value.deviceId === model.videoInputs?.value?.[0]?.deviceId) {
625
+ localStorage.removeItem('videoInput')
626
+ } else if(value) localStorage.setItem('videoInput', JSON.stringify(value))
688
627
  })
628
+
629
+
689
630
 
690
631
  </script>
691
632
 
@@ -2,12 +2,12 @@
2
2
  <div>
3
3
  <OverlayPanel ref="mediaSettingsOverlay">
4
4
  <div class="flex flex-col gap-2 pt-2 justify-around" style="min-width: 20rem; max-width: 90vw">
5
- <div v-if="audioInputRequest !== 'none' && audioInputs.length > 0"
5
+ git c<div v-if="audioInputRequest !== 'none' && model.audioInputs?.length > 0"
6
6
  class="flex flex-col items-stretch grow">
7
7
  <div class="text-sm mb-1 pl-1">Microphone</div>
8
8
  <Dropdown :modelValue="model.audioInput"
9
9
  @update:modelValue="value => updateAudioInput(value)"
10
- :options="audioInputs"
10
+ :options="model.audioInputs"
11
11
  optionLabel="label"
12
12
  placeholder="Select">
13
13
  <template #value="slotProps">
@@ -21,12 +21,12 @@
21
21
  </template>
22
22
  </Dropdown>
23
23
  </div>
24
- <div v-if="audioOutputRequest !== 'none' && audioOutputs.length > 0"
24
+ <div v-if="audioOutputRequest !== 'none' && model.audioOutputs?.length > 0"
25
25
  class="flex flex-col items-stretch grow">
26
26
  <div class="text-sm mb-1 pl-1">Audio output</div>
27
27
  <Dropdown :modelValue="model.audioOutput"
28
28
  @update:modelValue="value => updateAudioOutput(value)"
29
- :options="audioOutputs" optionLabel="label"
29
+ :options="model.audioOutputs" optionLabel="label"
30
30
  placeholder="Select">
31
31
  <template #value="slotProps">
32
32
  <div class="flex flex-row items-center">
@@ -40,12 +40,12 @@
40
40
  </Dropdown>
41
41
  </div>
42
42
 
43
- <div v-if="videoInputRequest !== 'none' && videoInputs.length > 0"
43
+ <div v-if="videoInputRequest !== 'none' && model.videoInputs?.length > 0"
44
44
  class="flex flex-col items-stretch grow">
45
45
  <div class="text-sm mb-1 pl-1">Camera</div>
46
46
  <Dropdown :modelValue="model.videoInput"
47
47
  @update:modelValue="value => updateVideoInput(value)"
48
- :options="videoInputs" optionLabel="label"
48
+ :options="model.videoInputs" optionLabel="label"
49
49
  placeholder="Select">
50
50
  <template #value="slotProps">
51
51
  <div class="flex flex-row items-center">
@@ -120,21 +120,6 @@
120
120
  }
121
121
  })
122
122
 
123
- const devices = ref([])
124
- async function updateDevices() {
125
- console.log("UPDATE DEVICES")
126
- devices.value = await navigator.mediaDevices.enumerateDevices()
127
- console.log("DEVICES", JSON.stringify(devices.value))
128
- }
129
- if(typeof window !== 'undefined') {
130
- useEventListener(navigator.mediaDevices, 'devicechange', updateDevices)
131
- onMounted(updateDevices)
132
- }
133
-
134
- const audioInputs = computed(() => devices.value.filter(device => device.kind === 'audioinput'))
135
- const audioOutputs = computed(() => devices.value.filter(device => device.kind === 'audiooutput'))
136
- const videoInputs = computed(() => devices.value.filter(device => device.kind === 'videoinput'))
137
-
138
123
  const mediaSettingsOverlay = ref()
139
124
 
140
125
  function toggleMediaSettings(ev) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/peer-connection-frontend",
3
- "version": "0.9.46",
3
+ "version": "0.9.48",
4
4
  "scripts": {
5
5
  "memDev": "dotenvx run -- node server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
6
6
  "localDevInit": "rm tmp.db; dotenvx run -- node server/start.js localDev --enableSessions --initScript ./init.js",
@@ -22,19 +22,19 @@
22
22
  },
23
23
  "type": "module",
24
24
  "dependencies": {
25
- "@live-change/cli": "^0.9.46",
26
- "@live-change/dao": "^0.9.46",
27
- "@live-change/dao-vue3": "^0.9.46",
28
- "@live-change/dao-websocket": "^0.9.46",
29
- "@live-change/framework": "^0.9.46",
30
- "@live-change/password-authentication-service": "^0.9.46",
31
- "@live-change/secret-code-service": "^0.9.46",
32
- "@live-change/secret-link-service": "^0.9.46",
33
- "@live-change/session-service": "^0.9.46",
34
- "@live-change/user-frontend": "^0.9.46",
35
- "@live-change/user-service": "^0.9.46",
36
- "@live-change/vue3-components": "^0.9.46",
37
- "@live-change/vue3-ssr": "^0.9.46",
25
+ "@live-change/cli": "^0.9.48",
26
+ "@live-change/dao": "^0.9.48",
27
+ "@live-change/dao-vue3": "^0.9.48",
28
+ "@live-change/dao-websocket": "^0.9.48",
29
+ "@live-change/framework": "^0.9.48",
30
+ "@live-change/password-authentication-service": "^0.9.48",
31
+ "@live-change/secret-code-service": "^0.9.48",
32
+ "@live-change/secret-link-service": "^0.9.48",
33
+ "@live-change/session-service": "^0.9.48",
34
+ "@live-change/user-frontend": "^0.9.48",
35
+ "@live-change/user-service": "^0.9.48",
36
+ "@live-change/vue3-components": "^0.9.48",
37
+ "@live-change/vue3-ssr": "^0.9.48",
38
38
  "@vueuse/core": "^12.3.0",
39
39
  "boxicons": "^2.1.4",
40
40
  "codeceptjs-assert": "^0.0.5",
@@ -54,7 +54,7 @@
54
54
  "vue3-scroll-border": "0.1.6"
55
55
  },
56
56
  "devDependencies": {
57
- "@live-change/codeceptjs-helper": "^0.9.46",
57
+ "@live-change/codeceptjs-helper": "^0.9.48",
58
58
  "codeceptjs": "^3.6.10",
59
59
  "generate-password": "1.7.1",
60
60
  "playwright": "1.49.1",
@@ -65,5 +65,5 @@
65
65
  "author": "Michał Łaszczewski <michal@laszczewski.pl>",
66
66
  "license": "BSD-3-Clause",
67
67
  "description": "",
68
- "gitHead": "9d2fe9cbfb28f6cd389c8cbc5cf051f583f58e9e"
68
+ "gitHead": "87d012a548f6170fb78b565a111644eddc571a32"
69
69
  }