forked from Shinonome/dots-hyprland
booru: proper danbooru support, fix gelbooru
This commit is contained in:
@@ -113,12 +113,14 @@ Singleton {
|
||||
property color colOnLayer1Inactive: mix(colOnLayer1, colLayer1, 0.45);
|
||||
property color colLayer2: mix(m3colors.m3surfaceContainer, m3colors.m3surfaceContainerHigh, 0.55);
|
||||
property color colOnLayer2: m3colors.m3onSurface;
|
||||
property color colOnLayer2Disabled: mix(colOnLayer2, m3colors.m3background, 0.4);
|
||||
property color colLayer3: mix(m3colors.m3surfaceContainerHigh, m3colors.m3onSurface, 0.96);
|
||||
property color colOnLayer3: m3colors.m3onSurface;
|
||||
property color colLayer1Hover: mix(colLayer1, colOnLayer1, 0.88);
|
||||
property color colLayer1Active: mix(colLayer1, colOnLayer1, 0.77);
|
||||
property color colLayer2Hover: mix(colLayer2, colOnLayer2, 0.90);
|
||||
property color colLayer2Active: mix(colLayer2, colOnLayer2, 0.80);
|
||||
property color colLayer2Disabled: mix(colLayer2, m3colors.m3background, 0.8);
|
||||
property color colLayer3Hover: mix(colLayer3, colOnLayer3, 0.90);
|
||||
property color colLayer3Active: mix(colLayer3, colOnLayer3, 0.80);
|
||||
property color colPrimaryHover: mix(m3colors.m3primary, colLayer1Hover, 0.85)
|
||||
|
||||
@@ -9,7 +9,7 @@ ToolTip {
|
||||
property bool extraVisibleCondition: true
|
||||
property bool alternativeVisibleCondition: false
|
||||
property bool internalVisibleCondition: false
|
||||
padding: 7
|
||||
padding: 5
|
||||
|
||||
visible: ((extraVisibleCondition && (parent.hovered === undefined || parent?.hovered) && internalVisibleCondition)) || alternativeVisibleCondition
|
||||
|
||||
@@ -50,6 +50,7 @@ ToolTip {
|
||||
StyledText {
|
||||
id: tooltipTextObject
|
||||
text: content
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
color: Appearance.colors.colOnTooltip
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import "root:/services"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import "./anime/"
|
||||
import Qt.labs.platform
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
@@ -15,6 +16,14 @@ Item {
|
||||
id: root
|
||||
property var panelWindow
|
||||
property var inputField: tagInputField
|
||||
property string previewDownloadPath: `${StandardPaths.standardLocations(StandardPaths.CacheLocation)[0]}/media/waifus`.replace("file://", "")
|
||||
property string downloadPath: (StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] + "/homework").replace("file://", "")
|
||||
property string nsfwPath: (StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] + "/homework/🌶️").replace("file://", "")
|
||||
|
||||
Component.onCompleted: {
|
||||
Hyprland.dispatch(`exec rm -rf ${previewDownloadPath}`)
|
||||
Hyprland.dispatch(`exec mkdir -p ${previewDownloadPath}`)
|
||||
}
|
||||
|
||||
function handleInput(inputText) {
|
||||
if (inputText.startsWith("/")) {
|
||||
@@ -28,9 +37,15 @@ Item {
|
||||
const newProvider = args[0];
|
||||
Booru.setProvider(newProvider);
|
||||
}
|
||||
else if (command == "lewd" || command == "nsfw") {
|
||||
else if (command == "nsfw") {
|
||||
ConfigOptions.sidebar.booru.allowNsfw = !ConfigOptions.sidebar.booru.allowNsfw
|
||||
}
|
||||
else if (command == "safe") {
|
||||
ConfigOptions.sidebar.booru.allowNsfw = false
|
||||
}
|
||||
else if (command == "lewd") {
|
||||
ConfigOptions.sidebar.booru.allowNsfw = true
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
@@ -105,6 +120,9 @@ Item {
|
||||
delegate: BooruResponse {
|
||||
responseData: modelData
|
||||
tagInputField: root.inputField
|
||||
previewDownloadPath: root.previewDownloadPath
|
||||
downloadPath: root.downloadPath
|
||||
nsfwPath: root.nsfwPath
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,34 +182,78 @@ Item {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
TextArea { // The actual input field widget
|
||||
id: tagInputField
|
||||
wrapMode: TextArea.Wrap
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
Layout.topMargin: 5
|
||||
padding: 10
|
||||
color: activeFocus ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3onSurfaceVariant
|
||||
renderType: Text.NativeRendering
|
||||
selectedTextColor: Appearance.m3colors.m3onPrimary
|
||||
selectionColor: Appearance.m3colors.m3primary
|
||||
placeholderText: qsTr("Enter tags")
|
||||
placeholderTextColor: Appearance.m3colors.m3outline
|
||||
spacing: 0
|
||||
TextArea { // The actual input field widget
|
||||
id: tagInputField
|
||||
wrapMode: TextArea.Wrap
|
||||
Layout.fillWidth: true
|
||||
padding: 10
|
||||
color: activeFocus ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3onSurfaceVariant
|
||||
renderType: Text.NativeRendering
|
||||
selectedTextColor: Appearance.m3colors.m3onPrimary
|
||||
selectionColor: Appearance.m3colors.m3primary
|
||||
placeholderText: qsTr("Enter tags")
|
||||
placeholderTextColor: Appearance.m3colors.m3outline
|
||||
|
||||
background: Item {}
|
||||
background: Item {}
|
||||
|
||||
Keys.onPressed: (event) => {
|
||||
if ((event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
// Insert newline
|
||||
tagInputField.insert(tagInputField.cursorPosition, "\n")
|
||||
event.accepted = true
|
||||
} else { // Accept text
|
||||
Keys.onPressed: (event) => {
|
||||
if ((event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
// Insert newline
|
||||
tagInputField.insert(tagInputField.cursorPosition, "\n")
|
||||
event.accepted = true
|
||||
} else { // Accept text
|
||||
const inputText = tagInputField.text
|
||||
root.handleInput(inputText)
|
||||
tagInputField.clear()
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Button { // Send button
|
||||
id: sendButton
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.rightMargin: 5
|
||||
implicitWidth: 40
|
||||
implicitHeight: 40
|
||||
enabled: tagInputField.text.length > 0
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: sendButton.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: {
|
||||
const inputText = tagInputField.text
|
||||
root.handleInput(inputText)
|
||||
tagInputField.clear()
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
radius: Appearance.rounding.small
|
||||
color: sendButton.enabled ? (sendButton.down ? Appearance.colors.colPrimaryActive :
|
||||
sendButton.hovered ? Appearance.colors.colPrimaryHover :
|
||||
Appearance.m3colors.m3primary) : Appearance.colors.colLayer2Disabled
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Appearance.animation.elementDecel.duration
|
||||
easing.type: Appearance.animation.elementDecel.type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: MaterialSymbol {
|
||||
anchors.centerIn: parent
|
||||
text: "send"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
color: sendButton.enabled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer2Disabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,8 +278,6 @@ Item {
|
||||
Item {
|
||||
implicitHeight: providerRowLayout.implicitHeight + 5 * 2
|
||||
implicitWidth: providerRowLayout.implicitWidth + 10 * 2
|
||||
// radius: Appearance.rounding.small
|
||||
// color: Appearance.colors.colLayer1
|
||||
|
||||
RowLayout {
|
||||
id: providerRowLayout
|
||||
@@ -249,7 +309,7 @@ Item {
|
||||
}
|
||||
|
||||
StyledText {
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
font.pixelSize: Appearance.font.pixelSize.large
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: "•"
|
||||
}
|
||||
@@ -267,13 +327,13 @@ Item {
|
||||
Layout.leftMargin: 10
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
color: Appearance.colors.coloOnLayer1
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: qsTr("NSFW")
|
||||
}
|
||||
StyledSwitch {
|
||||
id: nsfwSwitch
|
||||
enabled: Booru.currentProvider !== "zerochan"
|
||||
scale: 0.75
|
||||
scale: 0.6
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
checked: (ConfigOptions.sidebar.booru.allowNsfw && Booru.currentProvider !== "zerochan")
|
||||
onCheckedChanged: {
|
||||
@@ -294,9 +354,9 @@ Item {
|
||||
buttonText: modelData.name
|
||||
background: Rectangle {
|
||||
radius: Appearance.rounding.small
|
||||
color: (tagButton.down ? Appearance.colors.colLayer1Active :
|
||||
tagButton.hovered ? Appearance.colors.colLayer1Hover :
|
||||
Appearance.transparentize(Appearance.colors.colLayer1, 1))
|
||||
color: tagButton.down ? Appearance.colors.colLayer2Active :
|
||||
tagButton.hovered ? Appearance.colors.colLayer2Hover :
|
||||
Appearance.colors.colLayer2
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import "root:/"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import Qt.labs.platform
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
@@ -11,10 +13,31 @@ Button {
|
||||
id: root
|
||||
property var imageData
|
||||
property var rowHeight
|
||||
property bool manualDownload: false
|
||||
property string previewDownloadPath
|
||||
property string downloadPath
|
||||
property string nsfwPath
|
||||
property string fileName: decodeURIComponent((imageData.file_url).substring((imageData.file_url).lastIndexOf('/') + 1))
|
||||
|
||||
// onImageDataChanged: {
|
||||
// console.log("Image data changed:", imageData)
|
||||
// }
|
||||
Process {
|
||||
id: downloadProcess
|
||||
running: false
|
||||
command: ["bash", "-c", `curl '${imageData.preview_url}' -o '${previewDownloadPath}/${root.fileName}' && echo 'done'`]
|
||||
stdout: SplitParser {
|
||||
onRead: (data) => {
|
||||
console.log("Download output:", data)
|
||||
if(data.includes("done")) {
|
||||
imageObject.source = `${previewDownloadPath}/${root.fileName}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.manualDownload) {
|
||||
downloadProcess.running = true
|
||||
}
|
||||
}
|
||||
|
||||
padding: 0
|
||||
implicitWidth: imageObject.width
|
||||
|
||||
@@ -17,11 +17,15 @@ Rectangle {
|
||||
property var responseData
|
||||
property var tagInputField
|
||||
|
||||
property string previewDownloadPath
|
||||
property string downloadPath
|
||||
property string nsfwPath
|
||||
|
||||
onResponseDataChanged: {
|
||||
console.log("Response data changed:", responseData)
|
||||
}
|
||||
|
||||
property real availableWidth: parent?.width
|
||||
property real availableWidth: parent.width ?? 0
|
||||
property real rowTooShortThreshold: 100
|
||||
property real imageSpacing: 5
|
||||
property real responsePadding: 5
|
||||
@@ -65,7 +69,7 @@ Rectangle {
|
||||
visible: root.responseData.page != "" && root.responseData.page > 0
|
||||
implicitWidth: Math.max(pageNumber.implicitWidth + 10 * 2, 30)
|
||||
implicitHeight: pageNumber.implicitHeight + 5 * 2
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
StyledText {
|
||||
id: pageNumber
|
||||
@@ -205,6 +209,10 @@ Rectangle {
|
||||
delegate: BooruImage {
|
||||
imageData: modelData
|
||||
rowHeight: imageRow.rowHeight
|
||||
manualDownload: root.responseData.provider == "danbooru"
|
||||
previewDownloadPath: root.previewDownloadPath
|
||||
downloadPath: root.downloadPath
|
||||
nsfwPath: root.nsfwPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
property string failMessage: qsTr("That didn't work. Tips:\n- Check your tags and NSFW settings\n- If you don't have a tag in mind, type a page number")
|
||||
property var responses: []
|
||||
property var getWorkingImageSource: (url) => {
|
||||
if (url.includes('pximg.net')) {
|
||||
@@ -203,7 +204,12 @@ Singleton {
|
||||
else {
|
||||
params.push("tags=" + encodeURIComponent(tagString))
|
||||
params.push("limit=" + limit)
|
||||
params.push("page=" + page)
|
||||
if (currentProvider == "gelbooru") {
|
||||
params.push("pid=" + page)
|
||||
}
|
||||
else {
|
||||
params.push("page=" + page)
|
||||
}
|
||||
}
|
||||
var url = baseUrl
|
||||
if (baseUrl.indexOf("?") === -1) {
|
||||
@@ -224,7 +230,7 @@ Singleton {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
||||
try {
|
||||
// console.log("[Booru] Raw response length: " + xhr.responseText.length)
|
||||
// console.log("[Booru] Raw response: " + xhr.responseText)
|
||||
console.log("[Booru] Raw response: " + xhr.responseText)
|
||||
var response = JSON.parse(xhr.responseText)
|
||||
|
||||
// Access nested properties based on listAccess
|
||||
@@ -243,11 +249,18 @@ Singleton {
|
||||
"tags": tags,
|
||||
"page": page,
|
||||
"images": response,
|
||||
"message": ""
|
||||
"message": response.length > 0 ? "" : root.failMessage
|
||||
}]
|
||||
|
||||
} catch (e) {
|
||||
console.log("[Booru] Failed to parse response: " + e)
|
||||
root.responses = [...root.responses, {
|
||||
"provider": currentProvider,
|
||||
"tags": tags,
|
||||
"page": page,
|
||||
"images": [],
|
||||
"message": root.failMessage
|
||||
}]
|
||||
}
|
||||
}
|
||||
else if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
|
||||
Reference in New Issue
Block a user