mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Cycle through repeat modes by repeat toggle button.
This commit is contained in:
parent
969b27cb75
commit
0309eb023e
5 changed files with 61 additions and 168 deletions
|
@ -97,21 +97,9 @@ mediaPlayerShuffleDisabledIconOver: icon {
|
|||
mediaPlayerRepeatReverseIcon: icon {
|
||||
{ "player/player_repeat_reverse", mediaPlayerActiveFg, point(9px, 11px)}
|
||||
};
|
||||
mediaPlayerRepeatReverseDisabledIcon: icon {
|
||||
{ "player/player_repeat_reverse", menuIconFg, point(9px, 11px)}
|
||||
};
|
||||
mediaPlayerRepeatReverseDisabledIconOver: icon {
|
||||
{ "player/player_repeat_reverse", menuIconFgOver, point(9px, 11px)}
|
||||
};
|
||||
mediaPlayerRepeatShuffleIcon: icon {
|
||||
{ "player/player_repeat_shuffle", mediaPlayerActiveFg, point(9px, 11px)}
|
||||
};
|
||||
mediaPlayerRepeatShuffleDisabledIcon: icon {
|
||||
{ "player/player_repeat_shuffle", menuIconFg, point(9px, 11px)}
|
||||
};
|
||||
mediaPlayerRepeatShuffleDisabledIconOver: icon {
|
||||
{ "player/player_repeat_shuffle", menuIconFgOver, point(9px, 11px)}
|
||||
};
|
||||
mediaPlayerRepeatDisabledRippleBg: windowBgOver;
|
||||
|
||||
mediaPlayerSpeedButton: IconButton {
|
||||
|
|
|
@ -121,6 +121,13 @@ Instance::Instance()
|
|||
handleSongUpdate(audioId);
|
||||
});
|
||||
|
||||
_songData.repeat.changes(
|
||||
) | rpl::start_with_next([=](RepeatMode mode) {
|
||||
if (mode == RepeatMode::All) {
|
||||
refreshPlaylist(&_songData);
|
||||
}
|
||||
}, _lifetime);
|
||||
|
||||
using namespace rpl::mappers;
|
||||
rpl::combine(
|
||||
Core::App().calls().currentCallValue(),
|
||||
|
@ -254,7 +261,13 @@ void Instance::clearStreamed(not_null<Data*> data, bool savePosition) {
|
|||
void Instance::refreshPlaylist(not_null<Data*> data) {
|
||||
if (!validPlaylist(data)) {
|
||||
validatePlaylist(data);
|
||||
} else if (!validOtherPlaylist(data)) {
|
||||
} else {
|
||||
refreshOtherPlaylist(data);
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::refreshOtherPlaylist(not_null<Data*> data) {
|
||||
if (!validOtherPlaylist(data)) {
|
||||
validateOtherPlaylist(data);
|
||||
}
|
||||
playlistUpdated(data);
|
||||
|
@ -322,12 +335,12 @@ void Instance::validatePlaylist(not_null<Data*> data) {
|
|||
) | rpl::start_with_next([=](SparseIdsMergedSlice &&update) {
|
||||
data->playlistSlice = std::move(update);
|
||||
data->playlistSliceKey = key;
|
||||
playlistUpdated(data);
|
||||
refreshOtherPlaylist(data);
|
||||
}, data->playlistLifetime);
|
||||
} else {
|
||||
data->playlistSlice = std::nullopt;
|
||||
data->playlistSliceKey = data->playlistRequestedKey = std::nullopt;
|
||||
playlistUpdated(data);
|
||||
refreshOtherPlaylist(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,7 +469,14 @@ bool Instance::moveInPlaylist(
|
|||
};
|
||||
const auto newIndex = *data->playlistIndex
|
||||
+ (data->order.current() == OrderMode::Reverse ? -delta : delta);
|
||||
if (const auto item = itemByIndex(data, newIndex)) {
|
||||
const auto useIndex = (!data->playlistSlice
|
||||
|| data->playlistSlice->skippedAfter() != 0
|
||||
|| data->playlistSlice->skippedBefore() != 0
|
||||
|| !data->playlistSlice->size())
|
||||
? newIndex
|
||||
: ((newIndex + int(data->playlistSlice->size()))
|
||||
% int(data->playlistSlice->size()));
|
||||
if (const auto item = itemByIndex(data, useIndex)) {
|
||||
return jumpByItem(item);
|
||||
} else if (data->repeat.current() == RepeatMode::All
|
||||
&& data->playlistOtherSlice
|
||||
|
@ -740,23 +760,6 @@ void Instance::playPauseCancelClicked(AudioMsgId::Type type) {
|
|||
}
|
||||
}
|
||||
|
||||
void Instance::setRepeatMode(AudioMsgId::Type type, RepeatMode mode) {
|
||||
if (const auto data = getData(type)) {
|
||||
const auto otherNeeded = (mode == RepeatMode::All)
|
||||
&& (data->repeat.current() != RepeatMode::All);
|
||||
data->repeat = mode;
|
||||
if (otherNeeded) {
|
||||
refreshPlaylist(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::setOrderMode(AudioMsgId::Type type, OrderMode mode) {
|
||||
if (const auto data = getData(type)) {
|
||||
data->order = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::startSeeking(AudioMsgId::Type type) {
|
||||
if (auto data = getData(type)) {
|
||||
data->seeking = data->current;
|
||||
|
|
|
@ -116,50 +116,6 @@ public:
|
|||
return AudioMsgId();
|
||||
}
|
||||
|
||||
[[nodiscard]] RepeatMode repeatMode(AudioMsgId::Type type) const {
|
||||
if (const auto data = getData(type)) {
|
||||
return data->repeat.current();
|
||||
}
|
||||
return RepeatMode::None;
|
||||
}
|
||||
[[nodiscard]] rpl::producer<RepeatMode> repeatModeValue(
|
||||
AudioMsgId::Type type) const {
|
||||
if (const auto data = getData(type)) {
|
||||
return data->repeat.value();
|
||||
}
|
||||
return rpl::single(RepeatMode::None);
|
||||
}
|
||||
[[nodiscard]] rpl::producer<RepeatMode> repeatModeChanges(
|
||||
AudioMsgId::Type type) const {
|
||||
if (const auto data = getData(type)) {
|
||||
return data->repeat.changes();
|
||||
}
|
||||
return rpl::never<RepeatMode>();
|
||||
}
|
||||
void setRepeatMode(AudioMsgId::Type type, RepeatMode mode);
|
||||
|
||||
[[nodiscard]] OrderMode orderMode(AudioMsgId::Type type) const {
|
||||
if (const auto data = getData(type)) {
|
||||
return data->order.current();
|
||||
}
|
||||
return OrderMode::Default;
|
||||
}
|
||||
[[nodiscard]] rpl::producer<OrderMode> orderModeValue(
|
||||
AudioMsgId::Type type) const {
|
||||
if (const auto data = getData(type)) {
|
||||
return data->order.value();
|
||||
}
|
||||
return rpl::single(OrderMode::Default);
|
||||
}
|
||||
[[nodiscard]] rpl::producer<OrderMode> orderModeChanges(
|
||||
AudioMsgId::Type type) const {
|
||||
if (const auto data = getData(type)) {
|
||||
return data->order.changes();
|
||||
}
|
||||
return rpl::never<OrderMode>();
|
||||
}
|
||||
void setOrderMode(AudioMsgId::Type type, OrderMode mode);
|
||||
|
||||
[[nodiscard]] bool isSeeking(AudioMsgId::Type type) const {
|
||||
if (const auto data = getData(type)) {
|
||||
return (data->seeking == data->current);
|
||||
|
@ -268,6 +224,7 @@ private:
|
|||
|
||||
void setCurrent(const AudioMsgId &audioId);
|
||||
void refreshPlaylist(not_null<Data*> data);
|
||||
void refreshOtherPlaylist(not_null<Data*> data);
|
||||
std::optional<SliceKey> playlistKey(not_null<const Data*> data) const;
|
||||
bool validPlaylist(not_null<const Data*> data) const;
|
||||
void validatePlaylist(not_null<Data*> data);
|
||||
|
|
|
@ -70,22 +70,12 @@ void PrepareRepeatDropdown(not_null<Dropdown*> dropdown) {
|
|||
auto &settings = Core::App().settings();
|
||||
const auto active = (settings.playerRepeatMode() == mode);
|
||||
settings.setPlayerRepeatMode(active ? RepeatMode::None : mode);
|
||||
const auto type = AudioMsgId::Type::Song;
|
||||
instance()->setRepeatMode(type, settings.playerRepeatMode());
|
||||
if (!active) {
|
||||
instance()->setOrderMode(type, settings.playerOrderMode());
|
||||
}
|
||||
Core::App().saveSettingsDelayed();
|
||||
};
|
||||
const auto toggleOrder = [](OrderMode mode) {
|
||||
auto &settings = Core::App().settings();
|
||||
const auto active = (settings.playerOrderMode() == mode);
|
||||
settings.setPlayerOrderMode(active ? OrderMode::Default : mode);
|
||||
const auto type = AudioMsgId::Type::Song;
|
||||
instance()->setOrderMode(type, settings.playerOrderMode());
|
||||
if (!active) {
|
||||
instance()->setRepeatMode(type, settings.playerRepeatMode());
|
||||
}
|
||||
Core::App().saveSettingsDelayed();
|
||||
};
|
||||
repeatOne->setClickedCallback([=] { toggleRepeat(RepeatMode::One); });
|
||||
|
|
|
@ -292,31 +292,22 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> session)
|
|||
|
||||
rpl::combine(
|
||||
Core::App().settings().playerRepeatModeValue(),
|
||||
Core::App().settings().playerOrderModeValue(),
|
||||
instance()->repeatModeValue(AudioMsgId::Type::Song),
|
||||
instance()->orderModeValue(AudioMsgId::Type::Song)
|
||||
Core::App().settings().playerOrderModeValue()
|
||||
) | rpl::start_with_next([=] {
|
||||
updateRepeatToggleIcon();
|
||||
}, lifetime());
|
||||
|
||||
_repeatToggle->setClickedCallback([=] {
|
||||
const auto type = AudioMsgId::Type::Song;
|
||||
const auto repeat = Core::App().settings().playerRepeatMode();
|
||||
const auto order = Core::App().settings().playerOrderMode();
|
||||
const auto mayBeActive = (repeat != RepeatMode::None)
|
||||
|| (order != OrderMode::Default);
|
||||
const auto active = mayBeActive
|
||||
&& (repeat == instance()->repeatMode(type))
|
||||
&& (order == instance()->orderMode(type));
|
||||
if (!active && !mayBeActive) {
|
||||
Core::App().settings().setPlayerRepeatMode(RepeatMode::All);
|
||||
Core::App().saveSettingsDelayed();
|
||||
}
|
||||
instance()->setRepeatMode(type, active
|
||||
? RepeatMode::None
|
||||
: mayBeActive
|
||||
? repeat
|
||||
: RepeatMode::All);
|
||||
instance()->setOrderMode(type, active ? OrderMode::Default : order);
|
||||
auto &settings = Core::App().settings();
|
||||
settings.setPlayerRepeatMode([&] {
|
||||
switch (settings.playerRepeatMode()) {
|
||||
case RepeatMode::None: return RepeatMode::One;
|
||||
case RepeatMode::One: return RepeatMode::All;
|
||||
case RepeatMode::All: return RepeatMode::None;
|
||||
}
|
||||
Unexpected("Repeat mode in Settings.");
|
||||
}());
|
||||
Core::App().saveSettingsDelayed();
|
||||
});
|
||||
|
||||
_playbackSpeed->saved(
|
||||
|
@ -577,70 +568,34 @@ void Widget::updateRepeatToggleIcon() {
|
|||
const auto type = AudioMsgId::Type::Song;
|
||||
const auto repeat = Core::App().settings().playerRepeatMode();
|
||||
const auto order = Core::App().settings().playerOrderMode();
|
||||
const auto active = (repeat == instance()->repeatMode(type))
|
||||
&& (order == instance()->orderMode(type))
|
||||
&& (repeat != RepeatMode::None || order != OrderMode::Default);
|
||||
switch (repeat) {
|
||||
case RepeatMode::None:
|
||||
switch (order) {
|
||||
case OrderMode::Default:
|
||||
_repeatToggle->setIconOverride(
|
||||
&st::mediaPlayerRepeatDisabledIcon,
|
||||
&st::mediaPlayerRepeatDisabledIconOver);
|
||||
break;
|
||||
case OrderMode::Reverse:
|
||||
_repeatToggle->setIconOverride(
|
||||
(active
|
||||
? &st::mediaPlayerReverseIcon
|
||||
: &st::mediaPlayerReverseDisabledIcon),
|
||||
active ? nullptr : &st::mediaPlayerReverseDisabledIconOver);
|
||||
break;
|
||||
case OrderMode::Shuffle:
|
||||
_repeatToggle->setIconOverride(
|
||||
(active
|
||||
? &st::mediaPlayerShuffleIcon
|
||||
: &st::mediaPlayerShuffleDisabledIcon),
|
||||
active ? nullptr : &st::mediaPlayerShuffleDisabledIconOver);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RepeatMode::One:
|
||||
if (repeat == RepeatMode::None && order == OrderMode::Default) {
|
||||
_repeatToggle->setIconOverride(
|
||||
(active
|
||||
? &st::mediaPlayerRepeatOneIcon
|
||||
: &st::mediaPlayerRepeatOneDisabledIcon),
|
||||
active ? nullptr : &st::mediaPlayerRepeatOneDisabledIconOver);
|
||||
break;
|
||||
case RepeatMode::All:
|
||||
switch (order) {
|
||||
case OrderMode::Default:
|
||||
_repeatToggle->setIconOverride(
|
||||
(active ? nullptr : &st::mediaPlayerRepeatDisabledIcon),
|
||||
(active ? nullptr : &st::mediaPlayerRepeatDisabledIconOver));
|
||||
&st::mediaPlayerRepeatDisabledIcon,
|
||||
&st::mediaPlayerRepeatDisabledIconOver);
|
||||
_repeatToggle->setRippleColorOverride(
|
||||
&st::mediaPlayerRepeatDisabledRippleBg);
|
||||
return;
|
||||
}
|
||||
const auto &icon = [&]() -> const style::icon& {
|
||||
switch (repeat) {
|
||||
case RepeatMode::None:
|
||||
switch (order) {
|
||||
case OrderMode::Reverse: return st::mediaPlayerReverseIcon;
|
||||
case OrderMode::Shuffle: return st::mediaPlayerShuffleIcon;
|
||||
}
|
||||
break;
|
||||
case OrderMode::Reverse:
|
||||
_repeatToggle->setIconOverride(
|
||||
(active
|
||||
? &st::mediaPlayerRepeatReverseIcon
|
||||
: &st::mediaPlayerRepeatReverseDisabledIcon),
|
||||
(active
|
||||
? nullptr
|
||||
: &st::mediaPlayerRepeatReverseDisabledIconOver));
|
||||
break;
|
||||
case OrderMode::Shuffle:
|
||||
_repeatToggle->setIconOverride(
|
||||
(active
|
||||
? &st::mediaPlayerRepeatShuffleIcon
|
||||
: &st::mediaPlayerRepeatShuffleDisabledIcon),
|
||||
(active
|
||||
? nullptr
|
||||
: &st::mediaPlayerRepeatShuffleDisabledIconOver));
|
||||
case RepeatMode::One: return st::mediaPlayerRepeatOneIcon;
|
||||
case RepeatMode::All:
|
||||
switch (order) {
|
||||
case OrderMode::Default: return st::mediaPlayerRepeatButton.icon;
|
||||
case OrderMode::Reverse: return st::mediaPlayerRepeatReverseIcon;
|
||||
case OrderMode::Shuffle: return st::mediaPlayerRepeatShuffleIcon;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
_repeatToggle->setRippleColorOverride(
|
||||
active ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg);
|
||||
Unexpected("Repeat / order values in Settings.");
|
||||
}();
|
||||
_repeatToggle->setIconOverride(&icon);
|
||||
}
|
||||
|
||||
void Widget::checkForTypeChange() {
|
||||
|
|
Loading…
Add table
Reference in a new issue