Add shell plugin model tests
This commit is contained in:
@@ -3,6 +3,7 @@ import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import "ClipboardHistory.js" as ClipboardHistory
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -55,48 +56,15 @@ Item {
|
||||
}
|
||||
|
||||
function normalizeEntry(value) {
|
||||
if (typeof value === "string") {
|
||||
return value.length > 0 ? { type: "text", text: value } : null
|
||||
}
|
||||
if (!value || typeof value !== "object") return null
|
||||
|
||||
var type = String(value.type || value.kind || "")
|
||||
if (type === "text") {
|
||||
var text = String(value.text || "")
|
||||
return text.length > 0 ? { type: "text", text: text } : null
|
||||
}
|
||||
if (type === "image") {
|
||||
var path = String(value.path || "")
|
||||
if (!path) return null
|
||||
return {
|
||||
type: "image",
|
||||
path: path,
|
||||
mime: String(value.mime || "image/png")
|
||||
}
|
||||
}
|
||||
return null
|
||||
return ClipboardHistory.normalizeEntry(value)
|
||||
}
|
||||
|
||||
function entryKey(entry) {
|
||||
if (!entry) return ""
|
||||
if (entry.type === "image") return "image:" + String(entry.path || "")
|
||||
return "text:" + String(entry.text || "")
|
||||
return ClipboardHistory.entryKey(entry)
|
||||
}
|
||||
|
||||
function loadHistory(raw) {
|
||||
try {
|
||||
var parsed = JSON.parse(String(raw || "[]"))
|
||||
var next = []
|
||||
if (Array.isArray(parsed)) {
|
||||
for (var i = 0; i < parsed.length; i++) {
|
||||
var entry = root.normalizeEntry(parsed[i])
|
||||
if (entry) next.push(entry)
|
||||
}
|
||||
}
|
||||
root.history = next
|
||||
} catch (e) {
|
||||
root.history = []
|
||||
}
|
||||
root.history = ClipboardHistory.parseHistory(raw)
|
||||
if (root.opened) root.rebuildDisplay()
|
||||
}
|
||||
|
||||
@@ -105,52 +73,33 @@ Item {
|
||||
}
|
||||
|
||||
function addClipboardEntry(entry) {
|
||||
var normalized = root.normalizeEntry(entry)
|
||||
var normalized = ClipboardHistory.normalizeEntry(entry)
|
||||
if (!normalized) return
|
||||
|
||||
var key = root.entryKey(normalized)
|
||||
var next = [normalized]
|
||||
for (var i = 0; i < root.history.length && next.length < 100; i++) {
|
||||
var existing = root.normalizeEntry(root.history[i])
|
||||
if (!existing || root.entryKey(existing) === key) continue
|
||||
next.push(existing)
|
||||
}
|
||||
root.history = next
|
||||
root.history = ClipboardHistory.addEntry(root.history, normalized, 100)
|
||||
root.saveHistory()
|
||||
if (root.opened) root.rebuildDisplay()
|
||||
}
|
||||
|
||||
function addClipboardJson(line) {
|
||||
var raw = String(line || "").trim()
|
||||
if (!raw) return
|
||||
try { root.addClipboardEntry(JSON.parse(raw)) } catch (e) {}
|
||||
root.addClipboardEntry(ClipboardHistory.parseEntryJson(line))
|
||||
}
|
||||
|
||||
function rebuildDisplay() {
|
||||
var query = root.filterText.trim().toLowerCase()
|
||||
var rows = ClipboardHistory.displayRows(root.history, root.filterText, 50)
|
||||
|
||||
displayModel.clear()
|
||||
var outCount = 0
|
||||
|
||||
for (var i = 0; i < root.history.length; i++) {
|
||||
var entry = root.normalizeEntry(root.history[i])
|
||||
if (!entry) continue
|
||||
|
||||
var isImage = entry.type === "image"
|
||||
var searchable = isImage ? ("image " + String(entry.mime || "")) : String(entry.text || "")
|
||||
if (query && searchable.toLowerCase().indexOf(query) < 0) continue
|
||||
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
var row = rows[i]
|
||||
displayModel.append({
|
||||
entryType: entry.type,
|
||||
fullText: isImage ? "" : String(entry.text || ""),
|
||||
previewText: isImage ? "Image" : String(entry.text || "").replace(/\s+/g, " "),
|
||||
previewImage: isImage ? Util.fileUrl(entry.path) : "",
|
||||
path: isImage ? String(entry.path || "") : "",
|
||||
mime: isImage ? String(entry.mime || "image/png") : "text/plain",
|
||||
index: outCount
|
||||
entryType: row.entryType,
|
||||
fullText: row.fullText,
|
||||
previewText: row.previewText,
|
||||
previewImage: row.previewImage ? Util.fileUrl(row.previewImage) : "",
|
||||
path: row.path,
|
||||
mime: row.mime,
|
||||
index: row.index
|
||||
})
|
||||
outCount++
|
||||
if (outCount >= 50) break
|
||||
}
|
||||
|
||||
if (displayModel.count === 0) selectedIndex = 0
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
function normalizeEntry(value) {
|
||||
if (typeof value === "string")
|
||||
return value.length > 0 ? { type: "text", text: value } : null
|
||||
|
||||
if (!value || typeof value !== "object") return null
|
||||
|
||||
var type = String(value.type || value.kind || "")
|
||||
if (type === "text") {
|
||||
var text = String(value.text || "")
|
||||
return text.length > 0 ? { type: "text", text: text } : null
|
||||
}
|
||||
|
||||
if (type === "image") {
|
||||
var path = String(value.path || "")
|
||||
if (!path) return null
|
||||
return {
|
||||
type: "image",
|
||||
path: path,
|
||||
mime: String(value.mime || "image/png")
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function entryKey(entry) {
|
||||
if (!entry) return ""
|
||||
if (entry.type === "image") return "image:" + String(entry.path || "")
|
||||
return "text:" + String(entry.text || "")
|
||||
}
|
||||
|
||||
function parseHistory(raw) {
|
||||
try {
|
||||
var parsed = JSON.parse(String(raw || "[]"))
|
||||
var next = []
|
||||
if (!Array.isArray(parsed)) return next
|
||||
|
||||
for (var i = 0; i < parsed.length; i++) {
|
||||
var entry = normalizeEntry(parsed[i])
|
||||
if (entry) next.push(entry)
|
||||
}
|
||||
return next
|
||||
} catch (e) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
function addEntry(history, entry, limit) {
|
||||
var normalized = normalizeEntry(entry)
|
||||
var max = limit === undefined || limit === null ? 100 : Number(limit)
|
||||
if (isNaN(max)) max = 100
|
||||
max = Math.max(0, max)
|
||||
if (!normalized) return Array.isArray(history) ? history.slice(0, max) : []
|
||||
if (max === 0) return []
|
||||
|
||||
var key = entryKey(normalized)
|
||||
var next = [normalized]
|
||||
var values = Array.isArray(history) ? history : []
|
||||
|
||||
for (var i = 0; i < values.length && next.length < max; i++) {
|
||||
var existing = normalizeEntry(values[i])
|
||||
if (!existing || entryKey(existing) === key) continue
|
||||
next.push(existing)
|
||||
}
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
function parseEntryJson(line) {
|
||||
var raw = String(line || "").trim()
|
||||
if (!raw) return null
|
||||
try { return normalizeEntry(JSON.parse(raw)) } catch (e) { return null }
|
||||
}
|
||||
|
||||
function searchableText(entry) {
|
||||
if (!entry) return ""
|
||||
if (entry.type === "image") return "image " + String(entry.mime || "")
|
||||
return String(entry.text || "")
|
||||
}
|
||||
|
||||
function previewText(entry) {
|
||||
if (!entry) return ""
|
||||
if (entry.type === "image") return "Image"
|
||||
return String(entry.text || "").replace(/\s+/g, " ")
|
||||
}
|
||||
|
||||
function displayRows(history, query, limit) {
|
||||
var values = Array.isArray(history) ? history : []
|
||||
var needle = String(query || "").trim().toLowerCase()
|
||||
var max = limit === undefined || limit === null ? 50 : Number(limit)
|
||||
if (isNaN(max)) max = 50
|
||||
max = Math.max(0, max)
|
||||
if (max === 0) return []
|
||||
|
||||
var rows = []
|
||||
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
var entry = normalizeEntry(values[i])
|
||||
if (!entry) continue
|
||||
if (needle && searchableText(entry).toLowerCase().indexOf(needle) < 0) continue
|
||||
|
||||
var isImage = entry.type === "image"
|
||||
rows.push({
|
||||
entryType: entry.type,
|
||||
fullText: isImage ? "" : String(entry.text || ""),
|
||||
previewText: previewText(entry),
|
||||
previewImage: isImage ? String(entry.path || "") : "",
|
||||
path: isImage ? String(entry.path || "") : "",
|
||||
mime: isImage ? String(entry.mime || "image/png") : "text/plain",
|
||||
index: rows.length
|
||||
})
|
||||
if (rows.length >= max) break
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
if (typeof module !== "undefined") {
|
||||
module.exports = {
|
||||
normalizeEntry: normalizeEntry,
|
||||
entryKey: entryKey,
|
||||
parseHistory: parseHistory,
|
||||
addEntry: addEntry,
|
||||
parseEntryJson: parseEntryJson,
|
||||
searchableText: searchableText,
|
||||
previewText: previewText,
|
||||
displayRows: displayRows
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user