diff --git a/Content/wallpaper_html/index.html b/Content/wallpaper_html/index.html new file mode 100644 index 00000000..91e09dfb --- /dev/null +++ b/Content/wallpaper_html/index.html @@ -0,0 +1,63 @@ + + +
+ + +# Comments: " + var commentSuffix = "
" + var startIdx = raw.indexOf(commentPrefix) + if (startIdx === -1) + return "N/A" // return "N/A" if comment count is not found in the description + startIdx += commentPrefix.length + var endIdx = raw.indexOf(commentSuffix, startIdx) + return raw.substring(startIdx, endIdx) + } + function parsePoints(raw) { + var pointsPrefix = "Points: " + var pointsSuffix = "
" + var startIdx = raw.indexOf(pointsPrefix) + if (startIdx === -1) + return "N/A" // return "N/A" if points are not found in the description + startIdx += pointsPrefix.length + var endIdx = raw.indexOf(pointsSuffix, startIdx) + return raw.substring(startIdx, endIdx) + } + RowLayout { + id: wrapper + width: root.width + spacing: 5 + ColumnLayout { + Layout.fillHeight: true + Layout.fillWidth: true + + Text { + id: titleText + text: model.title + wrapMode: Text.WordWrap + font.pointSize: 14 + font.bold: true + color: "white" + Layout.maximumWidth: wrapper.width * .9 + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + Qt.openUrlExternally(model.link) + } + } + } + + Text { + id: descriptionText + text: root.points + " Points • " + root.commentCount + + " Comments 🔗 " + "• Published: " + root.pubDateFormatted + wrapMode: Text.WordWrap + font.pointSize: 10 + opacity: .7 + color: "white" + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + Qt.openUrlExternally(model.commentsLink) + } + } + } + } + } +} diff --git a/Content/widget_rss_hackernews/Readme.md b/Content/widget_rss_hackernews/Readme.md new file mode 100644 index 00000000..ec528c58 --- /dev/null +++ b/Content/widget_rss_hackernews/Readme.md @@ -0,0 +1,3 @@ +Widget that shows the latest dw feed + +https://corporate.dw.com/en/rss/s-31500 \ No newline at end of file diff --git a/Content/widget_rss_hackernews/main.qml b/Content/widget_rss_hackernews/main.qml new file mode 100644 index 00000000..87708c2c --- /dev/null +++ b/Content/widget_rss_hackernews/main.qml @@ -0,0 +1,117 @@ + +// SPDX-License-Identifier: BSD-3-Clause +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQml.XmlListModel +import ScreenPlayAssets + +Item { + id: root + implicitWidth: 480 + implicitHeight: 480 + ColumnLayout { + anchors.fill: parent + anchors.margins: 10 + + RowLayout { + Layout.fillWidth: true + ComboBox { + id: combo + Layout.fillWidth: true + Layout.preferredWidth: 1 + Layout.preferredHeight: 50 + valueRole: "rssurl" + textRole: "text" + Material.foreground: "white" + model: ListModel { + ListElement { + text: "Best" + rssurl: "https://hnrss.org/best" + } + ListElement { + text: "Front Page" + rssurl: "https://hnrss.org/frontpage" + } + ListElement { + text: "Jobs" + rssurl: "https://hnrss.org/jobs" + } + ListElement { + text: "Newest > 100 pts" + rssurl: "https://hnrss.org/newest?points=100" + } + } + onActivated: { + rssModel.source = combo.currentValue + } + } + ToolButton { + text: "Reload" + Material.foreground: "white" + onPressed: rssModel.load() + } + } + + ListView { + id: list + Layout.fillWidth: true + Layout.fillHeight: true + spacing: 10 + clip: true + model: rssModel + delegate: PostDelegate { + width: root.width + description: model.description + pubDate: model.pubDate + } + } + } + Timer { + interval: 15 * 60 * 1000 // 15 minutes + running: true + repeat: true + onTriggered: rssModel.load() + } + XmlListModel { + id: rssModel + source: combo.currentValue + query: "/rss/channel/item" + function load() { + print(":load") + var tempSource = rssModel.source + rssModel.source = "" + rssModel.source = tempSource + } + + XmlListModelRole { + name: "title" + elementName: "title" + } + XmlListModelRole { + name: "link" + elementName: "link" + } + XmlListModelRole { + name: "creator" + elementName: "dc:creator" + } + XmlListModelRole { + name: "commentsLink" + elementName: "comments" + } + XmlListModelRole { + name: "guid" + elementName: "guid" + } + XmlListModelRole { + name: "description" + elementName: "description" + } + XmlListModelRole { + name: "pubDate" + elementName: "pubDate" + } + } +} diff --git a/Content/widget_rss_hackernews/preview.png b/Content/widget_rss_hackernews/preview.png new file mode 100644 index 00000000..022b7d37 Binary files /dev/null and b/Content/widget_rss_hackernews/preview.png differ diff --git a/Content/widget_rss_hackernews/project.json b/Content/widget_rss_hackernews/project.json new file mode 100644 index 00000000..2811afff --- /dev/null +++ b/Content/widget_rss_hackernews/project.json @@ -0,0 +1,12 @@ +{ + "description": "Widget that shows the latest hackernews feed", + "file": "main.qml", + "preview": "preview.png", + "tags": [ + "hackernews", + "rss", + "feed" + ], + "title": "hackernews", + "type": "qmlWidget" +} \ No newline at end of file diff --git a/Content/widget_rss_reddit/PostDelegate.qml b/Content/widget_rss_reddit/PostDelegate.qml deleted file mode 100644 index 0a1d2dc6..00000000 --- a/Content/widget_rss_reddit/PostDelegate.qml +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - implicitHeight: 300 - implicitWidth: 300 - - property string contentRaw: model.content - property url href - onContentRawChanged: { - // Define the regular expression to match the image URL - var regex = /\[link\]<\/a>/i; - - // Parse the image URL from the HTML content - var match = regex.exec(contentRaw); - if (match != null) { - var imageUrl = match[1]; - var href = match[2]; - img.source = "" + imageUrl; - root.href = "" + href; - } - } - - Image { - id: img - asynchronous: true - anchors.fill: parent - clip: true - fillMode: Image.PreserveAspectCrop - } - Rectangle { - anchors.fill: img - gradient: Gradient { - GradientStop { - position: 0 - color: "#00333333" - } - GradientStop { - position: 1 - color: "#ff333333" - } - } - } - - Text { - anchors { - right: parent.right - bottom: parent.bottom - left: parent.left - leftMargin: 10 - } - wrapMode: Text.Wrap - width: parent.width - text: model.title - height: 20 - color: "white" - } - MouseArea { - anchors.fill: parent - onClicked: { - print(model.link); - Qt.openUrlExternally(model.link); - } - } -} diff --git a/Content/widget_rss_reddit/Readme.md b/Content/widget_rss_reddit/Readme.md deleted file mode 100644 index cbc8e706..00000000 --- a/Content/widget_rss_reddit/Readme.md +++ /dev/null @@ -1 +0,0 @@ -Widget that shows the latest reddit feed \ No newline at end of file diff --git a/Content/widget_rss_reddit/main.qml b/Content/widget_rss_reddit/main.qml deleted file mode 100644 index 3e2d0ddd..00000000 --- a/Content/widget_rss_reddit/main.qml +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -import QtQuick -import QtQuick.Controls -import QtQuick.Controls.Material -import QtQuick.Effects -import QtQuick.Particles -import QtQml.XmlListModel - -Item { - id: root - implicitWidth: 480 - implicitHeight: 480 - - property string subreddit: "funny" - - XmlListModel { - id: feedModel - onStatusChanged: { - print("status ", status); - if (status === XmlListModel.Error) { - console.log("Error: " + errorString); - } - } - - source: "https://www.reddit.com/r/" + root.subreddit + "/.rss" - query: "/feed/entry" - - XmlListModelRole { - name: "updated" - elementName: "updated" - } - XmlListModelRole { - name: "subtitle" - elementName: "subtitle" - } - XmlListModelRole { - name: "content" - elementName: "content" - } - XmlListModelRole { - name: "link" - elementName: "link" - attributeName: "href" - } - XmlListModelRole { - name: "title" - elementName: "title" - } - } - - ListView { - id: list - anchors.fill: parent - model: feedModel - delegate: PostDelegate { - width: parent.width - } - } -} diff --git a/Content/widget_rss_reddit/preview.png b/Content/widget_rss_reddit/preview.png deleted file mode 100644 index bf792d29..00000000 Binary files a/Content/widget_rss_reddit/preview.png and /dev/null differ diff --git a/Content/widget_rss_reddit/project.json b/Content/widget_rss_reddit/project.json deleted file mode 100644 index 9f805672..00000000 --- a/Content/widget_rss_reddit/project.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "description": "Widget that shows the latest reddit feed", - "file": "main.qml", - "preview": "preview.png", - "tags": [ - "reddit" - ], - "title": "reddit", - "type": "qmlWidget", - "properties": { - "subreddit": { - "type": "string", - "value": "funny" - } - } -} diff --git a/Content/widget_system_stats/main.qml b/Content/widget_system_stats/main.qml index d621a1bc..abe23e9a 100644 --- a/Content/widget_system_stats/main.qml +++ b/Content/widget_system_stats/main.qml @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: BSD-3-Clause import QtQuick import QtQuick.Layouts import QtQuick.Controls @@ -28,11 +28,11 @@ Item { } function stringListToString(list) { - let out = ""; + let out = "" for (var i = 0; i < list.length; i++) { - out += "\n" + list[i]; + out += "\n" + list[i] } - return out; + return out } RowLayout { @@ -57,7 +57,8 @@ Item { } } Text { - text: root.stringListToString(ipAddress.privateIpV4AddressList) + text: root.stringListToString( + ipAddress.privateIpV4AddressList) color: root.accentColor font { pointSize: 16 @@ -65,7 +66,8 @@ Item { } } Text { - text: root.stringListToString(ipAddress.privateIpV6AddressList) + text: root.stringListToString( + ipAddress.privateIpV6AddressList) color: root.accentColor font { pointSize: 16 diff --git a/Content/widget_weather/main.qml b/Content/widget_weather/main.qml index c5e2c180..4f934ada 100644 --- a/Content/widget_weather/main.qml +++ b/Content/widget_weather/main.qml @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: BSD-3-Clause import QtQuick import QtQuick.Layouts import QtQuick.Controls @@ -20,56 +20,56 @@ Item { id: weather city: "Friedrichshafen" onReady: { - rp.model = weather.days; + rp.model = weather.days // Qt bug https://bugreports.qt.io/browse/QTBUG-105137 - test(); + test() } } - function test() { - } + function test() {} function mapWeatherCode(code) { - const weather_time = ""; // or "-day", "-night" - const weather_prefix = "wi" + weather_time + "-"; + const weather_time = "" + // or "-day", "-night" + const weather_prefix = "wi" + weather_time + "-" // https://open-meteo.com/en/docs // WMO Weather interpretation codes (WW) // to https://erikflowers.github.io/weather-icons/ switch (code) { case 0: - return weather_prefix + "day-sunny"; + return weather_prefix + "day-sunny" case 1: case 2: case 3: - return weather_prefix + "cloud"; + return weather_prefix + "cloud" case 45: case 48: - return weather_prefix + "day-sunny"; + return weather_prefix + "day-sunny" case 51: case 53: case 55: - return weather_prefix + "rain-mix"; + return weather_prefix + "rain-mix" case 61: case 63: case 65: - return weather_prefix + "rain-mix"; + return weather_prefix + "rain-mix" case 71: case 73: case 75: - return weather_prefix + "snow"; + return weather_prefix + "snow" case 77: - return weather_prefix + "snow"; + return weather_prefix + "snow" case 80: case 81: case 82: - return weather_prefix + "snow"; + return weather_prefix + "snow" case 85: case 86: - return weather_prefix + "snow"; + return weather_prefix + "snow" case 95: - return weather_prefix + "thunderstorm"; + return weather_prefix + "thunderstorm" case 96: case 99: - return weather_prefix + "storm-showers"; + return weather_prefix + "storm-showers" } } @@ -89,7 +89,9 @@ Item { Layout.alignment: Qt.AlignCenter horizontalAlignment: Text.AlignHCenter color: Material.primaryTextColor - text: "longtitude: " + weather.longtitude + " - latitude: " + weather.latitude + " - elevation: " + weather.elevation + "m - population: " + weather.population + text: "longtitude: " + weather.longtitude + " - latitude: " + + weather.latitude + " - elevation: " + weather.elevation + + "m - population: " + weather.population } RowLayout { @@ -127,7 +129,8 @@ Item { } Layout.alignment: Qt.AlignCenter horizontalAlignment: Image.AlignHCenter - source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode(weatherCode) + ".svg" + source: "qrc:/qml/ScreenPlayWeather/assets/icons/" + root.mapWeatherCode( + weatherCode) + ".svg" } TextItem { text: "Weather Code" diff --git a/Content/widget_xkcd/main.qml b/Content/widget_xkcd/main.qml index 2142ce05..377b6706 100644 --- a/Content/widget_xkcd/main.qml +++ b/Content/widget_xkcd/main.qml @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: BSD-3-Clause +// SPDX-License-Identifier: BSD-3-Clause import QtQuick import QtQuick.Controls import QtQuick.Controls.Material @@ -8,45 +8,84 @@ import QtQuick.Particles Item { id: root - implicitWidth: 360 - implicitHeight: 360 + state: "normal" + implicitWidth: defaultWidth + implicitHeight: defaultHeight + property int defaultWidth: 200 + property int defaultHeight: 200 - Image { - id: img - anchors.fill: parent - onStatusChanged: { - if (img.status !== Image.Ready) - return; - if (img.sourceSize.width === 0 || img.sourceSize.height === 0) - return; - root.implicitHeight = img.sourceSize.height; - root.implicitWidth = img.sourceSize.width; - } - - fillMode: Image.PreserveAspectCrop + function request(url, callback) { + var xhr = new XMLHttpRequest() + xhr.onreadystatechange = (function (myxhr) { + return function () { + if (myxhr.readyState === 4) + callback(myxhr) + } + })(xhr) + xhr.open('GET', url) + xhr.send('') } Component.onCompleted: { request("http://xkcd.com/info.0.json", function (o) { - if (o.status === 200) { - var d = eval('new Object(' + o.responseText + ')'); - console.log(o.responseText); - img.source = d.img; - } else { - console.log("Some error has occurred"); - } - }); + if (o.status === 200) { + var d = eval('new Object(' + o.responseText + ')') + console.log(o.responseText) + img.source = d.img + } else { + console.log("Some error has occurred") + } + }) } - function request(url, callback) { - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = (function (myxhr) { - return function () { - if (myxhr.readyState === 4) - callback(myxhr); - }; - })(xhr); - xhr.open('GET', url); - xhr.send(''); + Image { + id: img + anchors.fill: parent + fillMode: Image.PreserveAspectCrop + property size imgSize: Qt.size(root.defaultWidth, defaultHeight) + onStatusChanged: { + if (img.status !== Image.Ready) + return + if (img.sourceSize.width === 0 || img.sourceSize.height === 0) + return + root.implicitWidth = img.sourceSize.width + root.implicitHeight = img.sourceSize.height + print(img.status, img.sourceSize.width, img.sourceSize.height) + img.imgSize = Qt.size(img.sourceSize.width, img.sourceSize.height) + print("img.size", img.imgSize) + } } + + MouseArea { + anchors.fill: parent + onClicked: { + root.state = root.state === "expanded" ? "normal" : "expanded" + print(root.state, root.implicitHeight, root.implicitWidth) + } + } + + states: [ + State { + PropertyChanges { + name: "normal" + root { + width: root.defaultWidth + height: root.defaultHeight + implicitWidth: root.defaultWidth + implicitHeight: root.defaultHeight + } + } + }, + State { + name: "expanded" + PropertyChanges { + root { + width: img.imgSize.width + height: img.imgSize.height + implicitWidth: img.imgSize.width + implicitHeight: img.imgSize.height + } + } + } + ] } diff --git a/Content/widget_countDown/main.qml b/Content/widget_year_count_down/main.qml similarity index 58% rename from Content/widget_countDown/main.qml rename to Content/widget_year_count_down/main.qml index 39fab9d4..dfddb45e 100644 --- a/Content/widget_countDown/main.qml +++ b/Content/widget_year_count_down/main.qml @@ -11,9 +11,17 @@ Item { implicitWidth: 240 implicitHeight: 120 property int totalHours: 24 - property int remainingHours: Math.max(0, Math.floor((new Date().setHours(24, 0, 0, 0) - new Date()) / 3600000)) - property int totalDays: new Date(new Date().getFullYear() + 1, 0, 1) - new Date() / (24 * 60 * 60 * 1000) - property int remainingDays: Math.max(0, Math.floor((new Date(new Date().getFullYear() + 1, 0, 1) - new Date()) / (24 * 60 * 60 * 1000))) + property int remainingHours: Math.max(0, Math.floor( + (new Date().setHours( + 24, 0, 0, + 0) - new Date()) / 3600000)) + property int totalDays: new Date(new Date().getFullYear() + 1, 0, + 1) - new Date() / (24 * 60 * 60 * 1000) + property int remainingDays: Math.max( + 0, Math.floor( + (new Date(new Date().getFullYear() + 1, + 0, + 1) - new Date()) / (24 * 60 * 60 * 1000))) Material.theme: Material.Dark Material.accent: Material.DeepOrange @@ -42,7 +50,11 @@ Item { running: true repeat: true onTriggered: { - remainingHours = Math.max(0, Math.floor((new Date().setHours(24, 0, 0, 0) - new Date()) / 3600000)); + remainingHours = Math.max( + 0, + Math.floor((new Date().setHours( + 24, 0, 0, + 0) - new Date()) / 3600000)) } } } @@ -69,7 +81,11 @@ Item { running: true repeat: true onTriggered: { - remainingDays = Math.max(0, Math.floor((new Date(new Date().getFullYear() + 1, 0, 1) - new Date()) / (24 * 60 * 60 * 1000))); + remainingDays = Math.max(0, + Math.floor((new Date(new Date().getFullYear( + ) + 1, + 0, 1) + - new Date()) / (24 * 60 * 60 * 1000))) } } } diff --git a/Content/widget_countDown/preview.png b/Content/widget_year_count_down/preview.png similarity index 100% rename from Content/widget_countDown/preview.png rename to Content/widget_year_count_down/preview.png diff --git a/Content/widget_countDown/project.json b/Content/widget_year_count_down/project.json similarity index 100% rename from Content/widget_countDown/project.json rename to Content/widget_year_count_down/project.json