diff --git a/modules/core/render-backend/index.ts b/modules/core/render-backend/index.ts index 8aab5c1..af44619 100644 --- a/modules/core/render-backend/index.ts +++ b/modules/core/render-backend/index.ts @@ -24,5 +24,7 @@ ipcMain.on('basic-action', (event, action, ...args: any[]) => { window.webContents.openDevTools(); } else if(action === "reload-window") { window.reload(); + } else if(action === "quit") { + window.close(); } }); \ No newline at end of file diff --git a/modules/core/ui-loader/Loader.ts b/modules/core/ui-loader/Loader.ts index 554bdfd..c6d99b2 100644 --- a/modules/core/ui-loader/Loader.ts +++ b/modules/core/ui-loader/Loader.ts @@ -231,6 +231,7 @@ async function loadCachedOrRemoteUiPack(channel: string, callbackStatus: (messag const requiredClientVersion = parseVersion(remoteVersion.requiredClientVersion); if(requiredClientVersion.newerThan(clientVersion) && !is_debug) { /* We can't use the newer version. Use the latest available. Update prompt should come when starting the client */ + console.log("Ignoring remote version since our client is too old to use it. Required client: %s, Client version: %s", remoteVersion.requiredClientVersion, clientVersion.toString()); } else if(remoteVersion.timestamp <= newestLocalVersion && !ignoreNewVersionTimestamp) { /* We've already a equal or newer version. Don't use the remote version */ /* if remote is older than current bundled version its not a drop since it could be used as a fallback */ diff --git a/modules/renderer/audio/AudioPlayer.ts b/modules/renderer/audio/AudioPlayer.ts index 3faed6f..78bc90e 100644 --- a/modules/renderer/audio/AudioPlayer.ts +++ b/modules/renderer/audio/AudioPlayer.ts @@ -1,78 +1,6 @@ import * as native from "tc-native/connection"; import {AudioBackend, OutputDevice} from "tc-shared/audio/Player"; -//FIXME: Native audio initialize handle! -export interface Device { - device_id: string; - name: string; -} - -let _initialized_callbacks: (() => any)[] = []; -export let _initialized = false; -export let _initializing = false; -export let _current_device: native.audio.AudioDevice; - -export function initialized() : boolean { - return _initialized; -} -export function on_ready(cb: () => any) { - if(_initialized) - cb(); - else - _initialized_callbacks.push(cb); -} - -export function initialize() { - if(_initializing) return; - _initializing = true; - - native.audio.initialize(() => { - _initialized = true; - for(const callback of _initialized_callbacks) - callback(); - _initialized_callbacks = []; - }); - return true; -} - -export async function available_devices() : Promise { - return native.audio.available_devices().filter(e => e.output_supported || e.output_default); -} - -export async function set_device(device_id?: string) : Promise { - const dev = native.audio.available_devices().filter(e => e.device_id == device_id); - if(dev.length == 0) { - console.warn("Missing audio device with is %s", device_id); - throw "invalid device id"; - } - - try { - native.audio.playback.set_device(dev[0].device_id); - } catch(error) { - if(error instanceof Error) - throw error.message; - throw error; - } - _current_device = dev[0]; -} - -export function current_device() : Device { - if(_current_device) - return _current_device; - - const dev = native.audio.available_devices().filter(e => e.output_default); - if(dev.length > 0) - return dev[0]; - return {device_id: "default", name: "default"} as Device; -} - -export function get_master_volume() : number { - return native.audio.playback.get_master_volume(); -} -export function set_master_volume(volume: number) { - native.audio.playback.set_master_volume(volume); -} - export class NativeAudioPlayer implements AudioBackend { private readonly audioContext: AudioContext; private initializedPromises: (() => void)[]; @@ -112,7 +40,20 @@ export class NativeAudioPlayer implements AudioBackend { } async getAvailableDevices(): Promise { - return native.audio.available_devices().filter(e => e.output_supported || e.output_default).map(entry => ({ + const devices = native.audio.available_devices().filter(e => e.output_supported || e.output_default); + /* Fixup MMEs character limit of 31 by trying to resolve a name somewhere else */ + devices.forEach(device => { + if(device.driver !== "MME") { + return; + } + + const fallback = devices.find(fallbackDevice => fallbackDevice.name.substring(0, 31) === device.name && fallbackDevice.name.length > 31); + if(fallback) { + device.name = fallback.name; + } + }); + + return devices.map(entry => ({ device_id: entry.device_id, driver: entry.driver, name: entry.name diff --git a/modules/renderer/audio/InputDeviceList.ts b/modules/renderer/audio/InputDeviceList.ts index 6935786..5655c4b 100644 --- a/modules/renderer/audio/InputDeviceList.ts +++ b/modules/renderer/audio/InputDeviceList.ts @@ -65,7 +65,8 @@ class InputDeviceList extends AbstractDeviceList { if(fallback) { device.name = fallback.name; } - }) + }); + this.setState("healthy"); return this.cachedDevices; } diff --git a/native/serverconnection/src/audio/AudioOutput.cpp b/native/serverconnection/src/audio/AudioOutput.cpp index c145df6..6ff4564 100644 --- a/native/serverconnection/src/audio/AudioOutput.cpp +++ b/native/serverconnection/src/audio/AudioOutput.cpp @@ -513,7 +513,9 @@ void AudioOutput::fill_buffer(void *output, size_t out_frame_count, size_t out_c void AudioOutput::set_device(const std::shared_ptr &new_device) { lock_guard lock(this->device_lock); - if(this->device == new_device) return; + if(this->device == new_device) { + return; + } this->close_device(); this->device = new_device; @@ -537,7 +539,9 @@ bool AudioOutput::playback(std::string& error) { error = "invalid device handle"; return false; } - if(this->playback_) return true; + if(this->playback_) { + return true; + } this->playback_ = this->device->playback(); if(!this->playback_) { diff --git a/native/serverconnection/src/audio/js/AudioPlayer.cpp b/native/serverconnection/src/audio/js/AudioPlayer.cpp index e65880b..b788c43 100644 --- a/native/serverconnection/src/audio/js/AudioPlayer.cpp +++ b/native/serverconnection/src/audio/js/AudioPlayer.cpp @@ -99,14 +99,13 @@ NAN_METHOD(player::set_playback_device) { return; } - const auto null_device = info[0]->IsNullOrUndefined(); - if(info.Length() != 1 || !(info[0]->IsString() || null_device)) { + if(info.Length() != 1 || !info[0]->IsString()) { Nan::ThrowError("invalid arguments"); return; } - auto device = null_device ? nullptr : audio::find_device_by_id(*Nan::Utf8String(info[0]), false); - if(!device && !null_device) { + auto device = audio::find_device_by_id(*Nan::Utf8String(info[0]), false); + if(!device) { Nan::ThrowError("invalid device id"); return; }