mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-09 21:23:43 +00:00
Added device storage usage line to local storage section.
This commit is contained in:
@@ -1150,6 +1150,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_local_storage_clear_some" = "Clear";
|
||||
"lng_local_storage_clear" = "Clear all";
|
||||
"lng_local_storage_clearing" = "Clearing...";
|
||||
"lng_local_storage_device_telegram" = "Telegram cache";
|
||||
"lng_local_storage_device_other" = "Other data";
|
||||
"lng_local_storage_device_free" = "Free";
|
||||
"lng_local_storage_device_total" = "Total";
|
||||
"lng_local_storage_device_usage" = "Telegram uses {percent} of your device storage.";
|
||||
|
||||
"lng_passcode_remove_button" = "Remove";
|
||||
|
||||
|
||||
@@ -238,6 +238,22 @@ localStorageParticleDocuments: icon{{ "local_storage/documents-72x72", windowFg
|
||||
localStorageParticleMusic: icon{{ "local_storage/music-72x72", windowFg }};
|
||||
localStorageParticleStickers: icon{{ "local_storage/stickers-72x72", windowFg }};
|
||||
|
||||
localStorageUsageTopSkip: 2px;
|
||||
localStorageUsageBarSkip: 9px;
|
||||
localStorageUsageBarWidth: 174px;
|
||||
localStorageUsageBarHeight: 4px;
|
||||
localStorageUsageBottomSkip: 6px;
|
||||
localStorageUsageBarMargin: margins(6px, 6px, 6px, 6px);
|
||||
localStorageUsageTooltipMaxWidth: 240px;
|
||||
localStorageUsageTooltipSkip: 8px;
|
||||
localStorageUsageSubtitle: FlatLabel(defaultFlatLabel) {
|
||||
textFg: windowSubTextFg;
|
||||
align: align(top);
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(13px);
|
||||
}
|
||||
}
|
||||
|
||||
shareRowsTop: 12px;
|
||||
shareRowHeight: 108px;
|
||||
sharePhotoTop: 6px;
|
||||
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "settings/sections/settings_local_storage.h"
|
||||
|
||||
#include "settings.h"
|
||||
#include "data/data_session.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
@@ -25,10 +26,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/emoji_config.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/rect.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/widgets/tooltip.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
#include <QtCore/QStorageInfo>
|
||||
|
||||
namespace Settings {
|
||||
namespace {
|
||||
|
||||
@@ -156,6 +162,32 @@ const QImage &ParticleImage(int index) {
|
||||
return image;
|
||||
}
|
||||
|
||||
[[nodiscard]] QString FormatStoragePercent(int64 part, int64 whole) {
|
||||
if (whole <= 0) {
|
||||
return u"0%"_q;
|
||||
}
|
||||
const auto ratio = part / float64(whole);
|
||||
if (ratio < 0.001) {
|
||||
return u"<0.1%"_q;
|
||||
}
|
||||
const auto percent = int(base::SafeRound(ratio * 100.));
|
||||
return (percent <= 0)
|
||||
? u"<1%"_q
|
||||
: (QString::number(percent) + '%');
|
||||
}
|
||||
|
||||
[[nodiscard]] QString FormatStorageSize(int64 size) {
|
||||
constexpr auto kGigabyte = int64(1024) * 1024 * 1024;
|
||||
if (size < kGigabyte) {
|
||||
return Ui::FormatSizeText(size);
|
||||
}
|
||||
const auto tenthGb = size * 10 / kGigabyte;
|
||||
return QString::number(tenthGb / 10)
|
||||
+ '.'
|
||||
+ QString::number(tenthGb % 10)
|
||||
+ u" GB"_q;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class LocalStorage::Chart final : public Ui::RpWidget {
|
||||
@@ -637,6 +669,192 @@ void LocalStorage::Chart::paintEvent(QPaintEvent *e) {
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
class LocalStorage::DeviceBar final : public Ui::RpWidget {
|
||||
public:
|
||||
explicit DeviceBar(QWidget *parent);
|
||||
|
||||
void setCache(int64 cache);
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void leaveEventHook(QEvent *e) override;
|
||||
|
||||
private:
|
||||
void refresh();
|
||||
void apply();
|
||||
[[nodiscard]] QRect barRect() const;
|
||||
[[nodiscard]] TextWithEntities tooltipText() const;
|
||||
void showTooltip();
|
||||
void hideTooltip();
|
||||
|
||||
object_ptr<Ui::FlatLabel> _subtitle;
|
||||
std::unique_ptr<Ui::ImportantTooltip> _tooltip;
|
||||
int64 _reported = 0;
|
||||
int64 _cache = 0;
|
||||
int64 _total = 0;
|
||||
int64 _free = 0;
|
||||
|
||||
};
|
||||
|
||||
LocalStorage::DeviceBar::DeviceBar(QWidget *parent)
|
||||
: RpWidget(parent)
|
||||
, _subtitle(this, QString(), st::localStorageUsageSubtitle) {
|
||||
_subtitle->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
setMouseTracking(true);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::refresh() {
|
||||
const auto weak = base::make_weak(this);
|
||||
const auto dir = cWorkingDir();
|
||||
crl::async([=] {
|
||||
const auto info = QStorageInfo(dir);
|
||||
const auto total = info.isValid() ? info.bytesTotal() : int64();
|
||||
const auto free = info.isValid() ? info.bytesAvailable() : int64();
|
||||
crl::on_main(weak, [=] {
|
||||
_total = total;
|
||||
_free = (free > total) ? total : free;
|
||||
apply();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::apply() {
|
||||
const auto used = std::max(_total - _free, int64());
|
||||
_cache = std::min(_reported, used);
|
||||
_subtitle->setText(tr::lng_local_storage_device_usage(
|
||||
tr::now,
|
||||
lt_percent,
|
||||
FormatStoragePercent(_cache, _total)));
|
||||
resizeToWidth(width());
|
||||
update();
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::setCache(int64 cache) {
|
||||
_reported = cache;
|
||||
apply();
|
||||
refresh();
|
||||
}
|
||||
|
||||
QRect LocalStorage::DeviceBar::barRect() const {
|
||||
const auto width = std::min(st::localStorageUsageBarWidth, QWidget::width());
|
||||
const auto top = st::localStorageUsageTopSkip
|
||||
+ _subtitle->height()
|
||||
+ st::localStorageUsageBarSkip;
|
||||
return QRect(
|
||||
(QWidget::width() - width) / 2,
|
||||
top,
|
||||
width,
|
||||
st::localStorageUsageBarHeight);
|
||||
}
|
||||
|
||||
int LocalStorage::DeviceBar::resizeGetHeight(int newWidth) {
|
||||
_subtitle->resizeToWidth(newWidth);
|
||||
_subtitle->moveToLeft(0, st::localStorageUsageTopSkip, newWidth);
|
||||
return st::localStorageUsageTopSkip
|
||||
+ _subtitle->height()
|
||||
+ st::localStorageUsageBarSkip
|
||||
+ st::localStorageUsageBarHeight
|
||||
+ st::localStorageUsageBottomSkip;
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::paintEvent(QPaintEvent *e) {
|
||||
if (_total <= 0) {
|
||||
return;
|
||||
}
|
||||
auto p = QPainter(this);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
|
||||
const auto bar = QRectF(barRect());
|
||||
const auto radius = bar.height() / 2.;
|
||||
const auto used = _total - _free;
|
||||
const auto cacheColor = st::activeButtonBg->c;
|
||||
const auto usedColor = st::windowSubTextFg->c;
|
||||
const auto freeColor = st::windowBg->c;
|
||||
|
||||
auto path = QPainterPath();
|
||||
path.addRoundedRect(bar, radius, radius);
|
||||
p.setClipPath(path);
|
||||
p.fillRect(bar, freeColor);
|
||||
|
||||
const auto fill = [&](int64 from, int64 size, QColor color) {
|
||||
if (size <= 0) {
|
||||
return;
|
||||
}
|
||||
const auto x1 = bar.x() + bar.width() * (from / float64(_total));
|
||||
const auto x2 = bar.x()
|
||||
+ bar.width() * ((from + size) / float64(_total));
|
||||
p.fillRect(QRectF(x1, bar.y(), x2 - x1, bar.height()), color);
|
||||
};
|
||||
fill(0, used, usedColor);
|
||||
fill(0, _cache, cacheColor);
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (_total > 0 && barRect().marginsAdded(st::localStorageUsageBarMargin)
|
||||
.contains(e->pos())) {
|
||||
showTooltip();
|
||||
} else {
|
||||
hideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::leaveEventHook(QEvent *e) {
|
||||
hideTooltip();
|
||||
}
|
||||
|
||||
TextWithEntities LocalStorage::DeviceBar::tooltipText() const {
|
||||
const auto used = _total - _free;
|
||||
const auto other = std::max(used - _cache, int64());
|
||||
auto result = TextWithEntities();
|
||||
const auto line = [&](const QString &label, int64 size) {
|
||||
if (!result.text.isEmpty()) {
|
||||
result.append('\n');
|
||||
}
|
||||
result.append(label).append(u": "_q).append(
|
||||
Ui::Text::Bold(FormatStorageSize(size)));
|
||||
};
|
||||
line(tr::lng_local_storage_device_telegram(tr::now), _cache);
|
||||
line(tr::lng_local_storage_device_other(tr::now), other);
|
||||
line(tr::lng_local_storage_device_free(tr::now), _free);
|
||||
line(tr::lng_local_storage_device_total(tr::now), _total);
|
||||
return result;
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::showTooltip() {
|
||||
if (_tooltip || _total <= 0) {
|
||||
return;
|
||||
}
|
||||
const auto parent = window();
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
_tooltip = std::make_unique<Ui::ImportantTooltip>(
|
||||
parent,
|
||||
Ui::MakeNiceTooltipLabel(
|
||||
parent,
|
||||
rpl::single(tooltipText()),
|
||||
st::localStorageUsageTooltipMaxWidth,
|
||||
st::defaultImportantTooltipLabel),
|
||||
st::defaultImportantTooltip);
|
||||
const auto tooltip = _tooltip.get();
|
||||
const auto weak = base::make_weak(tooltip);
|
||||
tooltip->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
tooltip->setHiddenCallback([=] { delete weak.get(); });
|
||||
auto area = Ui::MapFrom(parent, this, barRect());
|
||||
area.translate(0, -st::localStorageUsageTooltipSkip);
|
||||
tooltip->pointAt(area, RectPart::Top);
|
||||
tooltip->toggleAnimated(true);
|
||||
}
|
||||
|
||||
void LocalStorage::DeviceBar::hideTooltip() {
|
||||
if (const auto tooltip = _tooltip.release()) {
|
||||
tooltip->toggleAnimated(false);
|
||||
}
|
||||
}
|
||||
|
||||
class LocalStorage::Row : public Ui::RpWidget {
|
||||
public:
|
||||
Row(
|
||||
@@ -839,6 +1057,7 @@ void LocalStorage::update(
|
||||
}
|
||||
}
|
||||
updateChart();
|
||||
updateDeviceBar();
|
||||
}
|
||||
|
||||
void LocalStorage::updateChart() {
|
||||
@@ -860,6 +1079,12 @@ void LocalStorage::updateChart() {
|
||||
_chart->setParts(sizes, summary().totalSize);
|
||||
}
|
||||
|
||||
void LocalStorage::updateDeviceBar() {
|
||||
if (_deviceBar) {
|
||||
_deviceBar->setCache(summary().totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
auto LocalStorage::summary() const -> Database::TaggedSummary {
|
||||
auto result = _stats.full;
|
||||
result.count += _statsBig.full.count;
|
||||
@@ -940,7 +1165,9 @@ void LocalStorage::setupControls(not_null<Ui::VerticalLayout*> container) {
|
||||
return tr::lng_local_storage_media(tr::now);
|
||||
};
|
||||
_chart = container->add(object_ptr<Chart>(container));
|
||||
_deviceBar = container->add(object_ptr<DeviceBar>(container));
|
||||
updateChart();
|
||||
updateDeviceBar();
|
||||
createRow(
|
||||
0,
|
||||
std::move(summaryTitle),
|
||||
|
||||
@@ -50,9 +50,11 @@ public:
|
||||
private:
|
||||
class Row;
|
||||
class Chart;
|
||||
class DeviceBar;
|
||||
|
||||
void setupContent();
|
||||
void updateChart();
|
||||
void updateDeviceBar();
|
||||
void clearByTag(uint16 tag);
|
||||
void update(Database::Stats &&stats, Database::Stats &&statsBig);
|
||||
void updateRow(
|
||||
@@ -94,6 +96,7 @@ private:
|
||||
|
||||
base::flat_map<uint16, not_null<Ui::SlideWrap<Row>*>> _rows;
|
||||
Chart *_chart = nullptr;
|
||||
DeviceBar *_deviceBar = nullptr;
|
||||
Ui::MediaSlider *_totalSlider = nullptr;
|
||||
Ui::LabelSimple *_totalLabel = nullptr;
|
||||
Ui::MediaSlider *_mediaSlider = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user