mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-19 06:26:55 +00:00
Allow changing limits for cache in Settings.
This commit is contained in:
parent
5733f4079f
commit
069232ec1b
@ -366,6 +366,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_local_storage_round#other" = "{count} video messages";
|
||||
"lng_local_storage_animation#one" = "{count} animation";
|
||||
"lng_local_storage_animation#other" = "{count} animations";
|
||||
"lng_local_storage_size_limit" = "Total size limit: {size}";
|
||||
"lng_local_storage_time_limit" = "Clear files older than: {limit}";
|
||||
"lng_local_storage_limit_weeks#one" = "{count} week";
|
||||
"lng_local_storage_limit_weeks#other" = "{count} weeks";
|
||||
"lng_local_storage_limit_months#one" = "{count} month";
|
||||
"lng_local_storage_limit_months#other" = "{count} months";
|
||||
"lng_local_storage_limit_never" = "Never";
|
||||
"lng_local_storage_summary" = "Summary";
|
||||
"lng_local_storage_clear_some" = "Clear";
|
||||
"lng_local_storage_clear" = "Clear all";
|
||||
|
@ -355,7 +355,7 @@ peerListBox: PeerList(defaultPeerList) {
|
||||
}
|
||||
|
||||
localStorageRowHeight: 50px;
|
||||
localStorageRowPadding: margins(23px, 5px, 23px, 5px);
|
||||
localStorageRowPadding: margins(23px, 5px, 20px, 5px);
|
||||
localStorageRowTitle: FlatLabel(defaultFlatLabel) {
|
||||
textFg: windowBoldFg;
|
||||
maxHeight: 20px;
|
||||
@ -375,6 +375,14 @@ localStorageRowSize: FlatLabel(defaultFlatLabel) {
|
||||
}
|
||||
}
|
||||
localStorageClear: defaultBoxButton;
|
||||
localStorageLimitLabel: LabelSimple(defaultLabelSimple) {
|
||||
font: boxTextFont;
|
||||
}
|
||||
localStorageLimitLabelMargin: margins(23px, 10px, 20px, 5px);
|
||||
localStorageLimitSlider: MediaSlider(defaultContinuousSlider) {
|
||||
seekSize: size(15px, 15px);
|
||||
}
|
||||
localStorageLimitMargin: margins(23px, 5px, 20px, 10px);
|
||||
|
||||
shareRowsTop: 12px;
|
||||
shareRowHeight: 108px;
|
||||
|
@ -12,14 +12,97 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/continuous_sliders.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "storage/cache/storage_cache_database.h"
|
||||
#include "data/data_session.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwindow.h"
|
||||
#include "auth_session.h"
|
||||
#include "layout.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kSizeLimitsCount = 20;
|
||||
constexpr auto kTimeLimitsCount = 16;
|
||||
constexpr auto kMaxTimeLimitValue = std::numeric_limits<size_type>::max();
|
||||
|
||||
int64 SizeLimitInMB(int index) {
|
||||
if (index < 10) {
|
||||
return int64(index + 1) * 100;
|
||||
}
|
||||
return int64(index - 9) * 1024;
|
||||
}
|
||||
|
||||
int64 SizeLimit(int index) {
|
||||
return SizeLimitInMB(index) * 1024 * 1024;
|
||||
}
|
||||
|
||||
QString SizeLimitText(int64 limit) {
|
||||
const auto mb = (limit / (1024 * 1024));
|
||||
const auto gb = (mb / 1024);
|
||||
return (gb > 0)
|
||||
? (QString::number(gb) + " GB")
|
||||
: (QString::number(mb) + " MB");
|
||||
}
|
||||
|
||||
size_type TimeLimitInDays(int index) {
|
||||
if (index < 3) {
|
||||
const auto weeks = (index + 1);
|
||||
return size_type(weeks) * 7;
|
||||
} else if (index < 15) {
|
||||
const auto month = (index - 2);
|
||||
return (size_type(month) * 30)
|
||||
+ ((month >= 12) ? 5 :
|
||||
(month >= 10) ? 4 :
|
||||
(month >= 8) ? 3 :
|
||||
(month >= 7) ? 2 :
|
||||
(month >= 5) ? 1 :
|
||||
(month >= 3) ? 0 :
|
||||
(month >= 2) ? -1 :
|
||||
(month >= 1) ? 1 : 0);
|
||||
//+ (month >= 1 ? 1 : 0)
|
||||
//- (month >= 2 ? 2 : 0)
|
||||
//+ (month >= 3 ? 1 : 0)
|
||||
//+ (month >= 5 ? 1 : 0)
|
||||
//+ (month >= 7 ? 1 : 0)
|
||||
//+ (month >= 8 ? 1 : 0)
|
||||
//+ (month >= 10 ? 1 : 0)
|
||||
//+ (month >= 12 ? 1 : 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_type TimeLimit(int index) {
|
||||
const auto days = TimeLimitInDays(index);
|
||||
return days
|
||||
? (days * 24 * 60 * 60)
|
||||
: kMaxTimeLimitValue;
|
||||
}
|
||||
|
||||
QString TimeLimitText(size_type limit) {
|
||||
const auto days = (limit / (24 * 60 * 60));
|
||||
const auto weeks = (days / 7);
|
||||
const auto months = (days / 29);
|
||||
return (months > 0)
|
||||
? lng_local_storage_limit_months(lt_count, months)
|
||||
: (limit > 0)
|
||||
? lng_local_storage_limit_weeks(lt_count, weeks)
|
||||
: lang(lng_local_storage_limit_never);
|
||||
}
|
||||
|
||||
size_type LimitToValue(size_type timeLimit) {
|
||||
return timeLimit ? timeLimit : kMaxTimeLimitValue;
|
||||
}
|
||||
|
||||
size_type ValueToLimit(size_type timeLimit) {
|
||||
return (timeLimit != kMaxTimeLimitValue) ? timeLimit : 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class LocalStorageBox::Row : public Ui::RpWidget {
|
||||
public:
|
||||
Row(
|
||||
@ -134,7 +217,7 @@ int LocalStorageBox::Row::resizeGetHeight(int newWidth) {
|
||||
newWidth);
|
||||
}
|
||||
_clear->moveToRight(
|
||||
st::boxButtonPadding.right(),
|
||||
st::boxLayerButtonPadding.right(),
|
||||
(height - _clear->height()) / 2,
|
||||
newWidth);
|
||||
return height;
|
||||
@ -174,6 +257,9 @@ LocalStorageBox::LocalStorageBox(
|
||||
not_null<Database*> db,
|
||||
CreateTag)
|
||||
: _db(db) {
|
||||
const auto &settings = Local::cacheSettings();
|
||||
_sizeLimit = settings.totalSizeLimit;
|
||||
_timeLimit = settings.totalTimeLimit;
|
||||
}
|
||||
|
||||
void LocalStorageBox::Show(not_null<Database*> db) {
|
||||
@ -234,17 +320,17 @@ void LocalStorageBox::clearByTag(uint8 tag) {
|
||||
}
|
||||
|
||||
void LocalStorageBox::setupControls() {
|
||||
_content.create(this);
|
||||
|
||||
const auto container = setInnerWidget(
|
||||
object_ptr<Ui::VerticalLayout>(this));
|
||||
const auto createRow = [&](
|
||||
uint8 tag,
|
||||
Fn<QString(size_type)> title,
|
||||
Fn<QString()> clear,
|
||||
const Database::TaggedSummary &data) {
|
||||
auto result = _content->add(object_ptr<Ui::SlideWrap<Row>>(
|
||||
_content,
|
||||
auto result = container->add(object_ptr<Ui::SlideWrap<Row>>(
|
||||
container,
|
||||
object_ptr<Row>(
|
||||
_content,
|
||||
container,
|
||||
std::move(title),
|
||||
std::move(clear),
|
||||
data)));
|
||||
@ -280,11 +366,11 @@ void LocalStorageBox::setupControls() {
|
||||
std::move(summaryTitle),
|
||||
langFactory(lng_local_storage_clear),
|
||||
_stats.full);
|
||||
const auto shadow = _content->add(object_ptr<Ui::SlideWrap<>>(
|
||||
_content,
|
||||
object_ptr<Ui::PlainShadow>(_content),
|
||||
st::localStorageRowPadding)
|
||||
);
|
||||
setupLimits(container);
|
||||
const auto shadow = container->add(object_ptr<Ui::SlideWrap<>>(
|
||||
container,
|
||||
object_ptr<Ui::PlainShadow>(container),
|
||||
st::localStorageRowPadding));
|
||||
createTagRow(Data::kImageCacheTag, lng_local_storage_image);
|
||||
createTagRow(Data::kStickerCacheTag, lng_local_storage_sticker);
|
||||
createTagRow(Data::kVoiceMessageCacheTag, lng_local_storage_voice);
|
||||
@ -293,11 +379,98 @@ void LocalStorageBox::setupControls() {
|
||||
shadow->toggleOn(
|
||||
std::move(tracker).atLeastOneShownValue()
|
||||
);
|
||||
_content->resizeToWidth(st::boxWidth);
|
||||
_content->heightValue(
|
||||
container->resizeToWidth(st::boxWidth);
|
||||
container->heightValue(
|
||||
) | rpl::start_with_next([=](int height) {
|
||||
setDimensions(st::boxWidth, height);
|
||||
}, _content->lifetime());
|
||||
}, container->lifetime());
|
||||
}
|
||||
|
||||
template <
|
||||
typename Value,
|
||||
typename Convert,
|
||||
typename Callback,
|
||||
typename>
|
||||
void LocalStorageBox::createLimitsSlider(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
int valuesCount,
|
||||
Convert &&convert,
|
||||
Value currentValue,
|
||||
Callback &&callback) {
|
||||
const auto label = container->add(
|
||||
object_ptr<Ui::LabelSimple>(container, st::localStorageLimitLabel),
|
||||
st::localStorageLimitLabelMargin);
|
||||
callback(label, currentValue);
|
||||
const auto slider = container->add(
|
||||
object_ptr<Ui::MediaSlider>(container, st::localStorageLimitSlider),
|
||||
st::localStorageLimitMargin);
|
||||
slider->resize(st::localStorageLimitSlider.seekSize);
|
||||
slider->setPseudoDiscrete(
|
||||
valuesCount,
|
||||
std::forward<Convert>(convert),
|
||||
currentValue,
|
||||
[=, callback = std::forward<Callback>(callback)](Value value) {
|
||||
callback(label, value);
|
||||
});
|
||||
}
|
||||
|
||||
void LocalStorageBox::setupLimits(not_null<Ui::VerticalLayout*> container) {
|
||||
const auto shadow = container->add(
|
||||
object_ptr<Ui::PlainShadow>(container),
|
||||
st::localStorageRowPadding);
|
||||
|
||||
createLimitsSlider(
|
||||
container,
|
||||
kSizeLimitsCount,
|
||||
SizeLimit,
|
||||
_sizeLimit,
|
||||
[=](not_null<Ui::LabelSimple*> label, int64 limit) {
|
||||
const auto text = SizeLimitText(limit);
|
||||
label->setText(lng_local_storage_size_limit(lt_size, text));
|
||||
_sizeLimit = limit;
|
||||
limitsChanged();
|
||||
});
|
||||
|
||||
createLimitsSlider(
|
||||
container,
|
||||
kTimeLimitsCount,
|
||||
TimeLimit,
|
||||
LimitToValue(_timeLimit),
|
||||
[=](not_null<Ui::LabelSimple*> label, size_type limit) {
|
||||
const auto text = TimeLimitText(ValueToLimit(limit));
|
||||
label->setText(lng_local_storage_time_limit(lt_limit, text));
|
||||
_timeLimit = limit;
|
||||
limitsChanged();
|
||||
});
|
||||
}
|
||||
|
||||
void LocalStorageBox::limitsChanged() {
|
||||
const auto &settings = Local::cacheSettings();
|
||||
const auto changed = (settings.totalSizeLimit != _sizeLimit)
|
||||
|| (settings.totalTimeLimit != _timeLimit);
|
||||
if (_limitsChanged != changed) {
|
||||
_limitsChanged = changed;
|
||||
clearButtons();
|
||||
if (_limitsChanged) {
|
||||
addButton(langFactory(lng_settings_save), [=] { save(); });
|
||||
addButton(langFactory(lng_cancel), [=] { closeBox(); });
|
||||
} else {
|
||||
addButton(langFactory(lng_box_ok), [=] { closeBox(); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalStorageBox::save() {
|
||||
if (!_limitsChanged) {
|
||||
closeBox();
|
||||
return;
|
||||
}
|
||||
auto update = Storage::Cache::Database::SettingsUpdate();
|
||||
update.totalSizeLimit = _sizeLimit;
|
||||
update.totalTimeLimit = _timeLimit;
|
||||
Local::updateCacheSettings(update);
|
||||
Auth().data().cache().updateSettings(update);
|
||||
closeBox();
|
||||
}
|
||||
|
||||
void LocalStorageBox::paintEvent(QPaintEvent *e) {
|
||||
|
@ -20,6 +20,7 @@ namespace Ui {
|
||||
class VerticalLayout;
|
||||
template <typename Widget>
|
||||
class SlideWrap;
|
||||
class LabelSimple;
|
||||
} // namespace Ui
|
||||
|
||||
class LocalStorageBox : public BoxContent {
|
||||
@ -47,11 +48,34 @@ private:
|
||||
not_null<Ui::SlideWrap<Row>*> row,
|
||||
Database::TaggedSummary *data);
|
||||
void setupControls();
|
||||
void setupLimits(not_null<Ui::VerticalLayout*> container);
|
||||
void limitsChanged();
|
||||
void save();
|
||||
|
||||
template <
|
||||
typename Value,
|
||||
typename Convert,
|
||||
typename Callback,
|
||||
typename = std::enable_if_t<
|
||||
rpl::details::is_callable_plain_v<
|
||||
Callback,
|
||||
not_null<Ui::LabelSimple*>,
|
||||
Value>
|
||||
&& std::is_same_v<Value, decltype(std::declval<Convert>()(1))>>>
|
||||
void createLimitsSlider(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
int valuesCount,
|
||||
Convert &&convert,
|
||||
Value currentValue,
|
||||
Callback &&callback);
|
||||
|
||||
not_null<Storage::Cache::Database*> _db;
|
||||
Database::Stats _stats;
|
||||
|
||||
object_ptr<Ui::VerticalLayout> _content = { nullptr };
|
||||
base::flat_map<uint8, not_null<Ui::SlideWrap<Row>*>> _rows;
|
||||
|
||||
int64 _sizeLimit = 0;
|
||||
size_type _timeLimit = 0;
|
||||
bool _limitsChanged = false;
|
||||
|
||||
};
|
||||
|
@ -21,16 +21,8 @@ exportHeaderLabel: FlatLabel(boxTitle) {
|
||||
}
|
||||
}
|
||||
exportHeaderPadding: margins(22px, 20px, 22px, 9px);
|
||||
exportFileSizeSlider: MediaSlider {
|
||||
width: 3px;
|
||||
activeFg: mediaPlayerActiveFg;
|
||||
inactiveFg: mediaPlayerInactiveFg;
|
||||
activeFgOver: mediaPlayerActiveFg;
|
||||
inactiveFgOver: mediaPlayerInactiveFg;
|
||||
activeFgDisabled: mediaPlayerInactiveFg;
|
||||
inactiveFgDisabled: windowBg;
|
||||
exportFileSizeSlider: MediaSlider(defaultContinuousSlider) {
|
||||
seekSize: size(15px, 15px);
|
||||
duration: 150;
|
||||
}
|
||||
exportFileSizeLabel: LabelSimple(defaultLabelSimple) {
|
||||
font: boxTextFont;
|
||||
|
@ -469,27 +469,19 @@ void SettingsWidget::addSizeSlider(
|
||||
object_ptr<Ui::MediaSlider>(container, st::exportFileSizeSlider),
|
||||
st::exportFileSizePadding);
|
||||
slider->resize(st::exportFileSizeSlider.seekSize);
|
||||
slider->setAlwaysDisplayMarker(true);
|
||||
slider->setDirection(Ui::ContinuousSlider::Direction::Horizontal);
|
||||
for (auto i = 0; i != kSizeValueCount + 1; ++i) {
|
||||
if (readData().media.sizeLimit <= SizeLimitByIndex(i)) {
|
||||
slider->setValue(i / float64(kSizeValueCount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
slider->setPseudoDiscrete(
|
||||
kSizeValueCount + 1,
|
||||
SizeLimitByIndex,
|
||||
readData().media.sizeLimit,
|
||||
[=](int limit) {
|
||||
changeData([&](Settings &data) {
|
||||
data.media.sizeLimit = limit;
|
||||
});
|
||||
});
|
||||
|
||||
const auto label = Ui::CreateChild<Ui::LabelSimple>(
|
||||
container.get(),
|
||||
st::exportFileSizeLabel);
|
||||
slider->setAdjustCallback([=](float64 value) {
|
||||
return std::round(value * kSizeValueCount) / kSizeValueCount;
|
||||
});
|
||||
slider->setChangeProgressCallback([=](float64 value) {
|
||||
const auto index = int(std::round(value * kSizeValueCount));
|
||||
changeData([&](Settings &data) {
|
||||
data.media.sizeLimit = SizeLimitByIndex(index);
|
||||
});
|
||||
});
|
||||
value() | rpl::map([](const Settings &data) {
|
||||
return data.media.sizeLimit;
|
||||
}) | rpl::start_with_next([=](int sizeLimit) {
|
||||
@ -511,7 +503,6 @@ void SettingsWidget::addSizeSlider(
|
||||
st::exportFileSizePadding.right(),
|
||||
geometry.y() - label->height() - st::exportFileSizeLabelBottom);
|
||||
}, label->lifetime());
|
||||
|
||||
}
|
||||
|
||||
void SettingsWidget::refreshButtons(
|
||||
|
@ -193,17 +193,7 @@ mediaPlayerPanelPlaySkip: 7px;
|
||||
mediaPlayerPanelPlayTop: 58px;
|
||||
mediaPlayerPanelPlaybackTop: 32px;
|
||||
mediaPlayerPanelPlaybackPadding: 8px;
|
||||
mediaPlayerPanelPlayback: MediaSlider {
|
||||
width: 3px;
|
||||
activeFg: mediaPlayerActiveFg;
|
||||
inactiveFg: mediaPlayerInactiveFg;
|
||||
activeFgOver: mediaPlayerActiveFg;
|
||||
inactiveFgOver: mediaPlayerInactiveFg;
|
||||
activeFgDisabled: mediaPlayerInactiveFg;
|
||||
inactiveFgDisabled: windowBg;
|
||||
seekSize: size(9px, 9px);
|
||||
duration: 150;
|
||||
}
|
||||
mediaPlayerPanelPlayback: defaultContinuousSlider;
|
||||
|
||||
mediaPlayerPanelVolumeTop: 65px;
|
||||
mediaPlayerPanelVolumeSkip: 3px;
|
||||
|
@ -50,6 +50,7 @@ constexpr auto kSinglePeerTypeChannel = qint32(3);
|
||||
constexpr auto kSinglePeerTypeSelf = qint32(4);
|
||||
constexpr auto kSinglePeerTypeEmpty = qint32(0);
|
||||
|
||||
using Database = Storage::Cache::Database;
|
||||
using FileKey = quint64;
|
||||
|
||||
constexpr char tdfMagic[] = { 'T', 'D', 'F', '$' };
|
||||
@ -590,6 +591,7 @@ enum {
|
||||
dbiTxtDomainString = 0x53,
|
||||
dbiThemeKey = 0x54,
|
||||
dbiTileBackground = 0x55,
|
||||
dbiCacheSettings = 0x56,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
@ -647,6 +649,8 @@ bool _readingUserSettings = false;
|
||||
FileKey _userSettingsKey = 0;
|
||||
FileKey _recentHashtagsAndBotsKey = 0;
|
||||
bool _recentHashtagsAndBotsWereRead = false;
|
||||
qint64 _cacheTotalSizeLimit = Database::Settings().totalSizeLimit;
|
||||
qint32 _cacheTotalTimeLimit = Database::Settings().totalTimeLimit;
|
||||
|
||||
FileKey _exportSettingsKey = 0;
|
||||
|
||||
@ -1010,6 +1014,20 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||
cSetUseExternalVideoPlayer(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiCacheSettings: {
|
||||
qint64 size;
|
||||
qint32 time;
|
||||
stream >> size >> time;
|
||||
if (!_checkStreamStatus(stream)
|
||||
|| size <= Database::Settings().maxDataSize
|
||||
|| time < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_cacheTotalSizeLimit = size;
|
||||
_cacheTotalTimeLimit = time;
|
||||
}
|
||||
|
||||
case dbiSoundNotify: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
@ -1905,6 +1923,7 @@ void _writeUserSettings() {
|
||||
size += sizeof(quint32) + 3 * sizeof(qint32);
|
||||
size += sizeof(quint32) + 2 * sizeof(qint32);
|
||||
size += sizeof(quint32) + 2 * sizeof(qint32);
|
||||
size += sizeof(quint32) + sizeof(qint64) + sizeof(qint32);
|
||||
if (!Global::HiddenPinnedMessages().isEmpty()) {
|
||||
size += sizeof(quint32) + sizeof(qint32) + Global::HiddenPinnedMessages().size() * (sizeof(PeerId) + sizeof(MsgId));
|
||||
}
|
||||
@ -1940,6 +1959,7 @@ void _writeUserSettings() {
|
||||
data.stream << quint32(dbiModerateMode) << qint32(Global::ModerateModeEnabled() ? 1 : 0);
|
||||
data.stream << quint32(dbiAutoPlay) << qint32(cAutoPlayGif() ? 1 : 0);
|
||||
data.stream << quint32(dbiUseExternalVideoPlayer) << qint32(cUseExternalVideoPlayer());
|
||||
data.stream << quint32(dbiCacheSettings) << qint64(_cacheTotalSizeLimit) << qint32(_cacheTotalTimeLimit);
|
||||
if (!userData.isEmpty()) {
|
||||
data.stream << quint32(dbiAuthSessionSettings) << userData;
|
||||
}
|
||||
@ -2608,6 +2628,8 @@ void reset() {
|
||||
Window::Theme::Background()->reset();
|
||||
_userSettingsKey = _recentHashtagsAndBotsKey = _savedPeersKey = _exportSettingsKey = 0;
|
||||
_oldMapVersion = _oldSettingsVersion = 0;
|
||||
_cacheTotalSizeLimit = Database::Settings().totalSizeLimit;
|
||||
_cacheTotalTimeLimit = Database::Settings().totalTimeLimit;
|
||||
StoredAuthSessionCache.reset();
|
||||
_mapChanged = true;
|
||||
_writeMap(WriteMapWhen::Now);
|
||||
@ -2987,18 +3009,33 @@ QString cachePath() {
|
||||
return _userDbPath + "cache";
|
||||
}
|
||||
|
||||
Storage::Cache::Database::Settings cacheSettings() {
|
||||
auto result = Storage::Cache::Database::Settings();
|
||||
result.clearOnWrongKey = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
Storage::EncryptionKey cacheKey() {
|
||||
Expects(LocalKey != nullptr);
|
||||
|
||||
return Storage::EncryptionKey(bytes::make_vector(LocalKey->data()));
|
||||
}
|
||||
|
||||
Storage::Cache::Database::Settings cacheSettings() {
|
||||
auto result = Storage::Cache::Database::Settings();
|
||||
result.clearOnWrongKey = true;
|
||||
result.totalSizeLimit = _cacheTotalSizeLimit;
|
||||
result.totalTimeLimit = _cacheTotalTimeLimit;
|
||||
return result;
|
||||
}
|
||||
|
||||
void updateCacheSettings(Storage::Cache::Database::SettingsUpdate &update) {
|
||||
Expects(update.totalSizeLimit > Database::Settings().maxDataSize);
|
||||
Expects(update.totalTimeLimit >= 0);
|
||||
|
||||
if (_cacheTotalSizeLimit == update.totalSizeLimit
|
||||
&& _cacheTotalTimeLimit == update.totalTimeLimit) {
|
||||
return;
|
||||
}
|
||||
_cacheTotalSizeLimit = update.totalSizeLimit;
|
||||
_cacheTotalTimeLimit = update.totalTimeLimit;
|
||||
_writeUserSettings();
|
||||
}
|
||||
|
||||
class CountWaveformTask : public Task {
|
||||
public:
|
||||
CountWaveformTask(DocumentData *doc)
|
||||
|
@ -105,8 +105,9 @@ void writeFileLocation(MediaKey location, const FileLocation &local);
|
||||
FileLocation readFileLocation(MediaKey location, bool check = true);
|
||||
|
||||
QString cachePath();
|
||||
Storage::Cache::Database::Settings cacheSettings();
|
||||
Storage::EncryptionKey cacheKey();
|
||||
Storage::Cache::Database::Settings cacheSettings();
|
||||
void updateCacheSettings(Storage::Cache::Database::SettingsUpdate &update);
|
||||
|
||||
void countVoiceWaveform(DocumentData *document);
|
||||
|
||||
|
@ -130,6 +130,43 @@ public:
|
||||
}
|
||||
void disablePaint(bool disabled);
|
||||
|
||||
template <
|
||||
typename Value,
|
||||
typename Convert,
|
||||
typename Callback,
|
||||
typename = std::enable_if_t<
|
||||
rpl::details::is_callable_plain_v<Callback, Value>
|
||||
&& std::is_same_v<Value, decltype(std::declval<Convert>()(1))>>>
|
||||
void setPseudoDiscrete(
|
||||
int valuesCount,
|
||||
Convert &&convert,
|
||||
Value current,
|
||||
Callback &&callback) {
|
||||
Expects(valuesCount > 1);
|
||||
|
||||
setAlwaysDisplayMarker(true);
|
||||
setDirection(Ui::ContinuousSlider::Direction::Horizontal);
|
||||
|
||||
const auto sectionsCount = (valuesCount - 1);
|
||||
for (auto index = index_type(); index != valuesCount; ++index) {
|
||||
if (current <= convert(index)) {
|
||||
setValue(index / float64(sectionsCount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
setAdjustCallback([=](float64 value) {
|
||||
return std::round(value * sectionsCount) / sectionsCount;
|
||||
});
|
||||
setChangeProgressCallback([
|
||||
=,
|
||||
convert = std::forward<Convert>(convert),
|
||||
callback = std::forward<Callback>(callback)
|
||||
](float64 value) {
|
||||
const auto index = int(std::round(value * sectionsCount));
|
||||
callback(convert(index));
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
|
@ -888,6 +888,18 @@ defaultPanelAnimation: PanelAnimation {
|
||||
shadow: defaultRoundShadow;
|
||||
}
|
||||
|
||||
defaultContinuousSlider: MediaSlider {
|
||||
width: 3px;
|
||||
activeFg: mediaPlayerActiveFg;
|
||||
inactiveFg: mediaPlayerInactiveFg;
|
||||
activeFgOver: mediaPlayerActiveFg;
|
||||
inactiveFgOver: mediaPlayerInactiveFg;
|
||||
activeFgDisabled: mediaPlayerInactiveFg;
|
||||
inactiveFgDisabled: windowBg;
|
||||
seekSize: size(9px, 9px);
|
||||
duration: 150;
|
||||
}
|
||||
|
||||
defaultRoundCheckbox: RoundCheckbox {
|
||||
border: windowBg;
|
||||
bgActive: windowBgActive;
|
||||
|
Loading…
Reference in New Issue
Block a user