Improve call device migration.

This commit is contained in:
John Preston 2024-01-23 17:07:51 +04:00
parent e5b89b1572
commit 9a6ab3b0f2
3 changed files with 74 additions and 37 deletions

View file

@ -633,6 +633,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_section_devices" = "Speakers and Camera"; "lng_settings_section_devices" = "Speakers and Camera";
"lng_settings_devices_calls" = "Calls and video chats"; "lng_settings_devices_calls" = "Calls and video chats";
"lng_settings_devices_calls_same" = "Use the same devices for calls"; "lng_settings_devices_calls_same" = "Use the same devices for calls";
"lng_settings_devices_inactive" = "Unavailable";
"lng_settings_language" = "Language"; "lng_settings_language" = "Language";
"lng_settings_default_scale" = "Default interface scale"; "lng_settings_default_scale" = "Default interface scale";

View file

@ -160,8 +160,8 @@ QByteArray Settings::serialize() const {
+ Serialize::stringSize(_downloadPath.current()) + Serialize::stringSize(_downloadPath.current())
+ Serialize::bytearraySize(_downloadPathBookmark) + Serialize::bytearraySize(_downloadPathBookmark)
+ sizeof(qint32) * 9 + sizeof(qint32) * 9
+ Serialize::stringSize(_callPlaybackDeviceId.current()) + Serialize::stringSize(QString()) // legacy call output device id
+ Serialize::stringSize(_callCaptureDeviceId.current()) + Serialize::stringSize(QString()) // legacy call input device id
+ sizeof(qint32) * 5; + sizeof(qint32) * 5;
for (const auto &[key, value] : _soundOverrides) { for (const auto &[key, value] : _soundOverrides) {
size += Serialize::stringSize(key) + Serialize::stringSize(value); size += Serialize::stringSize(key) + Serialize::stringSize(value);
@ -207,7 +207,9 @@ QByteArray Settings::serialize() const {
} }
size += sizeof(qint32) * 2 size += sizeof(qint32) * 2
+ Serialize::stringSize(_playbackDeviceId.current()) + Serialize::stringSize(_playbackDeviceId.current())
+ Serialize::stringSize(_captureDeviceId.current()); + Serialize::stringSize(_captureDeviceId.current())
+ Serialize::stringSize(_callPlaybackDeviceId.current())
+ Serialize::stringSize(_callCaptureDeviceId.current());
auto result = QByteArray(); auto result = QByteArray();
result.reserve(size); result.reserve(size);
@ -232,8 +234,8 @@ QByteArray Settings::serialize() const {
<< qint32(_notificationsCount) << qint32(_notificationsCount)
<< static_cast<qint32>(_notificationsCorner) << static_cast<qint32>(_notificationsCorner)
<< qint32(_autoLock) << qint32(_autoLock)
<< _callPlaybackDeviceId.current() << QString() // legacy call output device id
<< _callCaptureDeviceId.current() << QString() // legacy call input device id
<< qint32(_callOutputVolume) << qint32(_callOutputVolume)
<< qint32(_callInputVolume) << qint32(_callInputVolume)
<< qint32(_callAudioDuckingEnabled ? 1 : 0) << qint32(_callAudioDuckingEnabled ? 1 : 0)
@ -349,7 +351,9 @@ QByteArray Settings::serialize() const {
<< qint32(_trayIconMonochrome.current() ? 1 : 0) << qint32(_trayIconMonochrome.current() ? 1 : 0)
<< qint32(_ttlVoiceClickTooltipHidden.current() ? 1 : 0) << qint32(_ttlVoiceClickTooltipHidden.current() ? 1 : 0)
<< _playbackDeviceId.current() << _playbackDeviceId.current()
<< _captureDeviceId.current(); << _captureDeviceId.current()
<< _callPlaybackDeviceId.current()
<< _callCaptureDeviceId.current();
} }
Ensures(result.size() == size); Ensures(result.size() == size);
@ -384,6 +388,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
QString playbackDeviceId = _playbackDeviceId.current(); QString playbackDeviceId = _playbackDeviceId.current();
QString captureDeviceId = _captureDeviceId.current(); QString captureDeviceId = _captureDeviceId.current();
QString cameraDeviceId = _cameraDeviceId.current(); QString cameraDeviceId = _cameraDeviceId.current();
QString legacyCallPlaybackDeviceId = _callPlaybackDeviceId.current();
QString legacyCallCaptureDeviceId = _callCaptureDeviceId.current();
QString callPlaybackDeviceId = _callPlaybackDeviceId.current(); QString callPlaybackDeviceId = _callPlaybackDeviceId.current();
QString callCaptureDeviceId = _callCaptureDeviceId.current(); QString callCaptureDeviceId = _callCaptureDeviceId.current();
qint32 callOutputVolume = _callOutputVolume; qint32 callOutputVolume = _callOutputVolume;
@ -483,8 +489,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
>> notificationsCount >> notificationsCount
>> notificationsCorner >> notificationsCorner
>> autoLock >> autoLock
>> callPlaybackDeviceId >> legacyCallPlaybackDeviceId
>> callCaptureDeviceId >> legacyCallCaptureDeviceId
>> callOutputVolume >> callOutputVolume
>> callInputVolume >> callInputVolume
>> callAudioDuckingEnabled >> callAudioDuckingEnabled
@ -728,6 +734,19 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
>> playbackDeviceId >> playbackDeviceId
>> captureDeviceId; >> captureDeviceId;
} }
if (!stream.atEnd()) {
stream
>> callPlaybackDeviceId
>> callCaptureDeviceId;
} else {
const auto &defaultId = Webrtc::kDefaultDeviceId;
callPlaybackDeviceId = (legacyCallPlaybackDeviceId == defaultId)
? QString()
: legacyCallPlaybackDeviceId;
callCaptureDeviceId = (legacyCallCaptureDeviceId == defaultId)
? QString()
: legacyCallCaptureDeviceId;
}
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
LOG(("App Error: " LOG(("App Error: "
"Bad data for Core::Settings::constructFromSerialized()")); "Bad data for Core::Settings::constructFromSerialized()"));

