diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
index 4f5bd1b2a..3bec57114 100644
--- a/apps/app-frontend/src/App.vue
+++ b/apps/app-frontend/src/App.vue
@@ -42,7 +42,7 @@ import ModrinthLoadingIndicator from '@/components/LoadingIndicatorBar.vue'
import { handleError, useNotifications } from '@/store/notifications.js'
import { command_listener, warning_listener } from '@/helpers/events.js'
import { type } from '@tauri-apps/plugin-os'
-import { areUpdatesEnabled, getOS, isDev, restartApp } from '@/helpers/utils.js'
+import { areUpdatesEnabled, getOS, isDev } from '@/helpers/utils.js'
import { debugAnalytics, initAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { getVersion } from '@tauri-apps/api/app'
@@ -59,7 +59,6 @@ import { get_opening_command, initialize_state } from '@/helpers/state'
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
import { renderString } from '@modrinth/utils'
import { useFetch } from '@/helpers/fetch.js'
-import { check } from '@tauri-apps/plugin-updater'
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'
@@ -72,6 +71,7 @@ import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
import UpdateModal from '@/components/ui/UpdateModal.vue'
import { get_available_capes, get_available_skins } from './helpers/skins'
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
+import { get as getSettings, set as setSettings } from '@/helpers/settings.ts'
const themeStore = useTheming()
@@ -347,6 +347,7 @@ async function handleCommand(e) {
}
const availableUpdate = ref(null)
+const updateSkipped = ref(false)
const updateModal = useTemplateRef('updateModal')
async function checkUpdates() {
if (!(await areUpdatesEnabled())) {
@@ -361,17 +362,30 @@ async function checkUpdates() {
}
const update = await invoke('plugin:updater|check')
- if (!!update) {
- console.log(`Update ${update.version} is available.`)
- if (update.version === availableUpdate.value?.version) {
- console.log(
- 'Skipping update modal because the new version is the same as the dismissed update',
- )
- } else {
- availableUpdate.value = update
- updateModal.value.show(update)
- }
+ if (!update) {
+ return
}
+
+ console.log(`Update ${update.version} is available.`)
+
+ if (update.version === availableUpdate.value?.version) {
+ console.log(
+ 'Skipping update modal because the new version is the same as the dismissed update',
+ )
+ return
+ }
+
+ availableUpdate.value = update
+
+ const settings = await getSettings()
+ if (settings.skipped_update === update.version) {
+ updateSkipped.value = true
+ console.log('Skipping update modal because the user chose to skip this update')
+ return
+ }
+
+ updateSkipped.value = false
+ updateModal.value.show(update)
}
await performCheck()
@@ -384,6 +398,23 @@ async function checkUpdates() {
)
}
+async function skipUpdate(version) {
+ updateSkipped.value = true
+ let settings = await getSettings()
+ settings.skipped_update = version
+ await setSettings(settings)
+}
+
+async function forceOpenUpdateModal() {
+ if (updateSkipped.value) {
+ updateSkipped.value = false
+ let settings = await getSettings()
+ settings.skipped_update = null
+ await setSettings(settings)
+ }
+ updateModal.value.show(availableUpdate.value)
+}
+
function handleClick(e) {
let target = e.target
while (target != null) {
@@ -425,7 +456,7 @@ function handleAuxClick(e) {
-
+
@@ -480,10 +511,11 @@ function handleAuxClick(e) {
-
-
+
+
+
diff --git a/apps/app-frontend/src/components/ui/UpdateModal.vue b/apps/app-frontend/src/components/ui/UpdateModal.vue
index 7aa165af5..fc831a777 100644
--- a/apps/app-frontend/src/components/ui/UpdateModal.vue
+++ b/apps/app-frontend/src/components/ui/UpdateModal.vue
@@ -17,12 +17,12 @@
-
-
+
{{ formatMessage(messages.skip) }}
@@ -40,6 +40,10 @@ import { getUpdateSize } from '@/helpers/utils'
import { formatBytes } from '@modrinth/utils'
import { handleError } from '@/store/notifications'
+const emit = defineEmits<{
+ (e: 'updateSkipped', version: string): void
+}>()
+
const { formatMessage } = useVIntl()
const messages = defineMessages({
@@ -100,6 +104,11 @@ function hide() {
}
defineExpose({ show, hide, isOpen })
+
+function skipUpdate() {
+ hide()
+ emit('updateSkipped', update.value!.version)
+}
diff --git a/apps/app-frontend/src/helpers/settings.ts b/apps/app-frontend/src/helpers/settings.ts
index c256575a4..6b00e9bb8 100644
--- a/apps/app-frontend/src/helpers/settings.ts
+++ b/apps/app-frontend/src/helpers/settings.ts
@@ -62,6 +62,7 @@ export type AppSettings = {
developer_mode: boolean
feature_flags: Record
+ skipped_update: string | null
}
// Get full settings object
diff --git a/apps/app-frontend/src/helpers/utils.js b/apps/app-frontend/src/helpers/utils.js
index e5d1568c5..1cda120de 100644
--- a/apps/app-frontend/src/helpers/utils.js
+++ b/apps/app-frontend/src/helpers/utils.js
@@ -45,13 +45,6 @@ export async function restartApp() {
return await invoke('restart_app')
}
-/**
- * @deprecated This method is no longer needed, and just returns its parameter
- */
-export function sanitizePotentialFileUrl(url) {
- return url
-}
-
export const releaseColor = (releaseType) => {
switch (releaseType) {
case 'release':
diff --git a/packages/app-lib/.sqlx/query-3613473fb4d836ee0fb3c292e6bf5e50912064c29ebf1a1e5ead79c44c37e64c.json b/packages/app-lib/.sqlx/query-6dd3b14f3736735ee9a734062c990d152b0ffb7abf87a729931dc6c54754be6d.json
similarity index 86%
rename from packages/app-lib/.sqlx/query-3613473fb4d836ee0fb3c292e6bf5e50912064c29ebf1a1e5ead79c44c37e64c.json
rename to packages/app-lib/.sqlx/query-6dd3b14f3736735ee9a734062c990d152b0ffb7abf87a729931dc6c54754be6d.json
index 2fce764bc..63320e4c4 100644
--- a/packages/app-lib/.sqlx/query-3613473fb4d836ee0fb3c292e6bf5e50912064c29ebf1a1e5ead79c44c37e64c.json
+++ b/packages/app-lib/.sqlx/query-6dd3b14f3736735ee9a734062c990d152b0ffb7abf87a729931dc6c54754be6d.json
@@ -1,12 +1,12 @@
{
"db_name": "SQLite",
- "query": "\n UPDATE settings\n SET\n max_concurrent_writes = $1,\n max_concurrent_downloads = $2,\n\n theme = $3,\n default_page = $4,\n collapsed_navigation = $5,\n advanced_rendering = $6,\n native_decorations = $7,\n\n discord_rpc = $8,\n developer_mode = $9,\n telemetry = $10,\n personalized_ads = $11,\n\n onboarded = $12,\n\n extra_launch_args = jsonb($13),\n custom_env_vars = jsonb($14),\n mc_memory_max = $15,\n mc_force_fullscreen = $16,\n mc_game_resolution_x = $17,\n mc_game_resolution_y = $18,\n hide_on_process_start = $19,\n\n hook_pre_launch = $20,\n hook_wrapper = $21,\n hook_post_exit = $22,\n\n custom_dir = $23,\n prev_custom_dir = $24,\n migrated = $25,\n\n toggle_sidebar = $26,\n feature_flags = $27,\n hide_nametag_skins_page = $28\n ",
+ "query": "\n UPDATE settings\n SET\n max_concurrent_writes = $1,\n max_concurrent_downloads = $2,\n\n theme = $3,\n default_page = $4,\n collapsed_navigation = $5,\n advanced_rendering = $6,\n native_decorations = $7,\n\n discord_rpc = $8,\n developer_mode = $9,\n telemetry = $10,\n personalized_ads = $11,\n\n onboarded = $12,\n\n extra_launch_args = jsonb($13),\n custom_env_vars = jsonb($14),\n mc_memory_max = $15,\n mc_force_fullscreen = $16,\n mc_game_resolution_x = $17,\n mc_game_resolution_y = $18,\n hide_on_process_start = $19,\n\n hook_pre_launch = $20,\n hook_wrapper = $21,\n hook_post_exit = $22,\n\n custom_dir = $23,\n prev_custom_dir = $24,\n migrated = $25,\n\n toggle_sidebar = $26,\n feature_flags = $27,\n hide_nametag_skins_page = $28,\n skipped_update = $29\n ",
"describe": {
"columns": [],
"parameters": {
- "Right": 28
+ "Right": 29
},
"nullable": []
},
- "hash": "3613473fb4d836ee0fb3c292e6bf5e50912064c29ebf1a1e5ead79c44c37e64c"
+ "hash": "6dd3b14f3736735ee9a734062c990d152b0ffb7abf87a729931dc6c54754be6d"
}
diff --git a/packages/app-lib/.sqlx/query-6e3fa492c085ebb8e7280dd4d55cdcf73da199ea6ac05ee3ee798ece80d877cf.json b/packages/app-lib/.sqlx/query-6e3fa492c085ebb8e7280dd4d55cdcf73da199ea6ac05ee3ee798ece80d877cf.json
index 9742cb7b4..22e39e75b 100644
--- a/packages/app-lib/.sqlx/query-6e3fa492c085ebb8e7280dd4d55cdcf73da199ea6ac05ee3ee798ece80d877cf.json
+++ b/packages/app-lib/.sqlx/query-6e3fa492c085ebb8e7280dd4d55cdcf73da199ea6ac05ee3ee798ece80d877cf.json
@@ -41,7 +41,7 @@
{
"name": "display_claims!: serde_json::Value",
"ordinal": 7,
- "type_info": "Null"
+ "type_info": "Text"
}
],
"parameters": {
diff --git a/packages/app-lib/.sqlx/query-5193f519f021b2e7013cdb67a6e1a31ae4bd7532d02f8b00b43d5645351941ca.json b/packages/app-lib/.sqlx/query-cb20c8117eeec23ea1ebc2ef293caf425d722bd103cd6164c2b9d6abe5539aef.json
similarity index 93%
rename from packages/app-lib/.sqlx/query-5193f519f021b2e7013cdb67a6e1a31ae4bd7532d02f8b00b43d5645351941ca.json
rename to packages/app-lib/.sqlx/query-cb20c8117eeec23ea1ebc2ef293caf425d722bd103cd6164c2b9d6abe5539aef.json
index 5dc714e29..d87a4032c 100644
--- a/packages/app-lib/.sqlx/query-5193f519f021b2e7013cdb67a6e1a31ae4bd7532d02f8b00b43d5645351941ca.json
+++ b/packages/app-lib/.sqlx/query-cb20c8117eeec23ea1ebc2ef293caf425d722bd103cd6164c2b9d6abe5539aef.json
@@ -1,6 +1,6 @@
{
"db_name": "SQLite",
- "query": "\n SELECT\n max_concurrent_writes, max_concurrent_downloads,\n theme, default_page, collapsed_navigation, hide_nametag_skins_page, advanced_rendering, native_decorations,\n discord_rpc, developer_mode, telemetry, personalized_ads,\n onboarded,\n json(extra_launch_args) extra_launch_args, json(custom_env_vars) custom_env_vars,\n mc_memory_max, mc_force_fullscreen, mc_game_resolution_x, mc_game_resolution_y, hide_on_process_start,\n hook_pre_launch, hook_wrapper, hook_post_exit,\n custom_dir, prev_custom_dir, migrated, json(feature_flags) feature_flags, toggle_sidebar\n FROM settings\n ",
+ "query": "\n SELECT\n max_concurrent_writes, max_concurrent_downloads,\n theme, default_page, collapsed_navigation, hide_nametag_skins_page, advanced_rendering, native_decorations,\n discord_rpc, developer_mode, telemetry, personalized_ads,\n onboarded,\n json(extra_launch_args) extra_launch_args, json(custom_env_vars) custom_env_vars,\n mc_memory_max, mc_force_fullscreen, mc_game_resolution_x, mc_game_resolution_y, hide_on_process_start,\n hook_pre_launch, hook_wrapper, hook_post_exit,\n custom_dir, prev_custom_dir, migrated, json(feature_flags) feature_flags, toggle_sidebar,\n skipped_update\n FROM settings\n ",
"describe": {
"columns": [
{
@@ -142,6 +142,11 @@
"name": "toggle_sidebar",
"ordinal": 27,
"type_info": "Integer"
+ },
+ {
+ "name": "skipped_update",
+ "ordinal": 28,
+ "type_info": "Text"
}
],
"parameters": {
@@ -175,8 +180,9 @@
true,
false,
null,
- false
+ false,
+ true
]
},
- "hash": "5193f519f021b2e7013cdb67a6e1a31ae4bd7532d02f8b00b43d5645351941ca"
+ "hash": "cb20c8117eeec23ea1ebc2ef293caf425d722bd103cd6164c2b9d6abe5539aef"
}
diff --git a/packages/app-lib/migrations/20250708222117_add-skipped-updates.sql b/packages/app-lib/migrations/20250708222117_add-skipped-updates.sql
new file mode 100644
index 000000000..76003b85c
--- /dev/null
+++ b/packages/app-lib/migrations/20250708222117_add-skipped-updates.sql
@@ -0,0 +1,2 @@
+ALTER TABLE settings
+ADD COLUMN skipped_update TEXT NULL;
diff --git a/packages/app-lib/src/state/settings.rs b/packages/app-lib/src/state/settings.rs
index 2615e150e..44ac55674 100644
--- a/packages/app-lib/src/state/settings.rs
+++ b/packages/app-lib/src/state/settings.rs
@@ -38,6 +38,7 @@ pub struct Settings {
pub developer_mode: bool,
pub feature_flags: HashMap,
+ pub skipped_update: Option,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, Hash, PartialEq)]
@@ -63,7 +64,8 @@ impl Settings {
json(extra_launch_args) extra_launch_args, json(custom_env_vars) custom_env_vars,
mc_memory_max, mc_force_fullscreen, mc_game_resolution_x, mc_game_resolution_y, hide_on_process_start,
hook_pre_launch, hook_wrapper, hook_post_exit,
- custom_dir, prev_custom_dir, migrated, json(feature_flags) feature_flags, toggle_sidebar
+ custom_dir, prev_custom_dir, migrated, json(feature_flags) feature_flags, toggle_sidebar,
+ skipped_update
FROM settings
"
)
@@ -117,6 +119,7 @@ impl Settings {
.as_ref()
.and_then(|x| serde_json::from_str(x).ok())
.unwrap_or_default(),
+ skipped_update: res.skipped_update
})
}
@@ -170,7 +173,8 @@ impl Settings {
toggle_sidebar = $26,
feature_flags = $27,
- hide_nametag_skins_page = $28
+ hide_nametag_skins_page = $28,
+ skipped_update = $29
",
max_concurrent_writes,
max_concurrent_downloads,
@@ -199,7 +203,8 @@ impl Settings {
self.migrated,
self.toggle_sidebar,
feature_flags,
- self.hide_nametag_skins_page
+ self.hide_nametag_skins_page,
+ self.skipped_update
)
.execute(exec)
.await?;