booru: more sexy

This commit is contained in:
end-4
2025-04-29 10:44:44 +02:00
parent b605cf33dd
commit 5543efac7a
10 changed files with 363 additions and 113 deletions
@@ -445,7 +445,7 @@ Item {
? `<style>img{max-width:${notificationBodyText.width}px;}</style>` + ? `<style>img{max-width:${notificationBodyText.width}px;}</style>` +
`${notificationObject.body.replace(/\n/g, "<br/>")}` `${notificationObject.body.replace(/\n/g, "<br/>")}`
: notificationObject.body.replace(/<img/g, "\n <img").split("\n")[0] : notificationObject.body.replace(/<img/g, "\n <img").split("\n")[0]
onLinkActivated: { onLinkActivated: (link) => {
Qt.openUrlExternally(link) Qt.openUrlExternally(link)
Hyprland.dispatch("global quickshell:sidebarRightClose") Hyprland.dispatch("global quickshell:sidebarRightClose")
} }
@@ -453,7 +453,7 @@ Item {
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.NoButton // Only for hover acceptedButtons: Qt.NoButton // Only for hover
hoverEnabled: true hoverEnabled: true
cursorShape: notificationBodyText.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor
} }
} }
} }
@@ -0,0 +1,71 @@
import "root:/modules/common/"
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt5Compat.GraphicalEffects
Switch {
id: root
property real scale: 1
implicitHeight: 32 * root.scale
implicitWidth: 52 * root.scale
// Custom track styling
background: Rectangle {
width: parent.width
height: parent.height
radius: Appearance.rounding.full
color: root.checked ? Appearance.m3colors.m3primary : Appearance.m3colors.m3surfaceContainerHighest
border.width: 2 * root.scale
border.color: root.checked ? Appearance.m3colors.m3primary : Appearance.m3colors.m3outline
Behavior on color {
ColorAnimation {
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
Behavior on border.color {
ColorAnimation {
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
}
// Custom thumb styling
indicator: Rectangle {
width: root.pressed ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
height: root.pressed ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
radius: Appearance.rounding.full
color: root.checked ? Appearance.m3colors.m3onPrimary : Appearance.m3colors.m3outline
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: root.checked ? (root.pressed ? (22 * root.scale) : 24 * root.scale) : (root.pressed ? (2 * root.scale) : 8 * root.scale)
Behavior on anchors.leftMargin {
NumberAnimation {
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
Behavior on width {
NumberAnimation {
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
Behavior on height {
NumberAnimation {
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
Behavior on color {
ColorAnimation {
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
}
}
+198 -73
View File
@@ -16,14 +16,48 @@ Item {
property var panelWindow property var panelWindow
property var inputField: tagInputField property var inputField: tagInputField
function handleInput(inputText) {
if (inputText.startsWith("/")) {
// Handle special commands
const command = inputText.split(" ")[0].substring(1);
const args = inputText.split(" ").slice(1);
if (command === "clear") {
Booru.clearResponses();
}
else if (command === "mode") {
const newProvider = args[0];
Booru.setProvider(newProvider);
}
else if (command == "lewd" || command == "nsfw") {
ConfigOptions.sidebar.booru.allowNsfw = !ConfigOptions.sidebar.booru.allowNsfw
}
}
else {
// Create tag list
const tagList = inputText.split(/\s+/);
let pageIndex = 1;
for (let i = 0; i < tagList.length; ++i) { // Detect page number
if (/^\d+$/.test(tagList[i])) {
pageIndex = parseInt(tagList[i], 10);
tagList.splice(i, 1);
break;
}
}
Booru.makeRequest(tagList, ConfigOptions.sidebar.booru.allowNsfw, ConfigOptions.sidebar.booru.limit, pageIndex);
}
}
Keys.onPressed: (event) => { Keys.onPressed: (event) => {
tagInputField.forceActiveFocus() tagInputField.forceActiveFocus()
if (event.key === Qt.Key_PageUp) { if (event.modifiers === Qt.NoModifier) {
booruResponseListView.contentY = Math.max(0, booruResponseListView.contentY - booruResponseListView.height / 2) if (event.key === Qt.Key_PageUp) {
event.accepted = true booruResponseListView.contentY = Math.max(0, booruResponseListView.contentY - booruResponseListView.height / 2)
} else if (event.key === Qt.Key_PageDown) { event.accepted = true
booruResponseListView.contentY = Math.min(booruResponseListView.contentHeight - booruResponseListView.height, booruResponseListView.contentY + booruResponseListView.height / 2) } else if (event.key === Qt.Key_PageDown) {
event.accepted = true booruResponseListView.contentY = Math.min(booruResponseListView.contentHeight - booruResponseListView.height / 2, booruResponseListView.contentY + booruResponseListView.height / 2)
event.accepted = true
}
} }
} }
@@ -37,46 +71,75 @@ Item {
id: columnLayout id: columnLayout
anchors.fill: parent anchors.fill: parent
ListView { // Booru responses Item {
id: booruResponseListView
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
clip: true ListView { // Booru responses
layer.enabled: true id: booruResponseListView
layer.effect: OpacityMask { anchors.fill: parent
maskSource: Rectangle { clip: true
width: swipeView.width layer.enabled: true
height: swipeView.height layer.effect: OpacityMask {
radius: Appearance.rounding.small maskSource: Rectangle {
width: swipeView.width
height: swipeView.height
radius: Appearance.rounding.small
}
}
Behavior on contentY {
NumberAnimation {
id: scrollAnim
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
spacing: 10
model: ScriptModel {
values: Booru.responses
}
delegate: BooruResponse {
responseData: modelData
tagInputField: root.inputField
} }
} }
Behavior on contentY { Item { // Placeholder when list is empty
NumberAnimation { visible: Booru.responses.length === 0
id: scrollAnim anchors.fill: parent
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
}
}
spacing: 10 ColumnLayout {
model: ScriptModel { anchors.centerIn: parent
values: Booru.responses spacing: 5
}
delegate: BooruResponse { MaterialSymbol {
responseData: modelData Layout.alignment: Qt.AlignHCenter
tagInputField: root.inputField font.pixelSize: 55
color: Appearance.m3colors.m3outline
text: "bookmark_heart"
}
StyledText {
Layout.alignment: Qt.AlignHCenter
font.pixelSize: Appearance.font.pixelSize.normal
color: Appearance.m3colors.m3outline
horizontalAlignment: Text.AlignHCenter
text: "Anime boorus"
}
}
} }
} }
Rectangle { Rectangle { // Tag input field
id: tagInputFieldContainer id: tagInputContainer
Layout.fillWidth: true Layout.fillWidth: true
radius: Appearance.rounding.small radius: Appearance.rounding.small
color: Appearance.colors.colLayer1 color: Appearance.colors.colLayer1
implicitWidth: tagInputField.implicitWidth implicitWidth: tagInputColumnLayout.implicitWidth
implicitHeight: Math.max(tagInputField.implicitHeight, 45) implicitHeight: Math.max(tagInputColumnLayout.implicitHeight, 45)
clip: true clip: true
border.color: Appearance.m3colors.m3outlineVariant
border.width: 1
Behavior on implicitHeight { Behavior on implicitHeight {
NumberAnimation { NumberAnimation {
@@ -85,56 +148,118 @@ Item {
} }
} }
TextArea { ColumnLayout {
id: tagInputField id: tagInputColumnLayout
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
wrapMode: TextArea.Wrap TextArea { // The actual input field widget
id: tagInputField
wrapMode: TextArea.Wrap
Layout.fillWidth: true
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
padding: 10 background: Item {}
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
Keys.onPressed: (event) => { Keys.onPressed: (event) => {
if ((event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) { if ((event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
if (event.modifiers & Qt.ShiftModifier) { if (event.modifiers & Qt.ShiftModifier) {
// Insert newline // Insert newline
tagInputField.insert(tagInputField.cursorPosition, "\n") tagInputField.insert(tagInputField.cursorPosition, "\n")
event.accepted = true event.accepted = true
} else { } else { // Accept text
const inputText = tagInputField.text const inputText = tagInputField.text
if (inputText.startsWith("/")) { root.handleInput(inputText)
// Handle special commands tagInputField.clear()
const command = inputText.split(" ")[0].substring(1); event.accepted = true
if (command === "clear") { }
Booru.clearResponses(); }
} }
else if (command === "mode") { }
const newProvider = inputText.split(" ")[1];
Booru.setProvider(newProvider); RowLayout { // Controls
Booru.addSystemMessage(`Provider set to ${Booru.providers[newProvider].name}`); id: commandButtonsRow
spacing: 5
Layout.bottomMargin: 5
Layout.leftMargin: 5
Layout.rightMargin: 5
property var commands: [
{
name: "/mode",
sendDirectly: false,
},
{
name: "/clear",
sendDirectly: true,
},
]
Rectangle {
implicitWidth: switchesRow.implicitWidth
RowLayout {
id: switchesRow
spacing: 5
anchors.centerIn: parent
StyledText {
Layout.fillHeight: true
Layout.leftMargin: 10
Layout.alignment: Qt.AlignVCenter
font.pixelSize: Appearance.font.pixelSize.smaller
color: Appearance.colors.coloOnLayer1
text: qsTr("NSFW")
}
StyledSwitch {
id: nsfwSwitch
scale: 0.75
Layout.alignment: Qt.AlignVCenter
checked: ConfigOptions.sidebar.booru.allowNsfw
onCheckedChanged: {
ConfigOptions.sidebar.booru.allowNsfw = checked
} }
} }
else { }
// Create tag list }
const tagList = inputText.split(/\s+/);
let pageIndex = 1; Item { Layout.fillWidth: true }
for (let i = 0; i < tagList.length; ++i) { // Detect page number
if (/^\d+$/.test(tagList[i])) { Repeater { // Command buttons
pageIndex = parseInt(tagList[i], 10); id: commandRepeater
tagList.splice(i, 1); model: commandButtonsRow.commands
break; delegate: BooruTagButton {
id: tagButton
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))
Behavior on color {
ColorAnimation {
duration: Appearance.animation.elementDecel.duration
easing.type: Appearance.animation.elementDecel.type
} }
} }
Booru.makeRequest(tagList, ConfigOptions.sidebar.booru.allowNsfw, ConfigOptions.sidebar.booru.limit, pageIndex);
} }
tagInputField.clear() onClicked: {
event.accepted = true if(modelData.sendDirectly) {
root.handleInput(modelData.name)
} else {
tagInputField.text = modelData.name + " "
tagInputField.cursorPosition = tagInputField.text.length
tagInputField.forceActiveFocus()
}
}
} }
} }
} }
@@ -90,9 +90,16 @@ Scope { // Scope
if (event.modifiers === Qt.ControlModifier) { if (event.modifiers === Qt.ControlModifier) {
if (event.key === Qt.Key_PageDown) { if (event.key === Qt.Key_PageDown) {
sidebarRoot.currentTab = Math.min(sidebarRoot.currentTab + 1, root.tabButtonList.length - 1) sidebarRoot.currentTab = Math.min(sidebarRoot.currentTab + 1, root.tabButtonList.length - 1)
} else if (event.key === Qt.Key_PageUp) { }
else if (event.key === Qt.Key_PageUp) {
sidebarRoot.currentTab = Math.max(sidebarRoot.currentTab - 1, 0) sidebarRoot.currentTab = Math.max(sidebarRoot.currentTab - 1, 0)
} }
else if (event.key === Qt.Key_Tab) {
sidebarRoot.currentTab = (sidebarRoot.currentTab + 1) % root.tabButtonList.length;
}
else if (event.key === Qt.Key_Backtab) {
sidebarRoot.currentTab = (sidebarRoot.currentTab - 1 + root.tabButtonList.length) % root.tabButtonList.length;
}
event.accepted = true; event.accepted = true;
} }
} }
@@ -12,7 +12,13 @@ Button {
property var imageData property var imageData
property var rowHeight property var rowHeight
// onImageDataChanged: {
// console.log("Image data changed:", imageData)
// }
padding: 0 padding: 0
implicitWidth: imageObject.width
implicitHeight: imageObject.height
PointingHandInteraction {} PointingHandInteraction {}
@@ -21,27 +27,27 @@ Button {
} }
background: Rectangle { background: Rectangle {
implicitWidth: imageData.width implicitWidth: imageObject.width
implicitHeight: imageData.height implicitHeight: imageObject.height
radius: Appearance.rounding.small radius: Appearance.rounding.small
color: Appearance.colors.colLayer2 color: Appearance.colors.colLayer2
} }
contentItem: Image { contentItem: Image {
id: imageData id: imageObject
anchors.fill: parent anchors.fill: parent
sourceSize.width: imageRow.rowHeight * modelData.aspect_ratio sourceSize.width: root.rowHeight * modelData.aspect_ratio
sourceSize.height: imageRow.rowHeight sourceSize.height: root.rowHeight
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
source: modelData.preview_url source: modelData.preview_url
width: imageRow.rowHeight * modelData.aspect_ratio width: root.rowHeight * modelData.aspect_ratio
height: imageRow.rowHeight height: root.rowHeight
layer.enabled: true layer.enabled: true
layer.effect: OpacityMask { layer.effect: OpacityMask {
maskSource: Rectangle { maskSource: Rectangle {
width: imageData.width width: imageObject.width
height: imageData.height height: imageObject.height
radius: Appearance.rounding.small radius: Appearance.rounding.small
} }
} }
@@ -14,9 +14,13 @@ import Qt5Compat.GraphicalEffects
Rectangle { Rectangle {
id: root id: root
property var responseData property var responseData: {}
property var tagInputField property var tagInputField
onResponseDataChanged: {
console.log("Response data changed:", responseData)
}
property real availableWidth: parent?.width property real availableWidth: parent?.width
property real rowTooShortThreshold: 100 property real rowTooShortThreshold: 100
property real imageSpacing: 5 property real imageSpacing: 5
@@ -38,9 +42,8 @@ Rectangle {
anchors.margins: responsePadding anchors.margins: responsePadding
spacing: root.imageSpacing spacing: root.imageSpacing
// Provider name RowLayout { // Header
RowLayout { Rectangle { // Provider name
Rectangle {
id: providerNameWrapper id: providerNameWrapper
color: Appearance.m3colors.m3secondaryContainer color: Appearance.m3colors.m3secondaryContainer
radius: Appearance.rounding.small radius: Appearance.rounding.small
@@ -52,31 +55,33 @@ Rectangle {
id: providerName id: providerName
anchors.centerIn: parent anchors.centerIn: parent
font.pixelSize: Appearance.font.pixelSize.large font.pixelSize: Appearance.font.pixelSize.large
font.weight: Font.DemiBold
color: Appearance.m3colors.m3onSecondaryContainer color: Appearance.m3colors.m3onSecondaryContainer
text: Booru.providers[root.responseData.provider].name text: Booru.providers[root.responseData.provider].name
} }
} }
Item { Layout.fillWidth: true } Item { Layout.fillWidth: true }
Rectangle { Rectangle { // Page number
visible: root.responseData.page != "" && root.responseData.page > 0
color: Appearance.colors.colLayer2 color: Appearance.colors.colLayer2
radius: Appearance.rounding.small radius: Appearance.rounding.small
implicitWidth: Math.max(pageNumber.implicitWidth + 10 * 2, 20) implicitWidth: Math.max(pageNumber.implicitWidth + 10 * 2, 30)
implicitHeight: pageNumber.implicitHeight + 5 * 2 implicitHeight: pageNumber.implicitHeight + 5 * 2
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignTop
StyledText { StyledText {
id: pageNumber id: pageNumber
anchors.centerIn: parent anchors.centerIn: parent
font.pixelSize: Appearance.font.pixelSize.small font.pixelSize: Appearance.font.pixelSize.smaller
color: Appearance.colors.colOnLayer2 color: Appearance.colors.colOnLayer2
text: `Page ${root.responseData.page}` text: `Page ${root.responseData.page}`
} }
} }
} }
// Tags Flickable { // Tag strip
Flickable {
id: tagsFlickable id: tagsFlickable
visible: root.responseData.tags.length > 0
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Layout.fillWidth: { Layout.fillWidth: {
console.log(root.responseData) console.log(root.responseData)
@@ -128,6 +133,28 @@ Rectangle {
} }
} }
StyledText { // Message
id: messageText
Layout.fillWidth: true
visible: root.responseData.message.length > 0
font.pixelSize: Appearance.font.pixelSize.small
color: Appearance.colors.colOnLayer1
text: root.responseData.message
wrapMode: Text.WordWrap
Layout.margins: responsePadding
textFormat: Text.MarkdownText
onLinkActivated: (link) => {
Qt.openUrlExternally(link)
Hyprland.dispatch("global quickshell:sidebarLeftClose")
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton // Only for hover
hoverEnabled: true
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
Repeater { Repeater {
model: { model: {
// Group two images every row, ensuring they are of the same height // Group two images every row, ensuring they are of the same height
@@ -22,8 +22,6 @@ Button {
color: (button.down ? Appearance.colors.colSurfaceContainerHighestActive : color: (button.down ? Appearance.colors.colSurfaceContainerHighestActive :
button.hovered ? Appearance.colors.colSurfaceContainerHighestHover : button.hovered ? Appearance.colors.colSurfaceContainerHighestHover :
Appearance.m3colors.m3surfaceContainerHighest) Appearance.m3colors.m3surfaceContainerHighest)
} }
contentItem: StyledText { contentItem: StyledText {
@@ -28,6 +28,14 @@ Rectangle {
} }
event.accepted = true; event.accepted = true;
} }
if (event.modifiers === Qt.ControlModifier) {
if (event.key === Qt.Key_Tab) {
root.currentTab = (root.currentTab + 1) % root.tabButtonList.length;
} else if (event.key === Qt.Key_Backtab) {
root.currentTab = (root.currentTab - 1 + root.tabButtonList.length) % root.tabButtonList.length;
}
event.accepted = true;
}
} }
ColumnLayout { ColumnLayout {
@@ -146,8 +146,8 @@ Item {
} }
} }
} }
// Placeholder when list is empty
Item { Item { // Placeholder when list is empty
visible: taskList.length === 0 visible: taskList.length === 0
anchors.fill: parent anchors.fill: parent
+22 -14
View File
@@ -10,6 +10,13 @@ import QtQuick;
Singleton { Singleton {
id: root id: root
Connections {
target: ConfigOptions.sidebar.booru
function onAllowNsfwChanged() {
root.addSystemMessage(ConfigOptions.sidebar.booru.allowNsfw ? qsTr("Tiddies enabled") : qsTr("No horny"))
}
}
property var responses: [] property var responses: []
property var getWorkingImageSource: (url) => { property var getWorkingImageSource: (url) => {
if (url.includes('pximg.net')) { if (url.includes('pximg.net')) {
@@ -42,7 +49,7 @@ Singleton {
"sample_url": item.sample_url ?? item.file_url, "sample_url": item.sample_url ?? item.file_url,
"file_url": item.file_url, "file_url": item.file_url,
"file_ext": item.file_ext, "file_ext": item.file_ext,
"source": getWorkingImageSource(item.source), "source": getWorkingImageSource(item.source) ?? item.file_url,
} }
}) })
} }
@@ -67,7 +74,7 @@ Singleton {
"sample_url": item.sample_url ?? item.file_url, "sample_url": item.sample_url ?? item.file_url,
"file_url": item.file_url, "file_url": item.file_url,
"file_ext": item.file_ext, "file_ext": item.file_ext,
"source": getWorkingImageSource(item.source), "source": getWorkingImageSource(item.source) ?? item.file_url,
} }
}) })
} }
@@ -92,7 +99,7 @@ Singleton {
"sample_url": item.thumbnail, "sample_url": item.thumbnail,
"file_url": item.thumbnail, "file_url": item.thumbnail,
"file_ext": "avif", "file_ext": "avif",
"source": getWorkingImageSource(item.source), "source": getWorkingImageSource(item.source) ?? item.thumbnail,
"character": item.tag "character": item.tag
} }
}) })
@@ -118,7 +125,7 @@ Singleton {
"sample_url": item.file_url ?? item.large_file_url, "sample_url": item.file_url ?? item.large_file_url,
"file_url": item.large_file_url, "file_url": item.large_file_url,
"file_ext": item.file_ext, "file_ext": item.file_ext,
"source": getWorkingImageSource(item.source), "source": getWorkingImageSource(item.source) ?? item.file_url,
} }
}) })
} }
@@ -143,7 +150,7 @@ Singleton {
"sample_url": item.sample_url ?? item.file_url, "sample_url": item.sample_url ?? item.file_url,
"file_url": item.file_url, "file_url": item.file_url,
"file_ext": item.file_url.split('.').pop(), "file_ext": item.file_url.split('.').pop(),
"source": getWorkingImageSource(item.source), "source": getWorkingImageSource(item.source) ?? item.file_url,
} }
}) })
} }
@@ -155,8 +162,11 @@ Singleton {
function setProvider(provider) { function setProvider(provider) {
if (providerList.indexOf(provider) !== -1) { if (providerList.indexOf(provider) !== -1) {
currentProvider = provider currentProvider = provider
root.addSystemMessage(qsTr("Provider set to ") + providers[provider].name
+ (provider == "zerochan" ? qsTr(". Notes for Zerochan:\n- You must enter a color\n- Set your zerochan username in `sidebar.booru.zerochan.username` config option. You [might be banned for not doing so](https://www.zerochan.net/api#:~:text=The%20request%20may%20still%20be%20completed%20successfully%20without%20this%20custom%20header%2C%20but%20your%20project%20may%20be%20banned%20for%20being%20anonymous.)!") : ""))
} else { } else {
console.log("[Booru] Invalid provider: " + provider) console.log("[Booru] Invalid provider: " + provider)
root.addSystemMessage(qsTr("Invalid provider. Supported providers: \n- ") + providerList.join("\n- "))
} }
} }
@@ -165,13 +175,13 @@ Singleton {
} }
function addSystemMessage(message) { function addSystemMessage(message) {
responses.push({ responses = [...responses, {
"provider": "system", "provider": "system",
"tags": [], "tags": [],
"page": 1, "page": -1,
"images": [], "images": [],
"message": `${message}` "message": `${message}`
}) }]
} }
function constructRequestUrl(tags, nsfw=true, limit=20, page=1) { function constructRequestUrl(tags, nsfw=true, limit=20, page=1) {
@@ -214,7 +224,7 @@ Singleton {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
try { try {
// console.log("[Booru] Raw response length: " + xhr.responseText.length) // 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) var response = JSON.parse(xhr.responseText)
// Access nested properties based on listAccess // Access nested properties based on listAccess
@@ -227,16 +237,14 @@ Singleton {
} }
} }
response = providers[currentProvider].mapFunc(response) response = providers[currentProvider].mapFunc(response)
console.log("[Booru] Scoped & mapped response: " + JSON.stringify(response)) // console.log("[Booru] Scoped & mapped response: " + JSON.stringify(response))
var newResponses = root.responses.slice() // make a shallow copy root.responses = [...root.responses, {
newResponses.push({
"provider": currentProvider, "provider": currentProvider,
"tags": tags, "tags": tags,
"page": page, "page": page,
"images": response, "images": response,
"message": "" "message": ""
}) }]
root.responses = newResponses
} catch (e) { } catch (e) {
console.log("[Booru] Failed to parse response: " + e) console.log("[Booru] Failed to parse response: " + e)