diff --git a/bin/cloudbrowser/qml/ItemPage.qml b/bin/cloudbrowser/qml/ItemPage.qml index 8995391af119c1ca5d528c82f56c98431494decd..a0aad8cb95dfa18799b588ddb9d068c0f5f0fb20 100644 --- a/bin/cloudbrowser/qml/ItemPage.qml +++ b/bin/cloudbrowser/qml/ItemPage.qml @@ -13,6 +13,11 @@ Kirigami.ScrollablePage { anchors.fill: parent supportsRefreshing: true + onIsCurrentPageChanged: { + if (isCurrentPage) + root.selected_item = list_view.currentItem ? list_view.currentItem.item : null; + } + onRefreshingChanged: { if (refreshing) { list.update(cloud, item); @@ -114,14 +119,102 @@ Kirigami.ScrollablePage { visible: list_view.currentItem && list_view.currentItem.item.type !== "directory" && item.supports("download") iconName: "document-save" - text: "Download " + (list_view.currentItem ? list_view.currentItem.item.filename : "") + text: "Download" onTriggered: { download_dialog.filename = list_view.currentItem.item.filename; download_dialog.open(); } + }, + Kirigami.Action { + visible: list_view.currentItem + iconName: "help-about" + text: "File information" + onTriggered: { + file_info_sheet.open(); + } } ] + Kirigami.OverlaySheet { + id: file_info_sheet + Item { + implicitWidth: Math.min(page.width * 0.8, 400) + implicitHeight: childrenRect.height - 50 + Text { + id: file_name + width: parent.width + font.pointSize: 18 + padding: 10 + text: root.selected_item ? root.selected_item.filename : "" + elide: Text.ElideRight + wrapMode: Text.Wrap + } + Column { + anchors.top: file_name.bottom + width: parent.implicitWidth * 0.8 + anchors.horizontalCenter: parent.horizontalCenter + Rectangle { + width: parent.width + height: childrenRect.height + border.width: 1 + anchors.leftMargin: 10 + Column { + width: parent.width + Item { + visible: root.selected_item ? root.selected_item.size !== -1 : "" + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 10 + height: 50 + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + font.pointSize: 12 + text: "size" + } + Text { + function show_size(size) { + if (size < 1024) + return size + " B"; + else if (size < 1024 * 1024) + return (size / 1024).toFixed(2) + " KB"; + else if (size < 1024 * 1024 * 1024) + return (size / (1024 * 1024)).toFixed(2) + " MB"; + else + return (size / (1024 * 1024 * 1024)).toFixed(2) + " GB"; + } + + font.pointSize: 16 + text: root.selected_item ? show_size(root.selected_item.size) : "" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + } + } + Item { + visible: root.selected_item ? root.selected_item.timestamp !== "" : false + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 10 + height: 50 + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + font.pointSize: 12 + text: "last modified" + } + Text { + font.pointSize: 16 + text: root.selected_item ? root.selected_item.timestamp : "" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + } + } + } + } + } + } + } + Kirigami.OverlaySheet { id: create_directory_sheet ColumnLayout { @@ -221,6 +314,7 @@ Kirigami.ScrollablePage { id: list_view model: list.list currentIndex: -1 + onCurrentItemChanged: root.selected_item = currentItem.item onCurrentIndexChanged: currentEdit = -1 footerPositioning: ListView.OverlayFooter footer: Kirigami.ItemViewHeader { diff --git a/bin/cloudbrowser/qml/main.qml b/bin/cloudbrowser/qml/main.qml index 38a97ac747188d55a7a8ef2b118414b569227e71..729bd3e8ada0a68f6d02a4cfac779a1ce6afe5bc 100644 --- a/bin/cloudbrowser/qml/main.qml +++ b/bin/cloudbrowser/qml/main.qml @@ -16,6 +16,7 @@ Kirigami.ApplicationWindow { property real last_volume: 1 property int player_count: 0 property int footer_height: ad_loaded && ad_visible ? 50 : 0 + property CloudItem selected_item id: root width: Math.min(800, screen.desktopAvailableWidth) @@ -188,6 +189,9 @@ Kirigami.ApplicationWindow { id: contextDrawer height: parent.height - footer_height handle.anchors.bottomMargin: footer_height + title: selected_item ? + selected_item.filename : + "Actions" } pageStack.initialPage: mainPageComponent pageStack.interactive: !visible_player diff --git a/bin/cloudbrowser/src/CloudItem.cpp b/bin/cloudbrowser/src/CloudItem.cpp index 4e451a12e569809d89a9b4b1868f2af51fe7a990..bceff530fcfbd36e25f2718fac75a092b98e27db 100644 --- a/bin/cloudbrowser/src/CloudItem.cpp +++ b/bin/cloudbrowser/src/CloudItem.cpp @@ -2,6 +2,8 @@ #include "Request/ListDirectory.h" +#include + #undef CreateDirectory using namespace cloudstorage; @@ -11,6 +13,24 @@ CloudItem::CloudItem(const Provider& p, IItem::Pointer item, QObject* parent) QString CloudItem::filename() const { return item_->filename().c_str(); } +qint64 CloudItem::size() const { + if (item_->size() == IItem::UnknownSize) + return -1; + else + return static_cast(item_->size()); +} + +QString CloudItem::timestamp() const { + if (item_->timestamp() == IItem::UnknownTimeStamp) + return ""; + else { + auto timestamp = std::chrono::system_clock::to_time_t(item_->timestamp()); + QDateTime date; + date.setTime_t(timestamp); + return date.toString(Qt::SystemLocaleShortDate); + } +} + QString CloudItem::type() const { switch (item_->type()) { case IItem::FileType::Unknown: diff --git a/bin/cloudbrowser/src/CloudItem.h b/bin/cloudbrowser/src/CloudItem.h index d2902b4ef0dda3eaadd6cc93ea147765f008c0b6..e72a147354d7e2c39b6030ef65b41a6eeb0b7797 100644 --- a/bin/cloudbrowser/src/CloudItem.h +++ b/bin/cloudbrowser/src/CloudItem.h @@ -23,7 +23,8 @@ struct Provider { class CloudItem : public QObject { public: Q_PROPERTY(QString filename READ filename CONSTANT) - Q_PROPERTY(uint64_t size READ size CONSTANT) + Q_PROPERTY(qint64 size READ size CONSTANT) + Q_PROPERTY(QString timestamp READ timestamp CONSTANT) Q_PROPERTY(QString type READ type CONSTANT) CloudItem(const Provider&, cloudstorage::IItem::Pointer, @@ -32,7 +33,8 @@ class CloudItem : public QObject { cloudstorage::IItem::Pointer item() const { return item_; } const Provider& provider() const { return provider_; } QString filename() const; - uint64_t size() const { return item_->size(); } + qint64 size() const; + QString timestamp() const; QString type() const; Q_INVOKABLE bool supports(QString operation) const; ListDirectoryCacheKey key() const; diff --git a/src/Utility/Item.cpp b/src/Utility/Item.cpp index b10518c8d9c0013a952b9c895e5fe382fbe73f8c..6d14677d05e8366e510a517c45cc6b7890f404b3 100644 --- a/src/Utility/Item.cpp +++ b/src/Utility/Item.cpp @@ -44,7 +44,7 @@ namespace cloudstorage { constexpr size_t IItem::UnknownSize; const IItem::TimeStamp IItem::UnknownTimeStamp = - std::chrono::system_clock::time_point::min(); + std::chrono::system_clock::from_time_t(0); namespace { bool find(const std::string* array, int length, std::string str) { @@ -90,8 +90,8 @@ std::string Item::toString() const { json["filename"] = filename(); json["type"] = static_cast(type()); json["id"] = id(); - json["timestamp"] = - static_cast(timestamp().time_since_epoch().count()); + json["timestamp"] = static_cast( + std::chrono::system_clock::to_time_t(timestamp())); json["size"] = static_cast(size()); if (!mime_type().empty()) json["mime_type"] = mime_type(); if (!parents().empty()) { @@ -110,8 +110,7 @@ IItem::Pointer IItem::fromString(const std::string& str) { auto item = util::make_unique( json["filename"].asString(), json["id"].asString(), json["size"].asInt64(), - std::chrono::system_clock::time_point( - std::chrono::seconds(json["timestamp"].asUInt64())), + std::chrono::system_clock::from_time_t(json["timestamp"].asUInt64()), static_cast(json["type"].asInt())); item->set_thumbnail_url(json["thumbnail_url"].asString()); item->set_hidden(json["hidden"].asBool());