View file

@ -513,6 +513,30 @@ void ChooseAudioDeviceBox(
*st, *st,
*radioSt), *radioSt),
margins); margins);
const auto showUnavailable = [=](QString text) {
AddSkip(other);
AddSubsectionTitle(other, tr::lng_settings_devices_inactive());
const auto &radio = *radioSt;
const auto button = other->add(
object_ptr<Ui::Radiobutton>(other, fake, 0, text, *st, radio),
margins);
button->show();
button->setDisabled(true);
button->finishAnimating();
button->setAttribute(Qt::WA_TransparentForMouseEvents);
while (other->count() > 3) {
delete other->widgetAt(0);
}
if (const auto width = box->width()) {
other->resizeToWidth(width);
}
};
const auto hideUnavailable = [=] {
while (other->count() > 0) {
delete other->widgetAt(0);
}
};
const auto selectCurrent = [=](QString current) { const auto selectCurrent = [=](QString current) {
state->ignoreValueChange = true; state->ignoreValueChange = true;
@ -521,7 +545,7 @@ void ChooseAudioDeviceBox(
}); });
if (current.isEmpty() || current == kDefaultDeviceId) { if (current.isEmpty() || current == kDefaultDeviceId) {
group->setValue(0); group->setValue(0);
other->clear(); hideUnavailable();
} else { } else {
auto found = false; auto found = false;
for (const auto &[index, id] : state->ids) { for (const auto &[index, id] : state->ids) {
@ -532,7 +556,7 @@ void ChooseAudioDeviceBox(
} }
} }
if (found) { if (found) {
other->clear(); hideUnavailable();
} else { } else {
group->setValue(0); group->setValue(0);
const auto i = ranges::find( const auto i = ranges::find(
@ -540,32 +564,22 @@ void ChooseAudioDeviceBox(
current, current,
&DeviceInfo::id); &DeviceInfo::id);
if (i != end(state->list)) { if (i != end(state->list)) {
const auto button = other->add( showUnavailable(i->name);
object_ptr<Ui::Radiobutton>(
other,
fake,
0,
i->name,
*st,
*radioSt),
margins);
button->show();
button->setDisabled(true);
button->finishAnimating();
button->setAttribute(Qt::WA_TransparentForMouseEvents);
while (other->count() > 1) {
delete other->widgetAt(1);
}
if (const auto width = box->width()) {
other->resizeToWidth(width);
}
} else { } else {
other->clear(); hideUnavailable();
} }
} }
} }
}; };
const auto choose = [=](const QString &id) {
const auto weak = Ui::MakeWeak(box);
chosen(id);
if (weak) {
box->closeBox();
}
};
std::move( std::move(
devicesValue devicesValue
) | rpl::start_with_next([=](std::vector<DeviceInfo> &&list) { ) | rpl::start_with_next([=](std::vector<DeviceInfo> &&list) {
@ -581,9 +595,10 @@ void ChooseAudioDeviceBox(
const auto current = state->currentId.current(); const auto current = state->currentId.current();
for (const auto &info : state->list) { for (const auto &info : state->list) {
const auto id = info.id;
if (info.inactive) { if (info.inactive) {
continue; continue;
} else if (current == info.id) { } else if (current == id) {
group->setValue(index); group->setValue(index);
} }
const auto button = buttons->insert( const auto button = buttons->insert(
@ -598,8 +613,14 @@ void ChooseAudioDeviceBox(
margins); margins);
button->show(); button->show();
button->finishAnimating(); button->finishAnimating();
button->clicks(
) | rpl::filter([=] {
return (current == id);
}) | rpl::start_with_next([=] {
choose(id);
}, button->lifetime());
state->ids.emplace(index, info.id); state->ids.emplace(index, id);
if (index < count) { if (index < count) {
delete buttons->widgetAt(index + 1); delete buttons->widgetAt(index + 1);
} }
@ -624,12 +645,8 @@ void ChooseAudioDeviceBox(
if (state->ignoreValueChange) { if (state->ignoreValueChange) {
return; return;
} }
const auto weak = Ui::MakeWeak(box);
const auto i = state->ids.find(value); const auto i = state->ids.find(value);
chosen((i != end(state->ids)) ? i->second : kDefaultDeviceId); choose((i != end(state->ids)) ? i->second : kDefaultDeviceId);
if (weak) {
box->closeBox();
}
}); });
} }