Implement skipping the update

This commit is contained in:
Josiah Glosson
2025-07-08 19:08:52 -05:00
parent 9a43d49b3b
commit ae75292fd0
9 changed files with 83 additions and 35 deletions

View File

@@ -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) {
<div id="teleports"></div>
<div v-if="stateInitialized" class="app-grid-layout experimental-styles-within relative">
<Suspense @resolve="checkUpdates">
<UpdateModal ref="updateModal" />
<UpdateModal ref="updateModal" @update-skipped="skipUpdate" />
</Suspense>
<Suspense>
<AppSettingsModal ref="settingsModal" />
@@ -480,10 +511,11 @@ function handleAuxClick(e) {
<NavButton
v-if="!!availableUpdate"
v-tooltip.right="'Update available'"
:to="() => updateModal.show(availableUpdate)"
:to="forceOpenUpdateModal"
>
<!-- TODO: Gray if updating on next restart -->
<DownloadIcon class="text-brand-green" />
<!-- TODO: Also gray if updating on next restart -->
<DownloadIcon v-if="updateSkipped" />
<DownloadIcon v-else class="text-brand-green" />
</NavButton>
<NavButton v-tooltip.right="'Settings'" :to="() => $refs.settingsModal.show()">
<SettingsIcon />

View File

@@ -17,12 +17,12 @@
</button>
</ButtonStyled>
<ButtonStyled>
<button @click="hide()">
<button @click="hide">
{{ formatMessage(messages.later) }}
</button>
</ButtonStyled>
<ButtonStyled color="red">
<button>
<button @click="skipUpdate">
{{ formatMessage(messages.skip) }}
</button>
</ButtonStyled>
@@ -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)
}
</script>
<style scoped lang="scss"></style>

View File

@@ -62,6 +62,7 @@ export type AppSettings = {
developer_mode: boolean
feature_flags: Record<FeatureFlag, boolean>
skipped_update: string | null
}
// Get full settings object

View File

@@ -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':

View File

@@ -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"
}

View File

@@ -41,7 +41,7 @@
{
"name": "display_claims!: serde_json::Value",
"ordinal": 7,
"type_info": "Null"
"type_info": "Text"
}
],
"parameters": {

View File

@@ -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"
}

View File

@@ -0,0 +1,2 @@
ALTER TABLE settings
ADD COLUMN skipped_update TEXT NULL;

View File

@@ -38,6 +38,7 @@ pub struct Settings {
pub developer_mode: bool,
pub feature_flags: HashMap<FeatureFlag, bool>,
pub skipped_update: Option<String>,
}
#[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?;