diff --git a/Cargo.lock b/Cargo.lock
index 2cdc71294..60565594f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1648,10 +1648,29 @@ version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
dependencies = [
+ "percent-encoding",
"time",
"version_check",
]
+[[package]]
+name = "cookie_store"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9"
+dependencies = [
+ "cookie 0.18.1",
+ "document-features",
+ "idna",
+ "log",
+ "publicsuffix",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "time",
+ "url",
+]
+
[[package]]
name = "core-foundation"
version = "0.9.4"
@@ -1962,6 +1981,12 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
+[[package]]
+name = "data-url"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
+
[[package]]
name = "deadpool"
version = "0.12.2"
@@ -2245,6 +2270,15 @@ dependencies = [
"const-random",
]
+[[package]]
+name = "document-features"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
+dependencies = [
+ "litrs",
+]
+
[[package]]
name = "dotenv-build"
version = "0.1.1"
@@ -4574,6 +4608,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
+[[package]]
+name = "litrs"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
+
[[package]]
name = "local-channel"
version = "0.1.5"
@@ -6266,6 +6306,12 @@ dependencies = [
"thiserror 1.0.69",
]
+[[package]]
+name = "psl-types"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
+
[[package]]
name = "psm"
version = "0.1.26"
@@ -6295,6 +6341,16 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "publicsuffix"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf"
+dependencies = [
+ "idna",
+ "psl-types",
+]
+
[[package]]
name = "qoi"
version = "0.4.1"
@@ -6783,6 +6839,8 @@ dependencies = [
"async-compression",
"base64 0.22.1",
"bytes",
+ "cookie 0.18.1",
+ "cookie_store",
"encoding_rs",
"futures-channel",
"futures-core",
@@ -8676,6 +8734,30 @@ dependencies = [
"url",
]
+[[package]]
+name = "tauri-plugin-http"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c1a38da944b357ffa23bafd563b1579f18e6fbd118fcd84769406d35dcc5c7"
+dependencies = [
+ "bytes",
+ "cookie_store",
+ "data-url",
+ "http 1.3.1",
+ "regex",
+ "reqwest",
+ "schemars 0.8.22",
+ "serde",
+ "serde_json",
+ "tauri",
+ "tauri-plugin",
+ "tauri-plugin-fs",
+ "thiserror 2.0.12",
+ "tokio",
+ "url",
+ "urlpattern",
+]
+
[[package]]
name = "tauri-plugin-opener"
version = "2.4.0"
@@ -8989,6 +9071,7 @@ dependencies = [
"tauri-build",
"tauri-plugin-deep-link",
"tauri-plugin-dialog",
+ "tauri-plugin-http",
"tauri-plugin-opener",
"tauri-plugin-os",
"tauri-plugin-single-instance",
diff --git a/apps/app-frontend/package.json b/apps/app-frontend/package.json
index 5f4cf3b01..6fccb56ce 100644
--- a/apps/app-frontend/package.json
+++ b/apps/app-frontend/package.json
@@ -20,6 +20,7 @@
"@sentry/vue": "^8.27.0",
"@tauri-apps/api": "^2.5.0",
"@tauri-apps/plugin-dialog": "^2.2.1",
+ "@tauri-apps/plugin-http": "^2.5.0",
"@tauri-apps/plugin-opener": "^2.2.6",
"@tauri-apps/plugin-os": "^2.2.1",
"@tauri-apps/plugin-updater": "^2.7.1",
diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
index 462edcdd4..5673661d4 100644
--- a/apps/app-frontend/src/App.vue
+++ b/apps/app-frontend/src/App.vue
@@ -25,7 +25,7 @@ import {
ButtonStyled,
Notifications,
OverflowMenu,
- useRelativeTime,
+ NewsArticleCard,
} from '@modrinth/ui'
import { useLoading, useTheming } from '@/store/state'
import ModrinthAppLogo from '@/assets/modrinth_app.svg?component'
@@ -62,15 +62,12 @@ import NavButton from '@/components/ui/NavButton.vue'
import { get as getCreds, login, logout } from '@/helpers/mr_auth.js'
import { get_user } from '@/helpers/cache.js'
import AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue'
-import dayjs from 'dayjs'
import PromotionWrapper from '@/components/ui/PromotionWrapper.vue'
import { hide_ads_window, init_ads_window } from '@/helpers/ads.js'
import FriendsList from '@/components/ui/friends/FriendsList.vue'
import { openUrl } from '@tauri-apps/plugin-opener'
import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
-const formatRelativeTime = useRelativeTime()
-
const themeStore = useTheming()
const news = ref([])
@@ -177,6 +174,7 @@ async function setupApp() {
'criticalAnnouncements',
true,
)
+ .then((response) => response.json())
.then((res) => {
if (res && res.header && res.body) {
criticalErrorMessage.value = res
@@ -188,11 +186,21 @@ async function setupApp() {
)
})
- useFetch(`https://modrinth.com/news/feed/articles.json`, 'news', true).then((res) => {
- if (res && res.articles) {
- news.value = res.articles
- }
- })
+ useFetch(`https://modrinth.com/news/feed/articles.json`, 'news', true)
+ .then((response) => response.json())
+ .then((res) => {
+ if (res && res.articles) {
+ // Format expected by NewsArticleCard component.
+ news.value = res.articles.map((article) => ({
+ ...article,
+ path: article.link,
+ thumbnail: article.thumbnail,
+ title: article.title,
+ summary: article.summary,
+ date: article.date,
+ }))
+ }
+ })
get_opening_command().then(handleCommand)
checkUpdates()
@@ -579,34 +587,15 @@ function handleAuxClick(e) {
{{ item.summary }}
-- {{ formatRelativeTime(dayjs(item.date).toISOString()) }} -
- -