refactor: move handleError to main notification manager class
This commit is contained in:
parent
444ace8e54
commit
c0f9bc0f48
@ -1,12 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { add_project_from_path } from '@/helpers/profile.js'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { DropdownIcon, FolderOpenIcon, PlusIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, injectNotificationManager, OverflowMenu } from '@modrinth/ui'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
|
||||
@ -4,7 +4,6 @@ import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { get_user_many } from '@/helpers/cache'
|
||||
import { friend_listener } from '@/helpers/events'
|
||||
import { add_friend, friend_statuses, friends, remove_friend } from '@/helpers/friends'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import {
|
||||
MailIcon,
|
||||
MoreVerticalIcon,
|
||||
@ -24,7 +23,7 @@ import type { Dayjs } from 'dayjs'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { duplicate, edit, edit_icon, list, remove } from '@/helpers/profile'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { CopyIcon, EditIcon, PlusIcon, SpinnerIcon, TrashIcon, UploadIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
@ -18,7 +17,7 @@ import { computed, ref, type Ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { GameInstance, InstanceSettingsTabProps } from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const router = useRouter()
|
||||
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { edit } from '@/helpers/profile'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { Checkbox, injectNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import type { AppSettings, Hooks, InstanceSettingsTabProps } from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<InstanceSettingsTabProps>()
|
||||
|
||||
@ -6,7 +6,6 @@ import { get_project, get_version_many } from '@/helpers/cache'
|
||||
import { get_loader_versions } from '@/helpers/metadata'
|
||||
import { edit, install, update_repair_modrinth } from '@/helpers/profile'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import {
|
||||
DownloadIcon,
|
||||
HammerIcon,
|
||||
@ -42,7 +41,7 @@ import type {
|
||||
ManifestLoaderVersion,
|
||||
} from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const repairConfirmModal = ref()
|
||||
|
||||
@ -3,14 +3,13 @@ import JavaSelector from '@/components/ui/JavaSelector.vue'
|
||||
import useMemorySlider from '@/composables/useMemorySlider'
|
||||
import { edit, get_optimal_jre_key } from '@/helpers/profile'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { CheckCircleIcon, XCircleIcon } from '@modrinth/assets'
|
||||
import { Checkbox, injectNotificationManager, Slider } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { computed, readonly, ref, watch } from 'vue'
|
||||
import type { AppSettings, InstanceSettingsTabProps, MemorySettings } from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<InstanceSettingsTabProps>()
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { edit } from '@/helpers/profile'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { Checkbox, injectNotificationManager, Toggle } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { computed, ref, type Ref, watch } from 'vue'
|
||||
import type { AppSettings, InstanceSettingsTabProps } from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<InstanceSettingsTabProps>()
|
||||
|
||||
@ -113,7 +113,6 @@ import {
|
||||
type Skin,
|
||||
type SkinModel,
|
||||
} from '@/helpers/skins.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import {
|
||||
CheckIcon,
|
||||
ChevronRightIcon,
|
||||
@ -133,7 +132,7 @@ import {
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref, useTemplateRef, watch } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const modal = useTemplateRef('modal')
|
||||
const selectCapeModal = useTemplateRef('selectCapeModal')
|
||||
|
||||
@ -6,7 +6,6 @@ import { get_by_profile_path } from '@/helpers/process'
|
||||
import { kill, run } from '@/helpers/profile'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { showProfileInFolder } from '@/helpers/utils'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import {
|
||||
EyeIcon,
|
||||
@ -33,7 +32,7 @@ import dayjs from 'dayjs'
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@ import {
|
||||
start_join_server,
|
||||
start_join_singleplayer_world,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import { useTheming } from '@/store/theme.ts'
|
||||
import { GAME_MODES, HeadingLink, injectNotificationManager } from '@modrinth/ui'
|
||||
@ -26,7 +25,7 @@ import type { Dayjs } from 'dayjs'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const props = defineProps<{
|
||||
recentInstances: GameInstance[]
|
||||
|
||||
@ -4,13 +4,12 @@ import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import ServerModalBody from '@/components/ui/world/modal/ServerModalBody.vue'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { add_server_to_profile, type ServerPackStatus, type ServerWorld } from '@/helpers/worlds.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { PlayIcon, PlusIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@ -10,13 +10,12 @@ import {
|
||||
type ServerPackStatus,
|
||||
type ServerWorld,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { SaveIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessage, useVIntl } from '@vintl/vintl'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@ -4,13 +4,12 @@ import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.v
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import type { DisplayStatus, SingleplayerWorld } from '@/helpers/worlds.ts'
|
||||
import { rename_world, reset_world_icon, set_world_display_status } from '@/helpers/worlds.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { ChevronRightIcon, SaveIcon, UndoIcon, XIcon } from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { arrayBufferToBase64 } from '@modrinth/utils'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
@ -40,7 +39,7 @@ export const DEFAULT_MODELS: Record<string, SkinModel> = {
|
||||
|
||||
export function filterSavedSkins(list: Skin[]) {
|
||||
const customSkins = list.filter((s) => s.source !== 'default')
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
fixUnknownSkins(customSkins).catch(handleError)
|
||||
return customSkins
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import SearchCard from '@/components/ui/SearchCard.vue'
|
||||
import { get_search_results } from '@/helpers/cache.js'
|
||||
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile.js'
|
||||
import { get_categories, get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { ClipboardCopyIcon, ExternalIcon, GlobeIcon, SearchIcon, XIcon } from '@modrinth/assets'
|
||||
import type { Category, GameVersion, Platform, ProjectType, SortType, Tags } from '@modrinth/ui'
|
||||
@ -29,7 +28,7 @@ import { computed, nextTick, ref, shallowRef, watch } from 'vue'
|
||||
import type { LocationQuery } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -5,7 +5,6 @@ import { get_search_results } from '@/helpers/cache.js'
|
||||
import { profile_listener } from '@/helpers/events'
|
||||
import { list } from '@/helpers/profile.js'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import type { SearchResult } from '@modrinth/utils'
|
||||
@ -13,7 +12,7 @@ import dayjs from 'dayjs'
|
||||
import { computed, onUnmounted, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
const breadcrumbs = useBreadcrumbs()
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ import {
|
||||
remove_custom_skin,
|
||||
set_default_cape,
|
||||
} from '@/helpers/skins.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import {
|
||||
EditIcon,
|
||||
@ -48,7 +47,7 @@ const editSkinModal = useTemplateRef('editSkinModal')
|
||||
const selectCapeModal = useTemplateRef('selectCapeModal')
|
||||
const uploadSkinModal = useTemplateRef('uploadSkinModal')
|
||||
|
||||
const notifications = injectNotificationManager() as AppNotificationManager
|
||||
const notifications = injectNotificationManager()
|
||||
const { handleError } = notifications
|
||||
|
||||
const settings = ref(await getSettings())
|
||||
|
||||
@ -273,7 +273,6 @@ import {
|
||||
} from '@/helpers/profile.js'
|
||||
import type { CacheBehaviour, ContentFile, GameInstance } from '@/helpers/types'
|
||||
import { highlightModInProfile } from '@/helpers/utils.js'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
ClipboardCopyIcon,
|
||||
@ -311,7 +310,7 @@ import dayjs from 'dayjs'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const props = defineProps<{
|
||||
instance: GameInstance
|
||||
|
||||
@ -151,7 +151,6 @@ import {
|
||||
start_join_server,
|
||||
start_join_singleplayer_world,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import type { AppNotificationManager } from '@/providers/app-notifications'
|
||||
import { PlusIcon, SearchIcon, SpinnerIcon, UpdatedIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Button,
|
||||
@ -168,7 +167,7 @@ import { defineMessages } from '@vintl/vintl'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager() as AppNotificationManager
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
|
||||
const addServerModal = ref<InstanceType<typeof AddServerModal>>()
|
||||
|
||||
@ -1,33 +1,25 @@
|
||||
import {
|
||||
AbstractWebNotificationManager,
|
||||
type NotificationPanelLocation,
|
||||
type WebNotification,
|
||||
type WebNotificationLocation,
|
||||
} from '@modrinth/ui'
|
||||
import { ref, type Ref } from 'vue'
|
||||
|
||||
export class AppNotificationManager extends AbstractWebNotificationManager {
|
||||
private readonly state: Ref<WebNotification[]>
|
||||
private readonly locationState: Ref<WebNotificationLocation>
|
||||
private readonly locationState: Ref<NotificationPanelLocation>
|
||||
|
||||
public constructor() {
|
||||
super()
|
||||
this.state = ref<WebNotification[]>([])
|
||||
this.locationState = ref<WebNotificationLocation>('right')
|
||||
this.locationState = ref<NotificationPanelLocation>('right')
|
||||
}
|
||||
|
||||
public handleError = (error: Error): void => {
|
||||
this.addNotification({
|
||||
title: 'An error occurred',
|
||||
text: error.message ?? error,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
|
||||
public getNotificationLocation(): WebNotificationLocation {
|
||||
public getNotificationLocation(): NotificationPanelLocation {
|
||||
return this.locationState.value
|
||||
}
|
||||
|
||||
public setNotificationLocation(location: WebNotificationLocation): void {
|
||||
public setNotificationLocation(location: NotificationPanelLocation): void {
|
||||
this.locationState.value = location
|
||||
}
|
||||
|
||||
|
||||
@ -1,25 +1,28 @@
|
||||
import { useState } from "#app";
|
||||
import {
|
||||
type NotificationPanelLocation,
|
||||
type WebNotification,
|
||||
type WebNotificationLocation,
|
||||
AbstractWebNotificationManager,
|
||||
} from "@modrinth/ui";
|
||||
|
||||
export class FrontendNotificationManager extends AbstractWebNotificationManager {
|
||||
private readonly state: Ref<WebNotification[]>;
|
||||
private readonly locationState: Ref<WebNotificationLocation>;
|
||||
private readonly locationState: Ref<NotificationPanelLocation>;
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
this.state = useState<WebNotification[]>("notifications", () => []);
|
||||
this.locationState = useState<WebNotificationLocation>("notifications.location", () => "right");
|
||||
this.locationState = useState<NotificationPanelLocation>(
|
||||
"notifications.location",
|
||||
() => "right",
|
||||
);
|
||||
}
|
||||
|
||||
public getNotificationLocation(): WebNotificationLocation {
|
||||
public getNotificationLocation(): NotificationPanelLocation {
|
||||
return this.locationState.value;
|
||||
}
|
||||
|
||||
public setNotificationLocation(location: WebNotificationLocation): void {
|
||||
public setNotificationLocation(location: NotificationPanelLocation): void {
|
||||
this.locationState.value = location;
|
||||
}
|
||||
|
||||
|
||||
@ -10,35 +10,47 @@ export interface WebNotification {
|
||||
timer?: NodeJS.Timeout
|
||||
}
|
||||
|
||||
export type WebNotificationLocation = 'left' | 'right'
|
||||
export type NotificationPanelLocation = 'left' | 'right'
|
||||
|
||||
export abstract class AbstractWebNotificationManager {
|
||||
protected readonly AUTO_DISMISS_DELAY_MS = 30 * 1000
|
||||
|
||||
abstract getNotifications(): WebNotification[]
|
||||
abstract getNotificationLocation(): WebNotificationLocation
|
||||
abstract setNotificationLocation(location: WebNotificationLocation): void
|
||||
abstract getNotificationLocation(): NotificationPanelLocation
|
||||
abstract setNotificationLocation(location: NotificationPanelLocation): void
|
||||
|
||||
protected abstract addNotificationToStorage(notification: WebNotification): void
|
||||
protected abstract removeNotificationFromStorage(id: string | number): void
|
||||
protected abstract removeNotificationFromStorageByIndex(index: number): void
|
||||
protected abstract clearAllNotificationsFromStorage(): void
|
||||
|
||||
addNotification = (notification: Partial<WebNotification>): void => {
|
||||
addNotification = (notification: Partial<WebNotification>): WebNotification => {
|
||||
const existingNotif = this.findExistingNotification(notification)
|
||||
|
||||
if (existingNotif) {
|
||||
this.refreshNotificationTimer(existingNotif)
|
||||
existingNotif.count = (existingNotif.count || 0) + 1
|
||||
return
|
||||
return existingNotif
|
||||
}
|
||||
|
||||
const newNotification = this.createNotification(notification)
|
||||
this.setNotificationTimer(newNotification)
|
||||
this.addNotificationToStorage(newNotification)
|
||||
return newNotification
|
||||
}
|
||||
|
||||
removeNotification = (id: string | number): void => {
|
||||
/**
|
||||
* @deprecated You should use `addNotification` instead to provide a more human-readable error message to the user.
|
||||
*/
|
||||
handleError = (error: Error): void => {
|
||||
this.addNotification({
|
||||
title: 'An error occurred',
|
||||
text: error.message ?? error,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
|
||||
removeNotification = (id: string | number): WebNotification | undefined => {
|
||||
const notifications = this.getNotifications()
|
||||
const notification = notifications.find((n) => n.id === id)
|
||||
|
||||
@ -46,16 +58,22 @@ export abstract class AbstractWebNotificationManager {
|
||||
this.clearNotificationTimer(notification)
|
||||
this.removeNotificationFromStorage(id)
|
||||
}
|
||||
|
||||
return notification
|
||||
}
|
||||
|
||||
removeNotificationByIndex = (index: number): void => {
|
||||
removeNotificationByIndex = (index: number): WebNotification | null => {
|
||||
const notifications = this.getNotifications()
|
||||
|
||||
if (index >= 0 && index < notifications.length) {
|
||||
const notification = notifications[index]
|
||||
this.clearNotificationTimer(notification)
|
||||
this.removeNotificationFromStorageByIndex(index)
|
||||
|
||||
return notification
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
clearAllNotifications = (): void => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user