forked from Shinonome/dots-hyprland
booru: fix 1image row width, add actions menu
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
import "root:/modules/common"
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
property string buttonText
|
||||||
|
implicitHeight: 36
|
||||||
|
implicitWidth: buttonTextWidget.implicitWidth + 14 * 2
|
||||||
|
|
||||||
|
PointingHandInteraction {}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: (button.down && button.enabled) ? Appearance.transparentize(Appearance.m3colors.m3onSurface, 0.84) :
|
||||||
|
((button.hovered && button.enabled) ? Appearance.transparentize(Appearance.m3colors.m3onSurface, 0.92) :
|
||||||
|
Appearance.transparentize(Appearance.m3colors.m3onSurface, 1))
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Appearance.animation.elementDecel.duration
|
||||||
|
easing.type: Appearance.animation.elementDecel.type
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: StyledText {
|
||||||
|
id: buttonTextWidget
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 14
|
||||||
|
anchors.rightMargin: 14
|
||||||
|
text: buttonText
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.small
|
||||||
|
color: button.enabled ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3outline
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Appearance.animation.elementDecel.duration
|
||||||
|
easing.type: Appearance.animation.elementDecel.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -112,10 +112,7 @@ Item {
|
|||||||
|
|
||||||
spacing: 10
|
spacing: 10
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
values: {
|
values: Booru.responses
|
||||||
console.log(JSON.stringify(Booru.responses))
|
|
||||||
return Booru.responses
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delegate: BooruResponse {
|
delegate: BooruResponse {
|
||||||
responseData: modelData
|
responseData: modelData
|
||||||
|
|||||||
@@ -229,4 +229,18 @@ Scope { // Scope
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlobalShortcut {
|
||||||
|
name: "sidebarLeftClose"
|
||||||
|
description: "Closes left sidebar on press"
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
for (let i = 0; i < sidebarVariants.instances.length; i++) {
|
||||||
|
let panelWindow = sidebarVariants.instances[i];
|
||||||
|
if (panelWindow.modelData.name == Hyprland.focusedMonitor.name) {
|
||||||
|
panelWindow.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ Button {
|
|||||||
property string nsfwPath
|
property string nsfwPath
|
||||||
property string fileName: decodeURIComponent((imageData.file_url).substring((imageData.file_url).lastIndexOf('/') + 1))
|
property string fileName: decodeURIComponent((imageData.file_url).substring((imageData.file_url).lastIndexOf('/') + 1))
|
||||||
|
|
||||||
|
property bool showActions: false
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: downloadProcess
|
id: downloadProcess
|
||||||
running: false
|
running: false
|
||||||
@@ -46,11 +48,7 @@ Button {
|
|||||||
implicitWidth: imageObject.width
|
implicitWidth: imageObject.width
|
||||||
implicitHeight: imageObject.height
|
implicitHeight: imageObject.height
|
||||||
|
|
||||||
PointingHandInteraction {}
|
// PointingHandInteraction {}
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
Hyprland.dispatch(`exec xdg-open ${imageData.source}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
implicitWidth: imageObject.width
|
implicitWidth: imageObject.width
|
||||||
@@ -59,23 +57,107 @@ Button {
|
|||||||
color: Appearance.colors.colLayer2
|
color: Appearance.colors.colLayer2
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: Image {
|
contentItem: Item {
|
||||||
id: imageObject
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
sourceSize.width: root.rowHeight * modelData.aspect_ratio
|
|
||||||
sourceSize.height: root.rowHeight
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
source: modelData.preview_url
|
|
||||||
width: root.rowHeight * modelData.aspect_ratio
|
|
||||||
height: root.rowHeight
|
|
||||||
|
|
||||||
layer.enabled: true
|
Image {
|
||||||
layer.effect: OpacityMask {
|
id: imageObject
|
||||||
maskSource: Rectangle {
|
anchors.fill: parent
|
||||||
width: imageObject.width
|
sourceSize.width: root.rowHeight * modelData.aspect_ratio
|
||||||
height: imageObject.height
|
sourceSize.height: root.rowHeight
|
||||||
radius: Appearance.rounding.small
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: modelData.preview_url
|
||||||
|
width: root.rowHeight * modelData.aspect_ratio
|
||||||
|
height: root.rowHeight
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: OpacityMask {
|
||||||
|
maskSource: Rectangle {
|
||||||
|
width: imageObject.width
|
||||||
|
height: imageObject.height
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: menuButton
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: 8
|
||||||
|
implicitHeight: 30
|
||||||
|
implicitWidth: 30
|
||||||
|
|
||||||
|
PointingHandInteraction {}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: menuButton.down ? Appearance.mix(Appearance.colors.colScrim, Appearance.m3colors.m3onSurface, 0.6) :
|
||||||
|
menuButton.hovered ? Appearance.mix(Appearance.colors.colScrim, Appearance.m3colors.m3onSurface, 0.8) :
|
||||||
|
Appearance.colors.colScrim
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: MaterialSymbol {
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.large
|
||||||
|
color: Appearance.m3colors.m3onSurface
|
||||||
|
text: "more_vert"
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.showActions = !root.showActions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: contextMenu
|
||||||
|
visible: root.showActions
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
color: Appearance.m3colors.m3surfaceContainer
|
||||||
|
anchors.top: menuButton.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: 8
|
||||||
|
implicitHeight: contextMenuColumnLayout.implicitHeight + radius * 2
|
||||||
|
implicitWidth: contextMenuColumnLayout.implicitWidth
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: contextMenuColumnLayout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
MenuButton {
|
||||||
|
id: openFileLinkButton
|
||||||
|
Layout.fillWidth: true
|
||||||
|
buttonText: "Open file link"
|
||||||
|
onClicked: {
|
||||||
|
root.showActions = false
|
||||||
|
Hyprland.dispatch("global quickshell:sidebarLeftClose")
|
||||||
|
Hyprland.dispatch(`exec xdg-open '${root.imageData.file_url}'`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuButton {
|
||||||
|
id: sourceButton
|
||||||
|
Layout.fillWidth: true
|
||||||
|
buttonText: "Go to source"
|
||||||
|
enabled: root.imageData.source && root.imageData.source.length > 0
|
||||||
|
onClicked: {
|
||||||
|
root.showActions = false
|
||||||
|
Hyprland.dispatch("global quickshell:sidebarLeftClose")
|
||||||
|
Hyprland.dispatch(`exec xdg-open '${root.imageData.source}'`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuButton {
|
||||||
|
id: downloadButton
|
||||||
|
Layout.fillWidth: true
|
||||||
|
buttonText: "Download"
|
||||||
|
onClicked: {
|
||||||
|
root.showActions = false
|
||||||
|
Hyprland.dispatch("global quickshell:sidebarLeftClose")
|
||||||
|
Hyprland.dispatch(`exec curl '${root.imageData.file_url}' -o '${root.imageData.is_nsfw ? root.nsfwPath : root.downloadPath}/${root.fileName}' && notify-send 'Download complete' '${root.downloadPath}/${root.fileName}'`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property real availableWidth: parent.width ?? 0
|
property real availableWidth: parent.width ?? 0
|
||||||
property real rowTooShortThreshold: 100
|
property real rowTooShortThreshold: 185
|
||||||
property real imageSpacing: 5
|
property real imageSpacing: 5
|
||||||
property real responsePadding: 5
|
property real responsePadding: 5
|
||||||
|
|
||||||
@@ -190,9 +190,9 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Otherwise, put only one image in the row
|
// Otherwise, put only one image in the row
|
||||||
const rowHeight = availableImageWidth / responseList[i].aspect_ratio;
|
const rowHeight = (availableWidth - (responsePadding * 2)) / responseList[i].aspect_ratio;
|
||||||
rows.push({
|
rows.push({
|
||||||
height: availableWidth / responseList[i].aspect_ratio,
|
height: rowHeight,
|
||||||
images: [responseList[i]],
|
images: [responseList[i]],
|
||||||
});
|
});
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user