fix: hide modal header & add "Hide update reminder" button w/ tooltip
This commit is contained in:
parent
071e2b58b3
commit
0310cc52d0
@ -1,5 +1,14 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, onUnmounted, ref, watch, useTemplateRef, provide } from 'vue'
|
import {
|
||||||
|
computed,
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
useTemplateRef,
|
||||||
|
provide,
|
||||||
|
nextTick,
|
||||||
|
} from 'vue'
|
||||||
import { RouterView, useRoute, useRouter } from 'vue-router'
|
import { RouterView, useRoute, useRouter } from 'vue-router'
|
||||||
import {
|
import {
|
||||||
ArrowBigUpDashIcon,
|
ArrowBigUpDashIcon,
|
||||||
@ -72,6 +81,7 @@ import UpdateModal from '@/components/ui/UpdateModal.vue'
|
|||||||
import { get_available_capes, get_available_skins } from './helpers/skins'
|
import { get_available_capes, get_available_skins } from './helpers/skins'
|
||||||
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
|
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
|
||||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||||
|
import { createTooltip, destroyTooltip } from 'floating-vue'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
const themeStore = useTheming()
|
||||||
|
|
||||||
@ -450,6 +460,20 @@ async function forceOpenUpdateModal() {
|
|||||||
updateModal.value.show(availableUpdate.value)
|
updateModal.value.show(availableUpdate.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateButton = useTemplateRef('updateButton')
|
||||||
|
async function showUpdateButtonTooltip() {
|
||||||
|
await nextTick()
|
||||||
|
const tooltip = createTooltip(updateButton.value.$el, {
|
||||||
|
placement: 'right',
|
||||||
|
content: 'Click here to view the update again.',
|
||||||
|
})
|
||||||
|
tooltip.show()
|
||||||
|
setTimeout(() => {
|
||||||
|
tooltip.hide()
|
||||||
|
destroyTooltip(updateButton.value.$el)
|
||||||
|
}, 3500)
|
||||||
|
}
|
||||||
|
|
||||||
function handleClick(e) {
|
function handleClick(e) {
|
||||||
let target = e.target
|
let target = e.target
|
||||||
while (target != null) {
|
while (target != null) {
|
||||||
@ -495,6 +519,7 @@ function handleAuxClick(e) {
|
|||||||
ref="updateModal"
|
ref="updateModal"
|
||||||
@update-skipped="skipUpdate"
|
@update-skipped="skipUpdate"
|
||||||
@update-enqueued-for-later="updateEnqueuedForLater"
|
@update-enqueued-for-later="updateEnqueuedForLater"
|
||||||
|
@modal-hidden="showUpdateButtonTooltip"
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
@ -549,6 +574,7 @@ function handleAuxClick(e) {
|
|||||||
<div class="flex flex-grow"></div>
|
<div class="flex flex-grow"></div>
|
||||||
<NavButton
|
<NavButton
|
||||||
v-if="!!availableUpdate"
|
v-if="!!availableUpdate"
|
||||||
|
ref="updateButton"
|
||||||
v-tooltip.right="
|
v-tooltip.right="
|
||||||
enqueuedUpdate === availableUpdate?.version
|
enqueuedUpdate === availableUpdate?.version
|
||||||
? 'Update installation queued for next restart'
|
? 'Update installation queued for next restart'
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<ModalWrapper
|
<ModalWrapper ref="modal" hide-header :closable="false" :on-hide="onHide">
|
||||||
ref="modal"
|
|
||||||
:header="formatMessage(messages.header)"
|
|
||||||
:on-hide="onHide"
|
|
||||||
:closable="!updatingImmediately && !downloadInProgress"
|
|
||||||
>
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="max-w-[500px]">
|
<div class="w-[500px]">
|
||||||
<div class="font-extrabold text-contrast text-xl mb-1">
|
<div class="font-extrabold text-contrast text-xl">
|
||||||
Modrinth App v{{ update!.version }}
|
{{ formatMessage(messages.header) }} Modrinth App v{{ update!.version }}
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!downloadInProgress && !downloadError">
|
<template v-if="!downloadInProgress && !downloadError">
|
||||||
<div class="mb-4 leading-tight">{{ formatMessage(messages.bodyVersion) }}</div>
|
<div class="mb-1 leading-tight">{{ formatMessage(messages.bodyVersion) }}</div>
|
||||||
<div class="text-sm text-secondary mb-3">
|
<div class="text-sm text-secondary mb-2">
|
||||||
{{ formatMessage(messages.downloadSize, { size: formatBytes(updateSize) }) }}
|
{{ formatMessage(messages.downloadSize, { size: formatBytes(updateSize) }) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -49,7 +44,7 @@
|
|||||||
</ButtonStyled>
|
</ButtonStyled>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!downloadError" class="flex flex-wrap gap-2 w-full mb-2">
|
<div v-if="!downloadError" class="flex flex-wrap gap-2 w-full">
|
||||||
<JoinedButtons
|
<JoinedButtons
|
||||||
:actions="installActions"
|
:actions="installActions"
|
||||||
:disabled="updatingImmediately || downloadInProgress"
|
:disabled="updatingImmediately || downloadInProgress"
|
||||||
@ -74,7 +69,7 @@ import { defineMessages, useVIntl } from '@vintl/vintl'
|
|||||||
import { useTemplateRef, ref, computed } from 'vue'
|
import { useTemplateRef, ref, computed } from 'vue'
|
||||||
import { AppearingProgressBar, ButtonStyled, JoinedButtons } from '@modrinth/ui'
|
import { AppearingProgressBar, ButtonStyled, JoinedButtons } from '@modrinth/ui'
|
||||||
import type { JoinedButtonAction } from '@modrinth/ui'
|
import type { JoinedButtonAction } from '@modrinth/ui'
|
||||||
import { ExternalIcon, DownloadIcon, RedoIcon, ClipboardCopyIcon } from '@modrinth/assets'
|
import { ExternalIcon, DownloadIcon, RedoIcon, ClipboardCopyIcon, XIcon } from '@modrinth/assets'
|
||||||
import { enqueueUpdateForInstallation, getUpdateSize } from '@/helpers/utils'
|
import { enqueueUpdateForInstallation, getUpdateSize } from '@/helpers/utils'
|
||||||
import { formatBytes } from '@modrinth/utils'
|
import { formatBytes } from '@modrinth/utils'
|
||||||
import { handleError } from '@/store/notifications'
|
import { handleError } from '@/store/notifications'
|
||||||
@ -85,13 +80,14 @@ import { ChatIcon } from '@/assets/icons'
|
|||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'updateEnqueuedForLater', version: string | null): Promise<void>
|
(e: 'updateEnqueuedForLater', version: string | null): Promise<void>
|
||||||
|
(e: 'modalHidden'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
header: {
|
header: {
|
||||||
id: 'app.update.modal-header',
|
id: 'app.update.modal-header',
|
||||||
defaultMessage: 'An update is available!',
|
defaultMessage: 'Update available - ',
|
||||||
},
|
},
|
||||||
copiedError: {
|
copiedError: {
|
||||||
id: 'app.update.copied-error',
|
id: 'app.update.copied-error',
|
||||||
@ -131,6 +127,10 @@ const messages = defineMessages({
|
|||||||
id: 'app.update.try-again',
|
id: 'app.update.try-again',
|
||||||
defaultMessage: 'Try again',
|
defaultMessage: 'Try again',
|
||||||
},
|
},
|
||||||
|
hide: {
|
||||||
|
id: 'app.update.hide',
|
||||||
|
defaultMessage: 'Hide update reminder',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
type UpdateData = {
|
type UpdateData = {
|
||||||
@ -146,7 +146,7 @@ const update = ref<UpdateData>()
|
|||||||
const updateSize = ref<number>()
|
const updateSize = ref<number>()
|
||||||
|
|
||||||
const updatingImmediately = ref(false)
|
const updatingImmediately = ref(false)
|
||||||
const downloadInProgress = ref(true)
|
const downloadInProgress = ref(false)
|
||||||
const downloadProgress = ref(0)
|
const downloadProgress = ref(0)
|
||||||
const copiedError = ref(false)
|
const copiedError = ref(false)
|
||||||
const downloadError = ref<Error | null>(null)
|
const downloadError = ref<Error | null>(null)
|
||||||
@ -167,6 +167,15 @@ const installActions = computed<JoinedButtonAction[]>(() => [
|
|||||||
icon: RedoIcon,
|
icon: RedoIcon,
|
||||||
action: updateAtNextExit,
|
action: updateAtNextExit,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'hide',
|
||||||
|
label: formatMessage(messages.hide),
|
||||||
|
action: () => {
|
||||||
|
hide()
|
||||||
|
emit('modalHidden')
|
||||||
|
},
|
||||||
|
icon: XIcon,
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const downloadedBytes = computed(() => {
|
const downloadedBytes = computed(() => {
|
||||||
|
|||||||
@ -11,6 +11,10 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
hideHeader: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
closable: {
|
closable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
@ -53,6 +57,7 @@ function onModalHide() {
|
|||||||
:header="header"
|
:header="header"
|
||||||
:noblur="!themeStore.advancedRendering"
|
:noblur="!themeStore.advancedRendering"
|
||||||
:closable="closable"
|
:closable="closable"
|
||||||
|
:hide-header="hideHeader"
|
||||||
@hide="onModalHide"
|
@hide="onModalHide"
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
<div class="modal-body flex flex-col bg-bg-raised rounded-2xl">
|
<div class="modal-body flex flex-col bg-bg-raised rounded-2xl">
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
|
v-if="!hideHeader"
|
||||||
class="grid grid-cols-[auto_min-content] items-center gap-12 p-6 border-solid border-0 border-b-[1px] border-divider max-w-full"
|
class="grid grid-cols-[auto_min-content] items-center gap-12 p-6 border-solid border-0 border-b-[1px] border-divider max-w-full"
|
||||||
>
|
>
|
||||||
<div class="flex text-wrap break-words items-center gap-3 min-w-0">
|
<div class="flex text-wrap break-words items-center gap-3 min-w-0">
|
||||||
@ -60,6 +61,7 @@ const props = withDefaults(
|
|||||||
closeOnClickOutside?: boolean
|
closeOnClickOutside?: boolean
|
||||||
warnOnClose?: boolean
|
warnOnClose?: boolean
|
||||||
header?: string
|
header?: string
|
||||||
|
hideHeader?: boolean
|
||||||
onHide?: () => void
|
onHide?: () => void
|
||||||
onShow?: () => void
|
onShow?: () => void
|
||||||
}>(),
|
}>(),
|
||||||
@ -71,6 +73,7 @@ const props = withDefaults(
|
|||||||
closeOnEsc: true,
|
closeOnEsc: true,
|
||||||
warnOnClose: false,
|
warnOnClose: false,
|
||||||
header: undefined,
|
header: undefined,
|
||||||
|
hideHeader: false,
|
||||||
onHide: () => {},
|
onHide: () => {},
|
||||||
onShow: () => {},
|
onShow: () => {},
|
||||||
},
|
},
|
||||||
@ -134,7 +137,7 @@ function updateMousePosition(event: { clientX: number; clientY: number }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyDown(event: KeyboardEvent) {
|
function handleKeyDown(event: KeyboardEvent) {
|
||||||
if (props.closeOnEsc && event.key === 'Escape') {
|
if (props.closeOnEsc && event.key === 'Escape' && props.closable) {
|
||||||
hide()
|
hide()
|
||||||
mouseX.value = window.innerWidth / 2
|
mouseX.value = window.innerWidth / 2
|
||||||
mouseY.value = window.innerHeight / 2
|
mouseY.value = window.innerHeight / 2
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user