From 5d94c0a7d44a2255b81815a52a7056a94a39842d Mon Sep 17 00:00:00 2001 From: nippy Date: Sat, 18 Apr 2026 13:49:56 +0200 Subject: update Raveos themes --- .../quickshell/Modals/FileBrowser/FileInfo.qml | 237 +++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml') diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml new file mode 100644 index 0000000..c41f039 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modals/FileBrowser/FileInfo.qml @@ -0,0 +1,237 @@ +import QtQuick +import QtCore +import Quickshell.Io +import qs.Common +import qs.Widgets + +Rectangle { + id: root + + property bool showFileInfo: false + property int selectedIndex: -1 + property var sourceFolderModel: null + property string currentPath: "" + + height: 200 + radius: Theme.cornerRadius + color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) + border.color: Theme.secondary + border.width: 2 + opacity: showFileInfo ? 1 : 0 + z: 100 + + onShowFileInfoChanged: { + if (showFileInfo && currentFileName && currentPath) { + const fullPath = currentPath + "/" + currentFileName + fileStatProcess.selectedFilePath = fullPath + fileStatProcess.running = true + } + } + + Process { + id: fileStatProcess + command: ["stat", "-c", "%y|%A|%s|%n", selectedFilePath] + property string selectedFilePath: "" + property var fileStats: null + running: false + + stdout: StdioCollector { + onStreamFinished: { + if (text && text.trim()) { + const parts = text.trim().split('|') + if (parts.length >= 4) { + fileStatProcess.fileStats = { + "modifiedTime": parts[0], + "permissions": parts[1], + "size": parseInt(parts[2]) || 0, + "fullPath": parts[3] + } + } + } + } + } + + onExited: function (exitCode) {} + } + + property string currentFileName: "" + property bool currentFileIsDir: false + property string currentFileExtension: "" + + onCurrentFileNameChanged: { + if (showFileInfo && currentFileName && currentPath) { + const fullPath = currentPath + "/" + currentFileName + if (fullPath !== fileStatProcess.selectedFilePath) { + fileStatProcess.selectedFilePath = fullPath + fileStatProcess.running = true + } + } + } + + function updateFileInfo(filePath, fileName, isDirectory) { + if (filePath && filePath !== fileStatProcess.selectedFilePath) { + fileStatProcess.selectedFilePath = filePath + currentFileName = fileName || "" + currentFileIsDir = isDirectory || false + + let ext = "" + if (!isDirectory && fileName) { + const lastDot = fileName.lastIndexOf('.') + if (lastDot > 0) { + ext = fileName.substring(lastDot + 1).toLowerCase() + } + } + currentFileExtension = ext + + if (showFileInfo) { + fileStatProcess.running = true + } + } + } + + readonly property var currentFileDisplayData: { + if (selectedIndex < 0 || !sourceFolderModel) { + return { + "exists": false, + "name": "No selection", + "type": "", + "size": "", + "modified": "", + "permissions": "", + "extension": "", + "position": "N/A" + } + } + + const hasValidFile = currentFileName !== "" + return { + "exists": hasValidFile, + "name": hasValidFile ? currentFileName : "Loading...", + "type": currentFileIsDir ? "Directory" : "File", + "size": fileStatProcess.fileStats ? formatFileSize(fileStatProcess.fileStats.size) : "Calculating...", + "modified": fileStatProcess.fileStats ? formatDateTime(fileStatProcess.fileStats.modifiedTime) : "Loading...", + "permissions": fileStatProcess.fileStats ? fileStatProcess.fileStats.permissions : "Loading...", + "extension": currentFileExtension, + "position": sourceFolderModel ? ((selectedIndex + 1) + " of " + sourceFolderModel.count) : "N/A" + } + } + + Column { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Theme.spacingM + spacing: Theme.spacingXS + + Row { + width: parent.width + spacing: Theme.spacingS + + DankIcon { + name: "info" + size: Theme.iconSize + color: Theme.secondary + } + + StyledText { + text: I18n.tr("File Information") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + font.weight: Font.Medium + anchors.verticalCenter: parent.verticalCenter + } + } + + Column { + width: parent.width + spacing: Theme.spacingXS + + StyledText { + text: currentFileDisplayData.name + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + width: parent.width + elide: Text.ElideMiddle + wrapMode: Text.NoWrap + font.weight: Font.Medium + } + + StyledText { + text: currentFileDisplayData.type + (currentFileDisplayData.extension ? " (." + currentFileDisplayData.extension + ")" : "") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceTextMedium + width: parent.width + } + + StyledText { + text: currentFileDisplayData.size + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceTextMedium + width: parent.width + visible: currentFileDisplayData.exists && !currentFileIsDir + } + + StyledText { + text: currentFileDisplayData.modified + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceTextMedium + width: parent.width + elide: Text.ElideRight + visible: currentFileDisplayData.exists + } + + StyledText { + text: currentFileDisplayData.permissions + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceTextMedium + visible: currentFileDisplayData.exists + } + + StyledText { + text: currentFileDisplayData.position + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceTextMedium + width: parent.width + } + } + } + + StyledText { + text: I18n.tr("F1/I: Toggle • F10: Help") + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceTextMedium + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: Theme.spacingM + horizontalAlignment: Text.AlignHCenter + } + + function formatFileSize(bytes) { + if (bytes === 0 || !bytes) { + return "0 B" + } + const k = 1024 + const sizes = ['B', 'KB', 'MB', 'GB', 'TB'] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i] + } + + function formatDateTime(dateTimeString) { + if (!dateTimeString) { + return "Unknown" + } + const parts = dateTimeString.split(' ') + if (parts.length >= 2) { + return parts[0] + " " + parts[1].split('.')[0] + } + return dateTimeString + } + + Behavior on opacity { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } +} -- cgit v1.3