Compare commits
6 Commits
cal/depend
...
alex/db-se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b2362c794 | ||
|
|
86ea212373 | ||
|
|
ed8f176a52 | ||
|
|
35aeab98cd | ||
|
|
dcc563d7ad | ||
|
|
e31197f649 |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -4,7 +4,6 @@
|
||||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
|
||||
"editor.detectIndentation": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "always",
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,6 @@
|
||||
<script setup>
|
||||
import ModrinthAppLogo from '@/assets/modrinth_app.svg?component'
|
||||
import ModrinthLoadingIndicator from '@/components/LoadingIndicatorBar.vue'
|
||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
|
||||
import ErrorModal from '@/components/ui/ErrorModal.vue'
|
||||
import FriendsList from '@/components/ui/friends/FriendsList.vue'
|
||||
import IncompatibilityWarningModal from '@/components/ui/install_flow/IncompatibilityWarningModal.vue'
|
||||
import InstallConfirmModal from '@/components/ui/install_flow/InstallConfirmModal.vue'
|
||||
import ModInstallModal from '@/components/ui/install_flow/ModInstallModal.vue'
|
||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||
import AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue'
|
||||
import AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue'
|
||||
import NavButton from '@/components/ui/NavButton.vue'
|
||||
import PromotionWrapper from '@/components/ui/PromotionWrapper.vue'
|
||||
import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
|
||||
import RunningAppBar from '@/components/ui/RunningAppBar.vue'
|
||||
import SplashScreen from '@/components/ui/SplashScreen.vue'
|
||||
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
||||
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||
import { hide_ads_window, init_ads_window } from '@/helpers/ads.js'
|
||||
import { debugAnalytics, initAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
|
||||
import { get_user } from '@/helpers/cache.js'
|
||||
import { command_listener, warning_listener } from '@/helpers/events.js'
|
||||
import { useFetch } from '@/helpers/fetch.js'
|
||||
import { cancelLogin, get as getCreds, login, logout } from '@/helpers/mr_auth.js'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import { get_opening_command, initialize_state } from '@/helpers/state'
|
||||
import { getOS, isDev, restartApp } from '@/helpers/utils.js'
|
||||
import { useError } from '@/store/error.js'
|
||||
import { useInstall } from '@/store/install.js'
|
||||
import { useLoading, useTheming } from '@/store/state'
|
||||
import { computed, onMounted, onUnmounted, ref, watch, provide } from 'vue'
|
||||
import { RouterView, useRoute, useRouter } from 'vue-router'
|
||||
import {
|
||||
ArrowBigUpDashIcon,
|
||||
ChangeSkinIcon,
|
||||
@@ -42,44 +13,68 @@ import {
|
||||
LogOutIcon,
|
||||
MaximizeIcon,
|
||||
MinimizeIcon,
|
||||
NewspaperIcon,
|
||||
PlusIcon,
|
||||
RestoreIcon,
|
||||
RightArrowIcon,
|
||||
SettingsIcon,
|
||||
WorldIcon,
|
||||
XIcon,
|
||||
NewspaperIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
ButtonStyled,
|
||||
NewsArticleCard,
|
||||
NotificationPanel,
|
||||
Notifications,
|
||||
OverflowMenu,
|
||||
provideNotificationManager,
|
||||
NewsArticleCard,
|
||||
} from '@modrinth/ui'
|
||||
import { renderString } from '@modrinth/utils'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { useLoading, useTheming } from '@/store/state'
|
||||
import ModrinthAppLogo from '@/assets/modrinth_app.svg?component'
|
||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
|
||||
import RunningAppBar from '@/components/ui/RunningAppBar.vue'
|
||||
import SplashScreen from '@/components/ui/SplashScreen.vue'
|
||||
import ErrorModal from '@/components/ui/ErrorModal.vue'
|
||||
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 { check } from '@tauri-apps/plugin-updater'
|
||||
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
||||
import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
|
||||
import { RouterView, useRoute, useRouter } from 'vue-router'
|
||||
import { getOS, isDev, restartApp } 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'
|
||||
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
||||
import { create_profile_and_install_from_file } from './helpers/pack'
|
||||
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
|
||||
import { useError } from '@/store/error.js'
|
||||
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||
import ModInstallModal from '@/components/ui/install_flow/ModInstallModal.vue'
|
||||
import IncompatibilityWarningModal from '@/components/ui/install_flow/IncompatibilityWarningModal.vue'
|
||||
import InstallConfirmModal from '@/components/ui/install_flow/InstallConfirmModal.vue'
|
||||
import { useInstall } from '@/store/install.js'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
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 { cancelLogin, 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 AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue'
|
||||
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'
|
||||
import { get_available_capes, get_available_skins } from './helpers/skins'
|
||||
import { AppNotificationManager } from './providers/app-notifications'
|
||||
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const notificationManager = new AppNotificationManager()
|
||||
provideNotificationManager(notificationManager)
|
||||
const { handleError, addNotification } = notificationManager
|
||||
|
||||
const news = ref([])
|
||||
|
||||
const urlModal = ref(null)
|
||||
@@ -172,7 +167,7 @@ async function setupApp() {
|
||||
}
|
||||
|
||||
await warning_listener((e) =>
|
||||
addNotification({
|
||||
notificationsWrapper.value.addNotification({
|
||||
title: 'Warning',
|
||||
text: e.message,
|
||||
type: 'warn',
|
||||
@@ -256,6 +251,9 @@ const route = useRoute()
|
||||
const loading = useLoading()
|
||||
loading.setEnabled(false)
|
||||
|
||||
const notifications = useNotifications()
|
||||
const notificationsWrapper = ref()
|
||||
|
||||
const error = useError()
|
||||
const errorModal = ref()
|
||||
|
||||
@@ -337,6 +335,8 @@ watch(
|
||||
onMounted(() => {
|
||||
invoke('show_window')
|
||||
|
||||
notifications.setNotifs(notificationsWrapper.value)
|
||||
|
||||
error.setErrorModal(errorModal.value)
|
||||
|
||||
install.setIncompatibilityWarningModal(incompatibilityWarningModal)
|
||||
@@ -657,7 +657,7 @@ function handleAuxClick(e) {
|
||||
</div>
|
||||
</div>
|
||||
<URLConfirmModal ref="urlModal" />
|
||||
<NotificationPanel has-sidebar />
|
||||
<Notifications ref="notificationsWrapper" sidebar />
|
||||
<ErrorModal ref="errorModal" />
|
||||
<ModInstallModal ref="modInstallModal" />
|
||||
<IncompatibilityWarningModal ref="incompatibilityWarningModal" />
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
<script setup>
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import Instance from '@/components/ui/Instance.vue'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { duplicate, remove } from '@/helpers/profile.js'
|
||||
import { computed, ref } from 'vue'
|
||||
import {
|
||||
ClipboardCopyIcon,
|
||||
EyeIcon,
|
||||
FolderOpenIcon,
|
||||
PlayIcon,
|
||||
PlusIcon,
|
||||
SearchIcon,
|
||||
StopCircleIcon,
|
||||
TrashIcon,
|
||||
StopCircleIcon,
|
||||
EyeIcon,
|
||||
SearchIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Button, DropdownSelect, injectNotificationManager } from '@modrinth/ui'
|
||||
import { Button, DropdownSelect } from '@modrinth/ui'
|
||||
import { formatCategoryHeader } from '@modrinth/utils'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { duplicate, remove } from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
|
||||
const props = defineProps({
|
||||
instances: {
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
<script setup>
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import Instance from '@/components/ui/Instance.vue'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import ProjectCard from '@/components/ui/ProjectCard.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_by_profile_path } from '@/helpers/process.js'
|
||||
import { duplicate, kill, remove, run } from '@/helpers/profile.js'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
import {
|
||||
ClipboardCopyIcon,
|
||||
DownloadIcon,
|
||||
ExternalIcon,
|
||||
EyeIcon,
|
||||
FolderOpenIcon,
|
||||
GlobeIcon,
|
||||
PlayIcon,
|
||||
PlusIcon,
|
||||
StopCircleIcon,
|
||||
TrashIcon,
|
||||
DownloadIcon,
|
||||
GlobeIcon,
|
||||
StopCircleIcon,
|
||||
ExternalIcon,
|
||||
EyeIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { HeadingLink, injectNotificationManager } from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import Instance from '@/components/ui/Instance.vue'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import ProjectCard from '@/components/ui/ProjectCard.vue'
|
||||
import { get_by_profile_path } from '@/helpers/process.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { duplicate, kill, remove, run } from '@/helpers/profile.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { HeadingLink } from '@modrinth/ui'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
|
||||
@@ -73,23 +73,22 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { DropdownIcon, PlusIcon, TrashIcon, LogInIcon, SpinnerIcon } from '@modrinth/assets'
|
||||
import { Avatar, Button, Card } from '@modrinth/ui'
|
||||
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue'
|
||||
import {
|
||||
get_default_user,
|
||||
login as login_flow,
|
||||
users,
|
||||
remove_user,
|
||||
set_default_user,
|
||||
users,
|
||||
login as login_flow,
|
||||
get_default_user,
|
||||
} from '@/helpers/auth'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
import { get_available_skins } from '@/helpers/skins'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { DropdownIcon, LogInIcon, PlusIcon, SpinnerIcon, TrashIcon } from '@modrinth/assets'
|
||||
import { Avatar, Button, Card, injectNotificationManager } from '@modrinth/ui'
|
||||
import { computed, onBeforeUnmount, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { get_available_skins } from '@/helpers/skins'
|
||||
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
|
||||
defineProps({
|
||||
mode: {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { add_project_from_path } from '@/helpers/profile.js'
|
||||
import { DropdownIcon, FolderOpenIcon, PlusIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, injectNotificationManager, OverflowMenu } from '@modrinth/ui'
|
||||
import { DropdownIcon, PlusIcon, FolderOpenIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, OverflowMenu } from '@modrinth/ui'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { add_project_from_path } from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
type: Object,
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
<script setup>
|
||||
import { ChatIcon } from '@/assets/icons'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
||||
import { install } from '@/helpers/profile.js'
|
||||
import { cancel_directory_change } from '@/helpers/settings.ts'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import {
|
||||
CheckIcon,
|
||||
CopyIcon,
|
||||
DropdownIcon,
|
||||
XIcon,
|
||||
HammerIcon,
|
||||
LogInIcon,
|
||||
UpdatedIcon,
|
||||
XIcon,
|
||||
CopyIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { ButtonStyled, Collapsible, injectNotificationManager } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { ChatIcon } from '@/assets/icons'
|
||||
import { ButtonStyled, Collapsible } from '@modrinth/ui'
|
||||
import { ref, computed } from 'vue'
|
||||
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { cancel_directory_change } from '@/helpers/settings.ts'
|
||||
import { install } from '@/helpers/profile.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const errorModal = ref()
|
||||
const error = ref()
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<script setup>
|
||||
import { XIcon, PlusIcon } from '@modrinth/assets'
|
||||
import { Button, Checkbox } from '@modrinth/ui'
|
||||
import { PackageIcon, VersionIcon } from '@/assets/icons'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
|
||||
import { PlusIcon, XIcon } from '@modrinth/assets'
|
||||
import { Button, Checkbox, injectNotificationManager } from '@modrinth/ui'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
<script setup>
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import { get_by_profile_path } from '@/helpers/process'
|
||||
import { finish_install, kill, run } from '@/helpers/profile'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {
|
||||
DownloadIcon,
|
||||
GameIcon,
|
||||
@@ -13,13 +9,17 @@ import {
|
||||
StopCircleIcon,
|
||||
TimerIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, injectNotificationManager, useRelativeTime } from '@modrinth/ui'
|
||||
import { Avatar, ButtonStyled, useRelativeTime } from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { finish_install, kill, run } from '@/helpers/profile'
|
||||
import { get_by_profile_path } from '@/helpers/process'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -198,17 +198,6 @@
|
||||
|
||||
<script setup>
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import {
|
||||
get_default_launcher_path,
|
||||
get_importable_instances,
|
||||
import_instance,
|
||||
} from '@/helpers/import.js'
|
||||
import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
|
||||
import { create_profile_and_install_from_file } from '@/helpers/pack.js'
|
||||
import { create } from '@/helpers/profile'
|
||||
import { get_loaders } from '@/helpers/tags'
|
||||
import {
|
||||
CodeIcon,
|
||||
FolderOpenIcon,
|
||||
@@ -219,14 +208,24 @@ import {
|
||||
UploadIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, Button, Checkbox, Chips, injectNotificationManager } from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { Avatar, Button, Checkbox, Chips } from '@modrinth/ui'
|
||||
import { computed, onUnmounted, ref, shallowRef } from 'vue'
|
||||
import { get_loaders } from '@/helpers/tags'
|
||||
import { create } from '@/helpers/profile'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { create_profile_and_install_from_file } from '@/helpers/pack.js'
|
||||
import {
|
||||
get_default_launcher_path,
|
||||
get_importable_instances,
|
||||
import_instance,
|
||||
} from '@/helpers/import.js'
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||
|
||||
const profile_name = ref('')
|
||||
const game_version = ref('')
|
||||
|
||||
@@ -35,14 +35,13 @@
|
||||
</ModalWrapper>
|
||||
</template>
|
||||
<script setup>
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { find_filtered_jres } from '@/helpers/jre.js'
|
||||
import { CheckIcon, PlusIcon, XIcon } from '@modrinth/assets'
|
||||
import { Button, injectNotificationManager } from '@modrinth/ui'
|
||||
import { PlusIcon, CheckIcon, XIcon } from '@modrinth/assets'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { find_filtered_jres } from '@/helpers/jre.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const chosenInstallOptions = ref([])
|
||||
const detectJavaModal = ref(null)
|
||||
|
||||
@@ -52,22 +52,21 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { auto_install_java, find_filtered_jres, get_jre, test_jre } from '@/helpers/jre.js'
|
||||
import {
|
||||
CheckIcon,
|
||||
DownloadIcon,
|
||||
FolderSearchIcon,
|
||||
PlayIcon,
|
||||
SearchIcon,
|
||||
PlayIcon,
|
||||
CheckIcon,
|
||||
XIcon,
|
||||
FolderSearchIcon,
|
||||
DownloadIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Button, injectNotificationManager } from '@modrinth/ui'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import { auto_install_java, find_filtered_jres, get_jre, test_jre } from '@/helpers/jre.js'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const props = defineProps({
|
||||
version: {
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<script setup>
|
||||
import NavButton from '@/components/ui/NavButton.vue'
|
||||
import { profile_listener } from '@/helpers/events.js'
|
||||
import { list } from '@/helpers/profile'
|
||||
import { SpinnerIcon } from '@modrinth/assets'
|
||||
import { Avatar, injectNotificationManager } from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import dayjs from 'dayjs'
|
||||
import { onUnmounted, ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { profile_listener } from '@/helpers/events.js'
|
||||
import NavButton from '@/components/ui/NavButton.vue'
|
||||
import { Avatar } from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { SpinnerIcon } from '@modrinth/assets'
|
||||
|
||||
const recentInstances = ref([])
|
||||
const getInstances = async () => {
|
||||
|
||||
@@ -94,24 +94,23 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { loading_listener, process_listener } from '@/helpers/events'
|
||||
import { get_all as getRunningProcesses, kill as killProcess } from '@/helpers/process'
|
||||
import { get_many } from '@/helpers/profile.js'
|
||||
import { progress_bars_list } from '@/helpers/state.js'
|
||||
import {
|
||||
DownloadIcon,
|
||||
DropdownIcon,
|
||||
StopCircleIcon,
|
||||
TerminalSquareIcon,
|
||||
DropdownIcon,
|
||||
UnplugIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Button, ButtonStyled, Card, injectNotificationManager } from '@modrinth/ui'
|
||||
import { Button, ButtonStyled, Card } from '@modrinth/ui'
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { get_all as getRunningProcesses, kill as killProcess } from '@/helpers/process'
|
||||
import { loading_listener, process_listener } from '@/helpers/events'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { progress_bars_list } from '@/helpers/state.js'
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { get_many } from '@/helpers/profile.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
|
||||
const router = useRouter()
|
||||
const card = ref(null)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<script setup>
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||
import { get_project, get_version } from '@/helpers/cache.js'
|
||||
import { get_categories } from '@/helpers/tags.js'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
import { Button, injectNotificationManager } from '@modrinth/ui'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||
import { get_categories } from '@/helpers/tags.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { get_version, get_project } from '@/helpers/cache.js'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const confirmModal = ref(null)
|
||||
const project = ref(null)
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
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 { Avatar, ButtonStyled, OverflowMenu, useRelativeTime } from '@modrinth/ui'
|
||||
import {
|
||||
MailIcon,
|
||||
UserPlusIcon,
|
||||
MoreVerticalIcon,
|
||||
MailIcon,
|
||||
SettingsIcon,
|
||||
TrashIcon,
|
||||
UserPlusIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
useRelativeTime,
|
||||
} from '@modrinth/ui'
|
||||
import { ref, onUnmounted, watch, computed } from 'vue'
|
||||
import { friend_listener } from '@/helpers/events'
|
||||
import { friends, friend_statuses, add_friend, remove_friend } from '@/helpers/friends'
|
||||
import { get_user_many } from '@/helpers/cache'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import type { Dayjs } from 'dayjs'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -57,16 +57,15 @@
|
||||
|
||||
<script setup>
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||
import { DownloadIcon, XIcon } from '@modrinth/assets'
|
||||
import { Button, injectNotificationManager } from '@modrinth/ui'
|
||||
import { XIcon, DownloadIcon } from '@modrinth/assets'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import { formatCategory } from '@modrinth/utils'
|
||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||
import { ref } from 'vue'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const instance = ref(null)
|
||||
const project = ref(null)
|
||||
const versions = ref(null)
|
||||
@@ -77,10 +76,10 @@ const installing = ref(false)
|
||||
const onInstall = ref(() => {})
|
||||
|
||||
defineExpose({
|
||||
show: (instanceVal, projectVal, projectVersions, callback) => {
|
||||
show: (instanceVal, projectVal, projectVersions, selected, callback) => {
|
||||
instance.value = instanceVal
|
||||
versions.value = projectVersions
|
||||
selectedVersion.value = projectVersions[0]
|
||||
selectedVersion.value = selected ?? projectVersions[0]
|
||||
|
||||
project.value = projectVal
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<script setup>
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { create_profile_and_install as pack_install } from '@/helpers/pack'
|
||||
import { DownloadIcon, XIcon } from '@modrinth/assets'
|
||||
import { Button, injectNotificationManager } from '@modrinth/ui'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import { create_profile_and_install as pack_install } from '@/helpers/pack'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const versionId = ref()
|
||||
const project = ref()
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<script setup>
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import {
|
||||
check_installed,
|
||||
create,
|
||||
get,
|
||||
add_project_from_version as installMod,
|
||||
list,
|
||||
} from '@/helpers/profile'
|
||||
import { installVersionDependencies } from '@/store/install.js'
|
||||
import {
|
||||
CheckIcon,
|
||||
DownloadIcon,
|
||||
PlusIcon,
|
||||
RightArrowIcon,
|
||||
UploadIcon,
|
||||
XIcon,
|
||||
RightArrowIcon,
|
||||
CheckIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, Button, Card, injectNotificationManager } from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { Avatar, Button, Card } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import {
|
||||
add_project_from_version as installMod,
|
||||
check_installed,
|
||||
get,
|
||||
list,
|
||||
create,
|
||||
} from '@/helpers/profile'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { installVersionDependencies } from '@/store/install.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const router = useRouter()
|
||||
|
||||
const versions = ref()
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { duplicate, edit, edit_icon, list, remove } from '@/helpers/profile'
|
||||
import { CopyIcon, EditIcon, PlusIcon, SpinnerIcon, TrashIcon, UploadIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
} from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { SpinnerIcon, TrashIcon, UploadIcon, PlusIcon, EditIcon, CopyIcon } from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, OverflowMenu, Checkbox } from '@modrinth/ui'
|
||||
import { computed, ref, type Ref, watch } from 'vue'
|
||||
import { duplicate, edit, edit_icon, list, remove } from '@/helpers/profile'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { computed, ref, type Ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { GameInstance, InstanceSettingsTabProps } from '../../../helpers/types'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import type { InstanceSettingsTabProps, GameInstance } from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const router = useRouter()
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { edit } from '@/helpers/profile'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import { Checkbox, injectNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { Checkbox } from '@modrinth/ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import type { AppSettings, Hooks, InstanceSettingsTabProps } from '../../../helpers/types'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import { edit } from '@/helpers/profile'
|
||||
import type { InstanceSettingsTabProps, AppSettings, Hooks } from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<InstanceSettingsTabProps>()
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
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 {
|
||||
DownloadIcon,
|
||||
HammerIcon,
|
||||
IssuesIcon,
|
||||
SpinnerIcon,
|
||||
TransferIcon,
|
||||
UndoIcon,
|
||||
UnlinkIcon,
|
||||
UnplugIcon,
|
||||
IssuesIcon,
|
||||
HammerIcon,
|
||||
DownloadIcon,
|
||||
WrenchIcon,
|
||||
UndoIcon,
|
||||
SpinnerIcon,
|
||||
UnplugIcon,
|
||||
UnlinkIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
Chips,
|
||||
TeleportDropdownMenu,
|
||||
injectNotificationManager,
|
||||
} from '@modrinth/ui'
|
||||
import { Avatar, Checkbox, Chips, ButtonStyled, TeleportDropdownMenu } from '@modrinth/ui'
|
||||
import { computed, type ComputedRef, type Ref, ref, shallowRef, watch } from 'vue'
|
||||
import { edit, install, update_repair_modrinth } from '@/helpers/profile'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { get_loader_versions } from '@/helpers/metadata'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import {
|
||||
formatCategory,
|
||||
type GameVersionTag,
|
||||
@@ -32,16 +25,16 @@ import {
|
||||
type Project,
|
||||
type Version,
|
||||
} from '@modrinth/utils'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { get_project, get_version_many } from '@/helpers/cache'
|
||||
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, ref, shallowRef, watch, type ComputedRef, type Ref } from 'vue'
|
||||
import type {
|
||||
InstanceSettingsTabProps,
|
||||
Manifest,
|
||||
ManifestLoaderVersion,
|
||||
Manifest,
|
||||
} from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const repairConfirmModal = ref()
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
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 { Checkbox, Slider } from '@modrinth/ui'
|
||||
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'
|
||||
import { edit, get_optimal_jre_key } from '@/helpers/profile'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import JavaSelector from '@/components/ui/JavaSelector.vue'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import type { InstanceSettingsTabProps, AppSettings, MemorySettings } from '../../../helpers/types'
|
||||
import useMemorySlider from '@/composables/useMemorySlider'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<InstanceSettingsTabProps>()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { edit } from '@/helpers/profile'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import { Checkbox, injectNotificationManager, Toggle } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { Checkbox, Toggle } from '@modrinth/ui'
|
||||
import { computed, ref, type Ref, watch } from 'vue'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import { edit } from '@/helpers/profile'
|
||||
import type { AppSettings, InstanceSettingsTabProps } from '../../../helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<InstanceSettingsTabProps>()
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<script setup>
|
||||
import JavaSelector from '@/components/ui/JavaSelector.vue'
|
||||
import { get_java_versions, set_java_version } from '@/helpers/jre'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { get_java_versions, set_java_version } from '@/helpers/jre'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import JavaSelector from '@/components/ui/JavaSelector.vue'
|
||||
|
||||
const javaVersions = ref(await get_java_versions().catch(handleError))
|
||||
async function updateJavaVersion(version) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script setup>
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { purge_cache_types } from '@/helpers/cache.js'
|
||||
import { get, set } from '@/helpers/settings.ts'
|
||||
import { BoxIcon, FolderSearchIcon, TrashIcon } from '@modrinth/assets'
|
||||
import { Button, Slider, injectNotificationManager } from '@modrinth/ui'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { Button, Slider } from '@modrinth/ui'
|
||||
import { ref, watch } from 'vue'
|
||||
import { get, set } from '@/helpers/settings.ts'
|
||||
import { purge_cache_types } from '@/helpers/cache.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { BoxIcon, FolderSearchIcon, TrashIcon } from '@modrinth/assets'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const settings = ref(await get())
|
||||
|
||||
watch(
|
||||
|
||||
@@ -100,39 +100,37 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { ref, computed, watch, useTemplateRef } from 'vue'
|
||||
import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue'
|
||||
import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue'
|
||||
import {
|
||||
add_and_equip_custom_skin,
|
||||
determineModelType,
|
||||
get_normalized_skin_texture,
|
||||
remove_custom_skin,
|
||||
unequip_skin,
|
||||
type Cape,
|
||||
type Skin,
|
||||
type SkinModel,
|
||||
} from '@/helpers/skins.ts'
|
||||
import {
|
||||
CheckIcon,
|
||||
ChevronRightIcon,
|
||||
SaveIcon,
|
||||
SpinnerIcon,
|
||||
UploadIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
SkinPreviewRenderer,
|
||||
Button,
|
||||
ButtonStyled,
|
||||
RadioButtons,
|
||||
CapeButton,
|
||||
CapeLikeTextButton,
|
||||
injectNotificationManager,
|
||||
RadioButtons,
|
||||
SkinPreviewRenderer,
|
||||
ButtonStyled,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref, useTemplateRef, watch } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import {
|
||||
add_and_equip_custom_skin,
|
||||
remove_custom_skin,
|
||||
unequip_skin,
|
||||
type Skin,
|
||||
type Cape,
|
||||
type SkinModel,
|
||||
get_normalized_skin_texture,
|
||||
determineModelType,
|
||||
} from '@/helpers/skins.ts'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import {
|
||||
UploadIcon,
|
||||
CheckIcon,
|
||||
SaveIcon,
|
||||
XIcon,
|
||||
ChevronRightIcon,
|
||||
SpinnerIcon,
|
||||
} from '@modrinth/assets'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue'
|
||||
|
||||
const modal = useTemplateRef('modal')
|
||||
const selectCapeModal = useTemplateRef('selectCapeModal')
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onBeforeUnmount, watch } from 'vue'
|
||||
import { UploadIcon } from '@modrinth/assets'
|
||||
import { useNotifications } from '@/store/state'
|
||||
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { get_dragged_skin_data } from '@/helpers/skins'
|
||||
import { UploadIcon } from '@modrinth/assets'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||
import { onBeforeUnmount, ref, watch } from 'vue'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const notifications = useNotifications()
|
||||
|
||||
const modal = ref()
|
||||
const fileInput = ref<HTMLInputElement>()
|
||||
@@ -99,7 +99,7 @@ async function setupDragDropListener() {
|
||||
const data = await get_dragged_skin_data(filePath)
|
||||
await processData(data.buffer)
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
notifications.addNotification({
|
||||
title: 'Error processing file',
|
||||
text: error instanceof Error ? error.message : 'Failed to read the dropped file.',
|
||||
type: 'error',
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project } from '@/helpers/cache'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
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 { handleSevereError } from '@/store/error'
|
||||
import type { Dayjs } from 'dayjs'
|
||||
import dayjs from 'dayjs'
|
||||
import {
|
||||
EyeIcon,
|
||||
FolderOpenIcon,
|
||||
@@ -19,20 +13,25 @@ import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
SmartClickable,
|
||||
useRelativeTime,
|
||||
} from '@modrinth/ui'
|
||||
import { capitalizeString } from '@modrinth/utils'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { useVIntl } from '@vintl/vintl'
|
||||
import type { Dayjs } from 'dayjs'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { computed, nextTick, ref, onMounted, onUnmounted } from 'vue'
|
||||
import { showProfileInFolder } from '@/helpers/utils'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { get_project } from '@/helpers/cache'
|
||||
import { capitalizeString } from '@modrinth/utils'
|
||||
import { kill, run } from '@/helpers/profile'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_by_profile_path } from '@/helpers/process'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import InstanceItem from '@/components/ui/world/InstanceItem.vue'
|
||||
import WorldItem from '@/components/ui/world/WorldItem.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { process_listener, profile_listener } from '@/helpers/events'
|
||||
import { get_all } from '@/helpers/process'
|
||||
import { kill, run } from '@/helpers/profile'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import {
|
||||
type ProtocolVersion,
|
||||
type ServerData,
|
||||
type ServerWorld,
|
||||
type ServerData,
|
||||
type WorldWithProfile,
|
||||
get_recent_worlds,
|
||||
getWorldIdentifier,
|
||||
get_profile_protocol_version,
|
||||
get_recent_worlds,
|
||||
refreshServerData,
|
||||
start_join_server,
|
||||
start_join_singleplayer_world,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import { useTheming } from '@/store/theme.ts'
|
||||
import { GAME_MODES, HeadingLink, injectNotificationManager } from '@modrinth/ui'
|
||||
import { HeadingLink, GAME_MODES } from '@modrinth/ui'
|
||||
import WorldItem from '@/components/ui/world/WorldItem.vue'
|
||||
import InstanceItem from '@/components/ui/world/InstanceItem.vue'
|
||||
import { watch, onMounted, onUnmounted, ref, computed } from 'vue'
|
||||
import type { Dayjs } from 'dayjs'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { useTheming } from '@/store/theme.ts'
|
||||
import { kill, run } from '@/helpers/profile'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { process_listener, profile_listener } from '@/helpers/events'
|
||||
import { get_all } from '@/helpers/process'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
|
||||
const props = defineProps<{
|
||||
recentInstances: GameInstance[]
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import InstanceModalTitlePrefix from '@/components/ui/modal/InstanceModalTitlePrefix.vue'
|
||||
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 { PlayIcon, PlusIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { ButtonStyled, commonMessages } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import InstanceModalTitlePrefix from '@/components/ui/modal/InstanceModalTitlePrefix.vue'
|
||||
import { add_server_to_profile, type ServerPackStatus, type ServerWorld } from '@/helpers/worlds.ts'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import ServerModalBody from '@/components/ui/world/modal/ServerModalBody.vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { SaveIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, commonMessages } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.vue'
|
||||
import ServerModalBody from '@/components/ui/world/modal/ServerModalBody.vue'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import {
|
||||
type ServerPackStatus,
|
||||
edit_server_in_profile,
|
||||
type ServerWorld,
|
||||
set_world_display_status,
|
||||
type DisplayStatus,
|
||||
type ServerPackStatus,
|
||||
type ServerWorld,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import { SaveIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessage, useVIntl } from '@vintl/vintl'
|
||||
import { computed, ref } from 'vue'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import ServerModalBody from '@/components/ui/world/modal/ServerModalBody.vue'
|
||||
import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { ChevronRightIcon, SaveIcon, XIcon, UndoIcon } from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, commonMessages } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.vue'
|
||||
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 { ChevronRightIcon, SaveIcon, UndoIcon, XIcon } from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { set_world_display_status, rename_world, reset_world_icon } from '@/helpers/worlds.ts'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { computed, ref } from 'vue'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { get_max_memory } from '@/helpers/jre.js'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
|
||||
export default async function () {
|
||||
const { handleError } = injectNotificationManager()
|
||||
const maxMemory = ref(Math.floor((await get_max_memory().catch(handleError)) / 1024))
|
||||
|
||||
const snapPoints = computed(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
import { fetch } from '@tauri-apps/plugin-http'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
|
||||
export const useFetch = async (url, item, isSilent) => {
|
||||
try {
|
||||
@@ -11,7 +11,6 @@ export const useFetch = async (url, item, isSilent) => {
|
||||
})
|
||||
} catch (err) {
|
||||
if (!isSilent) {
|
||||
const { handleError } = injectNotificationManager()
|
||||
handleError({ message: `Error fetching ${item}` })
|
||||
}
|
||||
console.error(err)
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* So, for example, addDefaultInstance creates a blank Profile object, where the Rust struct is serialized,
|
||||
* and deserialized into a usable JS object.
|
||||
*/
|
||||
import { install_to_existing_profile } from '@/helpers/pack.js'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { install_to_existing_profile } from '@/helpers/pack.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
|
||||
/// Add instance
|
||||
/*
|
||||
@@ -190,7 +190,6 @@ export async function edit_icon(path, iconPath) {
|
||||
}
|
||||
|
||||
export async function finish_install(instance) {
|
||||
const { handleError } = injectNotificationManager()
|
||||
if (instance.install_stage !== 'pack_installed') {
|
||||
let linkedData = instance.linked_data
|
||||
await install_to_existing_profile(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { arrayBufferToBase64 } from '@modrinth/utils'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { arrayBufferToBase64 } from '@modrinth/utils'
|
||||
|
||||
export interface Cape {
|
||||
id: string
|
||||
@@ -39,7 +39,6 @@ export const DEFAULT_MODELS: Record<string, SkinModel> = {
|
||||
|
||||
export function filterSavedSkins(list: Skin[]) {
|
||||
const customSkins = list.filter((s) => s.source !== 'default')
|
||||
const { handleError } = injectNotificationManager()
|
||||
fixUnknownSkins(customSkins).catch(handleError)
|
||||
return customSkins
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import App from '@/App.vue'
|
||||
import { createApp } from 'vue'
|
||||
import router from '@/routes'
|
||||
import * as Sentry from '@sentry/vue'
|
||||
import { VueScanPlugin } from '@taijased/vue-render-tracker'
|
||||
import { createPlugin } from '@vintl/vintl/plugin'
|
||||
import App from '@/App.vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import FloatingVue from 'floating-vue'
|
||||
import 'floating-vue/dist/style.css'
|
||||
import { createPinia } from 'pinia'
|
||||
import { createApp } from 'vue'
|
||||
import { createPlugin } from '@vintl/vintl/plugin'
|
||||
import * as Sentry from '@sentry/vue'
|
||||
import { VueScanPlugin } from '@taijased/vue-render-tracker'
|
||||
|
||||
const VIntlPlugin = createPlugin({
|
||||
controllerOpts: {
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import type Instance from '@/components/ui/Instance.vue'
|
||||
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
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 { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { ClipboardCopyIcon, ExternalIcon, GlobeIcon, SearchIcon, XIcon } from '@modrinth/assets'
|
||||
import { computed, nextTick, ref, shallowRef, watch } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
import { SearchIcon, XIcon, ClipboardCopyIcon, GlobeIcon, ExternalIcon } from '@modrinth/assets'
|
||||
import type { Category, GameVersion, Platform, ProjectType, SortType, Tags } from '@modrinth/ui'
|
||||
import {
|
||||
SearchFilterControl,
|
||||
SearchSidebarFilter,
|
||||
Button,
|
||||
Checkbox,
|
||||
DropdownSelect,
|
||||
injectNotificationManager,
|
||||
LoadingIndicator,
|
||||
Pagination,
|
||||
SearchFilterControl,
|
||||
SearchSidebarFilter,
|
||||
useSearch,
|
||||
} from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import type { Ref } from 'vue'
|
||||
import { computed, nextTick, ref, shallowRef, watch } from 'vue'
|
||||
import { handleError } from '@/store/state'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { get_categories, get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import type { LocationQuery } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile.js'
|
||||
import { get_search_results } from '@/helpers/cache.js'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
import type Instance from '@/components/ui/Instance.vue'
|
||||
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import RowDisplay from '@/components/RowDisplay.vue'
|
||||
import RecentWorldsList from '@/components/ui/world/RecentWorldsList.vue'
|
||||
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 { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import type { SearchResult } from '@modrinth/utils'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, onUnmounted, ref } from 'vue'
|
||||
import { ref, onUnmounted, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import RowDisplay from '@/components/RowDisplay.vue'
|
||||
import { list } from '@/helpers/profile.js'
|
||||
import { profile_listener } from '@/helpers/events'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import dayjs from 'dayjs'
|
||||
import { get_search_results } from '@/helpers/cache.js'
|
||||
import type { SearchResult } from '@modrinth/utils'
|
||||
import RecentWorldsList from '@/components/ui/world/RecentWorldsList.vue'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
const breadcrumbs = useBreadcrumbs()
|
||||
|
||||
|
||||
@@ -1,26 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import type AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||
import EditSkinModal from '@/components/ui/skin/EditSkinModal.vue'
|
||||
import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue'
|
||||
import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_default_user, login as login_flow, users } from '@/helpers/auth'
|
||||
import type { RenderResult } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
import { generateSkinPreviews, skinBlobUrlMap } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
import { get as getSettings } from '@/helpers/settings.ts'
|
||||
import type { Cape, Skin } from '@/helpers/skins.ts'
|
||||
import {
|
||||
equip_skin,
|
||||
filterDefaultSkins,
|
||||
filterSavedSkins,
|
||||
get_available_capes,
|
||||
get_available_skins,
|
||||
get_normalized_skin_texture,
|
||||
normalize_skin_texture,
|
||||
remove_custom_skin,
|
||||
set_default_cape,
|
||||
} from '@/helpers/skins.ts'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import {
|
||||
EditIcon,
|
||||
ExcitedRinthbot,
|
||||
@@ -34,21 +12,42 @@ import {
|
||||
Button,
|
||||
ButtonStyled,
|
||||
ConfirmModal,
|
||||
injectNotificationManager,
|
||||
SkinButton,
|
||||
SkinLikeTextButton,
|
||||
SkinPreviewRenderer,
|
||||
} from '@modrinth/ui'
|
||||
import { arrayBufferToBase64 } from '@modrinth/utils'
|
||||
import { computedAsync } from '@vueuse/core'
|
||||
import type { Ref } from 'vue'
|
||||
import { computed, inject, onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue'
|
||||
import EditSkinModal from '@/components/ui/skin/EditSkinModal.vue'
|
||||
import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue'
|
||||
import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue'
|
||||
import { handleError, useNotifications } from '@/store/notifications'
|
||||
import type { Cape, Skin } from '@/helpers/skins.ts'
|
||||
import {
|
||||
normalize_skin_texture,
|
||||
equip_skin,
|
||||
filterDefaultSkins,
|
||||
filterSavedSkins,
|
||||
get_available_capes,
|
||||
get_available_skins,
|
||||
get_normalized_skin_texture,
|
||||
remove_custom_skin,
|
||||
set_default_cape,
|
||||
} from '@/helpers/skins.ts'
|
||||
import { get as getSettings } from '@/helpers/settings.ts'
|
||||
import { get_default_user, login as login_flow, users } from '@/helpers/auth'
|
||||
import type { RenderResult } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
import { generateSkinPreviews, skinBlobUrlMap } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
import { handleSevereError } from '@/store/error'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import type AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||
import { arrayBufferToBase64 } from '@modrinth/utils'
|
||||
const editSkinModal = useTemplateRef('editSkinModal')
|
||||
const selectCapeModal = useTemplateRef('selectCapeModal')
|
||||
const uploadSkinModal = useTemplateRef('uploadSkinModal')
|
||||
|
||||
const notifications = injectNotificationManager()
|
||||
const { handleError } = notifications
|
||||
const notifications = useNotifications()
|
||||
|
||||
const settings = ref(await getSettings())
|
||||
const skins = ref<Skin[]>([])
|
||||
@@ -114,7 +113,7 @@ async function loadCapes() {
|
||||
defaultCape.value = capes.value.find((c) => c.is_equipped)
|
||||
originalDefaultCape.value = defaultCape.value
|
||||
} catch (error) {
|
||||
if (currentUser.value && error instanceof Error) {
|
||||
if (currentUser.value) {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
@@ -127,7 +126,7 @@ async function loadSkins() {
|
||||
selectedSkin.value = skins.value.find((s) => s.is_equipped) ?? null
|
||||
originalSelectedSkin.value = selectedSkin.value
|
||||
} catch (error) {
|
||||
if (currentUser.value && error instanceof Error) {
|
||||
if (currentUser.value) {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
@@ -162,7 +161,7 @@ async function changeSkin(newSkin: Skin) {
|
||||
text: "You're changing your skin too frequently. Mojang's servers have temporarily blocked further requests. Please wait a moment before trying again.",
|
||||
})
|
||||
} else {
|
||||
handleError(error as Error)
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,7 +190,7 @@ async function handleCapeSelected(cape: Cape | undefined) {
|
||||
text: "You're changing your cape too frequently. Mojang's servers have temporarily blocked further requests. Please wait a moment before trying again.",
|
||||
})
|
||||
} else {
|
||||
handleError(error as Error)
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,7 +207,7 @@ async function loadCurrentUser() {
|
||||
const allAccounts = await users()
|
||||
currentUser.value = allAccounts.find((acc) => acc.profile.id === defaultId)
|
||||
} catch (e) {
|
||||
handleError(e as Error)
|
||||
handleError(e)
|
||||
currentUser.value = undefined
|
||||
currentUserId.value = undefined
|
||||
}
|
||||
@@ -277,7 +276,7 @@ async function checkUserChanges() {
|
||||
await loadSkins()
|
||||
}
|
||||
} catch (error) {
|
||||
if (currentUser.value && error instanceof Error) {
|
||||
if (currentUser.value) {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
@@ -377,7 +376,7 @@ await Promise.all([loadCapes(), loadSkins(), loadCurrentUser()])
|
||||
color="green"
|
||||
aria-label="Edit skin"
|
||||
class="pointer-events-auto"
|
||||
@click.stop="(e: MouseEvent) => editSkinModal?.show(e, skin)"
|
||||
@click.stop="(e) => editSkinModal?.show(e, skin)"
|
||||
>
|
||||
<EditIcon /> Edit
|
||||
</Button>
|
||||
|
||||
@@ -157,18 +157,13 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import ExportModal from '@/components/ui/ExportModal.vue'
|
||||
import InstanceSettingsModal from '@/components/ui/modal/InstanceSettingsModal.vue'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project, get_version_many } from '@/helpers/cache.js'
|
||||
import { process_listener, profile_listener } from '@/helpers/events'
|
||||
import { get_by_profile_path } from '@/helpers/process'
|
||||
import { finish_install, get, get_full_path, kill, run } from '@/helpers/profile'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { useBreadcrumbs, useLoading } from '@/store/state'
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
ContentPageHeader,
|
||||
LoadingIndicator,
|
||||
OverflowMenu,
|
||||
} from '@modrinth/ui'
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
ClipboardCopyIcon,
|
||||
@@ -192,25 +187,28 @@ import {
|
||||
UserPlusIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
ContentPageHeader,
|
||||
injectNotificationManager,
|
||||
LoadingIndicator,
|
||||
OverflowMenu,
|
||||
} from '@modrinth/ui'
|
||||
import { finish_install, get, get_full_path, kill, run } from '@/helpers/profile'
|
||||
import { get_by_profile_path } from '@/helpers/process'
|
||||
import { process_listener, profile_listener } from '@/helpers/events'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { handleError, useBreadcrumbs, useLoading } from '@/store/state'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { get_project, get_version_many } from '@/helpers/cache.js'
|
||||
import dayjs from 'dayjs'
|
||||
import duration from 'dayjs/plugin/duration'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import ExportModal from '@/components/ui/ExportModal.vue'
|
||||
import InstanceSettingsModal from '@/components/ui/modal/InstanceSettingsModal.vue'
|
||||
|
||||
dayjs.extend(duration)
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -88,30 +88,30 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||
import { process_listener } from '@/helpers/events.js'
|
||||
import { CheckIcon, ClipboardCopyIcon, ShareIcon, TrashIcon } from '@modrinth/assets'
|
||||
import { Button, Card, Checkbox, DropdownSelect } from '@modrinth/ui'
|
||||
import {
|
||||
delete_logs_by_filename,
|
||||
get_latest_log_cursor,
|
||||
get_logs,
|
||||
get_output_by_filename,
|
||||
get_latest_log_cursor,
|
||||
} from '@/helpers/logs.js'
|
||||
import { get_by_profile_path } from '@/helpers/process.js'
|
||||
import { CheckIcon, ClipboardCopyIcon, ShareIcon, TrashIcon } from '@modrinth/assets'
|
||||
import { Button, Card, Checkbox, DropdownSelect, injectNotificationManager } from '@modrinth/ui'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import isToday from 'dayjs/plugin/isToday'
|
||||
import isYesterday from 'dayjs/plugin/isYesterday'
|
||||
import { ofetch } from 'ofetch'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import { get_by_profile_path } from '@/helpers/process.js'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { process_listener } from '@/helpers/events.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { ofetch } from 'ofetch'
|
||||
import { RecycleScroller } from 'vue-virtual-scroller'
|
||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||
|
||||
dayjs.extend(isToday)
|
||||
dayjs.extend(isYesterday)
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -249,30 +249,6 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { TextInputIcon } from '@/assets/icons'
|
||||
import AddContentButton from '@/components/ui/AddContentButton.vue'
|
||||
import type ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import ExportModal from '@/components/ui/ExportModal.vue'
|
||||
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import {
|
||||
get_organization_many,
|
||||
get_project_many,
|
||||
get_team_many,
|
||||
get_version_many,
|
||||
} from '@/helpers/cache.js'
|
||||
import { profile_listener } from '@/helpers/events.js'
|
||||
import {
|
||||
add_project_from_path,
|
||||
get_projects,
|
||||
remove_project,
|
||||
toggle_disable_project,
|
||||
update_all,
|
||||
update_project,
|
||||
} from '@/helpers/profile.js'
|
||||
import type { CacheBehaviour, ContentFile, GameInstance } from '@/helpers/types'
|
||||
import { highlightModInProfile } from '@/helpers/utils.js'
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
ClipboardCopyIcon,
|
||||
@@ -295,22 +271,44 @@ import {
|
||||
Button,
|
||||
ButtonStyled,
|
||||
ContentListPanel,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
Pagination,
|
||||
RadialHeader,
|
||||
Toggle,
|
||||
} from '@modrinth/ui'
|
||||
import type { ContentItem } from '@modrinth/ui/src/components/content/ContentListItem.vue'
|
||||
import type { Organization, Project, TeamMember, Version } from '@modrinth/utils'
|
||||
import { formatProjectType } from '@modrinth/utils'
|
||||
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import dayjs from 'dayjs'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import {
|
||||
add_project_from_path,
|
||||
get_projects,
|
||||
remove_project,
|
||||
toggle_disable_project,
|
||||
update_all,
|
||||
update_project,
|
||||
} from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { highlightModInProfile } from '@/helpers/utils.js'
|
||||
import { TextInputIcon } from '@/assets/icons'
|
||||
import ExportModal from '@/components/ui/ExportModal.vue'
|
||||
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
|
||||
import AddContentButton from '@/components/ui/AddContentButton.vue'
|
||||
import {
|
||||
get_organization_many,
|
||||
get_project_many,
|
||||
get_team_many,
|
||||
get_version_many,
|
||||
} from '@/helpers/cache.js'
|
||||
import { profile_listener } from '@/helpers/events.js'
|
||||
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||
import dayjs from 'dayjs'
|
||||
import type { CacheBehaviour, ContentFile, GameInstance } from '@/helpers/types'
|
||||
import type ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import type { ContentItem } from '@modrinth/ui/src/components/content/ContentListItem.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
instance: GameInstance
|
||||
|
||||
@@ -121,55 +121,55 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { ref, computed, onUnmounted, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import {
|
||||
Button,
|
||||
ButtonStyled,
|
||||
RadialHeader,
|
||||
FilterBar,
|
||||
type FilterBarOption,
|
||||
type GameVersion,
|
||||
GAME_MODES,
|
||||
} from '@modrinth/ui'
|
||||
import { PlusIcon, SpinnerIcon, UpdatedIcon, SearchIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
type ProtocolVersion,
|
||||
type SingleplayerWorld,
|
||||
type World,
|
||||
type ServerWorld,
|
||||
type ServerData,
|
||||
type ProfileEvent,
|
||||
get_profile_protocol_version,
|
||||
remove_server_from_profile,
|
||||
delete_world,
|
||||
start_join_server,
|
||||
start_join_singleplayer_world,
|
||||
getWorldIdentifier,
|
||||
refreshServerData,
|
||||
refreshWorld,
|
||||
sortWorlds,
|
||||
refreshServers,
|
||||
hasWorldQuickPlaySupport,
|
||||
refreshWorlds,
|
||||
handleDefaultProfileUpdateEvent,
|
||||
showWorldInFolder,
|
||||
hasServerQuickPlaySupport,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import AddServerModal from '@/components/ui/world/modal/AddServerModal.vue'
|
||||
import EditServerModal from '@/components/ui/world/modal/EditServerModal.vue'
|
||||
import EditWorldModal from '@/components/ui/world/modal/EditSingleplayerWorldModal.vue'
|
||||
import WorldItem from '@/components/ui/world/WorldItem.vue'
|
||||
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import type ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import type { Version } from '@modrinth/utils'
|
||||
import { profile_listener } from '@/helpers/events'
|
||||
import { get_game_versions } from '@/helpers/tags'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import {
|
||||
type ProfileEvent,
|
||||
type ProtocolVersion,
|
||||
type ServerData,
|
||||
type ServerWorld,
|
||||
type SingleplayerWorld,
|
||||
type World,
|
||||
delete_world,
|
||||
getWorldIdentifier,
|
||||
get_profile_protocol_version,
|
||||
handleDefaultProfileUpdateEvent,
|
||||
hasServerQuickPlaySupport,
|
||||
hasWorldQuickPlaySupport,
|
||||
refreshServerData,
|
||||
refreshServers,
|
||||
refreshWorld,
|
||||
refreshWorlds,
|
||||
remove_server_from_profile,
|
||||
showWorldInFolder,
|
||||
sortWorlds,
|
||||
start_join_server,
|
||||
start_join_singleplayer_world,
|
||||
} from '@/helpers/worlds.ts'
|
||||
import { PlusIcon, SearchIcon, SpinnerIcon, UpdatedIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Button,
|
||||
ButtonStyled,
|
||||
FilterBar,
|
||||
type FilterBarOption,
|
||||
GAME_MODES,
|
||||
type GameVersion,
|
||||
RadialHeader,
|
||||
injectNotificationManager,
|
||||
} from '@modrinth/ui'
|
||||
import type { Version } from '@modrinth/utils'
|
||||
import { defineMessages } from '@vintl/vintl'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
|
||||
const addServerModal = ref<InstanceType<typeof AddServerModal>>()
|
||||
@@ -282,7 +282,7 @@ async function editServer(server: ServerWorld) {
|
||||
await refreshServer(server.address)
|
||||
}
|
||||
} else {
|
||||
handleError(new Error(`Error refreshing server, refreshing all worlds`))
|
||||
handleError(`Error refreshing server, refreshing all worlds`)
|
||||
await refreshAllWorlds()
|
||||
}
|
||||
}
|
||||
@@ -301,7 +301,7 @@ async function editWorld(path: string, name: string, removeIcon: boolean) {
|
||||
}
|
||||
sortWorlds(worlds.value)
|
||||
} else {
|
||||
handleError(new Error(`Error finding world in list, refreshing all worlds`))
|
||||
handleError(`Error finding world in list, refreshing all worlds`)
|
||||
await refreshAllWorlds()
|
||||
}
|
||||
}
|
||||
@@ -311,7 +311,7 @@ async function deleteWorld(world: SingleplayerWorld) {
|
||||
worlds.value = worlds.value.filter((w) => w.type !== 'singleplayer' || w.path !== world.path)
|
||||
}
|
||||
|
||||
function handleJoinError(err: Error) {
|
||||
function handleJoinError(err: unknown) {
|
||||
handleError(err)
|
||||
startingInstance.value = false
|
||||
worldPlaying.value = undefined
|
||||
@@ -436,7 +436,7 @@ function promptToRemoveWorld(world: World): boolean {
|
||||
|
||||
async function proceedRemoveServer() {
|
||||
if (!serverToRemove.value) {
|
||||
handleError(new Error(`Error removing server, no server marked for removal.`))
|
||||
handleError(`Error removing server, no server marked for removal.`)
|
||||
return
|
||||
}
|
||||
await removeServer(serverToRemove.value)
|
||||
@@ -445,7 +445,7 @@ async function proceedRemoveServer() {
|
||||
|
||||
async function proceedDeleteWorld() {
|
||||
if (!worldToDelete.value) {
|
||||
handleError(new Error(`Error deleting world, no world marked for removal.`))
|
||||
handleError(`Error deleting world, no world marked for removal.`)
|
||||
return
|
||||
}
|
||||
await deleteWorld(worldToDelete.value)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<script setup>
|
||||
import { NewInstanceImage } from '@/assets/icons'
|
||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
import { profile_listener } from '@/helpers/events.js'
|
||||
import { list } from '@/helpers/profile.js'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs.js'
|
||||
import { PlusIcon } from '@modrinth/assets'
|
||||
import { Button, injectNotificationManager } from '@modrinth/ui'
|
||||
import { onUnmounted, ref, shallowRef } from 'vue'
|
||||
import { list } from '@/helpers/profile.js'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs.js'
|
||||
import { profile_listener } from '@/helpers/events.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import { PlusIcon } from '@modrinth/assets'
|
||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||
import { NewInstanceImage } from '@/assets/icons'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
const breadcrumbs = useBreadcrumbs()
|
||||
|
||||
|
||||
@@ -129,46 +129,46 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
import { get_project, get_team, get_version_many } from '@/helpers/cache.js'
|
||||
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile'
|
||||
import { get_categories, get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
import {
|
||||
BookmarkIcon,
|
||||
CheckIcon,
|
||||
ClipboardCopyIcon,
|
||||
DownloadIcon,
|
||||
ExternalIcon,
|
||||
GlobeIcon,
|
||||
HeartIcon,
|
||||
MoreVerticalIcon,
|
||||
DownloadIcon,
|
||||
ReportIcon,
|
||||
HeartIcon,
|
||||
ExternalIcon,
|
||||
CheckIcon,
|
||||
GlobeIcon,
|
||||
ClipboardCopyIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
ButtonStyled,
|
||||
OverflowMenu,
|
||||
ProjectBackgroundGradient,
|
||||
ProjectHeader,
|
||||
ProjectSidebarCompatibility,
|
||||
ButtonStyled,
|
||||
OverflowMenu,
|
||||
ProjectSidebarLinks,
|
||||
ProjectSidebarCreators,
|
||||
ProjectSidebarDetails,
|
||||
ProjectSidebarLinks,
|
||||
injectNotificationManager,
|
||||
ProjectBackgroundGradient,
|
||||
} from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
|
||||
import { get_categories, get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile'
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import { ref, shallowRef, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ref, shallowRef, watch } from 'vue'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
import { get_project, get_team, get_version_many } from '@/helpers/cache.js'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const breadcrumbs = useBreadcrumbs()
|
||||
|
||||
@@ -65,16 +65,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ProjectPageVersions, ButtonStyled, OverflowMenu } from '@modrinth/ui'
|
||||
import { CheckIcon, DownloadIcon, ExternalIcon, MoreVerticalIcon } from '@modrinth/assets'
|
||||
import { ref } from 'vue'
|
||||
import { SwapIcon } from '@/assets/icons/index.js'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags.js'
|
||||
import { CheckIcon, DownloadIcon, ExternalIcon, MoreVerticalIcon } from '@modrinth/assets'
|
||||
import {
|
||||
ButtonStyled,
|
||||
OverflowMenu,
|
||||
ProjectPageVersions,
|
||||
injectNotificationManager,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
|
||||
defineProps({
|
||||
project: {
|
||||
@@ -107,8 +103,6 @@ defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const { handleError } = injectNotificationManager()
|
||||
|
||||
const [loaders, gameVersions] = await Promise.all([
|
||||
get_loaders().catch(handleError).then(ref),
|
||||
get_game_versions().catch(handleError).then(ref),
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import {
|
||||
AbstractWebNotificationManager,
|
||||
type NotificationPanelLocation,
|
||||
type WebNotification,
|
||||
} from '@modrinth/ui'
|
||||
import { ref, type Ref } from 'vue'
|
||||
|
||||
export class AppNotificationManager extends AbstractWebNotificationManager {
|
||||
private readonly state: Ref<WebNotification[]>
|
||||
private readonly locationState: Ref<NotificationPanelLocation>
|
||||
|
||||
public constructor() {
|
||||
super()
|
||||
this.state = ref<WebNotification[]>([])
|
||||
this.locationState = ref<NotificationPanelLocation>('right')
|
||||
}
|
||||
|
||||
public getNotificationLocation(): NotificationPanelLocation {
|
||||
return this.locationState.value
|
||||
}
|
||||
|
||||
public setNotificationLocation(location: NotificationPanelLocation): void {
|
||||
this.locationState.value = location
|
||||
}
|
||||
|
||||
public getNotifications(): WebNotification[] {
|
||||
return this.state.value
|
||||
}
|
||||
|
||||
protected addNotificationToStorage(notification: WebNotification): void {
|
||||
this.state.value.push(notification)
|
||||
}
|
||||
|
||||
protected removeNotificationFromStorage(id: string | number): void {
|
||||
const index = this.state.value.findIndex((n) => n.id === id)
|
||||
if (index > -1) {
|
||||
this.state.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
protected removeNotificationFromStorageByIndex(index: number): void {
|
||||
this.state.value.splice(index, 1)
|
||||
}
|
||||
|
||||
protected clearAllNotificationsFromStorage(): void {
|
||||
this.state.value.splice(0)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import { trackEvent } from '@/helpers/analytics.js'
|
||||
import { get_project, get_version_many } from '@/helpers/cache.js'
|
||||
import { create_profile_and_install as packInstall } from '@/helpers/pack.js'
|
||||
import { defineStore } from 'pinia'
|
||||
import {
|
||||
add_project_from_version,
|
||||
check_installed,
|
||||
@@ -9,9 +7,11 @@ import {
|
||||
list,
|
||||
remove_project,
|
||||
} from '@/helpers/profile.js'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { get_project, get_version_many } from '@/helpers/cache.js'
|
||||
import { create_profile_and_install as packInstall } from '@/helpers/pack.js'
|
||||
import { trackEvent } from '@/helpers/analytics.js'
|
||||
import dayjs from 'dayjs'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useInstall = defineStore('installStore', {
|
||||
state: () => ({
|
||||
@@ -29,8 +29,8 @@ export const useInstall = defineStore('installStore', {
|
||||
setIncompatibilityWarningModal(ref) {
|
||||
this.incompatibilityWarningModal = ref
|
||||
},
|
||||
showIncompatibilityWarningModal(instance, project, versions, onInstall) {
|
||||
this.incompatibilityWarningModal.show(instance, project, versions, onInstall)
|
||||
showIncompatibilityWarningModal(instance, project, versions, selected, onInstall) {
|
||||
this.incompatibilityWarningModal.show(instance, project, versions, selected, onInstall)
|
||||
},
|
||||
setModInstallModal(ref) {
|
||||
this.modInstallModal = ref
|
||||
@@ -49,7 +49,6 @@ export const install = async (
|
||||
callback = () => {},
|
||||
createInstanceCallback = () => {},
|
||||
) => {
|
||||
const { handleError } = injectNotificationManager()
|
||||
const project = await get_project(projectId, 'must_revalidate').catch(handleError)
|
||||
|
||||
if (project.project_type === 'modpack') {
|
||||
@@ -134,7 +133,13 @@ export const install = async (
|
||||
callback(version.id)
|
||||
} else {
|
||||
const install = useInstall()
|
||||
install.showIncompatibilityWarningModal(instance, project, projectVersions, callback)
|
||||
install.showIncompatibilityWarningModal(
|
||||
instance,
|
||||
project,
|
||||
projectVersions,
|
||||
version,
|
||||
callback,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
const versions = (await get_version_many(project.versions).catch(handleError)).sort(
|
||||
@@ -161,7 +166,6 @@ export const install = async (
|
||||
}
|
||||
|
||||
export const installVersionDependencies = async (profile, version) => {
|
||||
const { handleError } = injectNotificationManager()
|
||||
for (const dep of version.dependencies) {
|
||||
if (dep.dependency_type !== 'required') continue
|
||||
// disallow fabric api install on quilt
|
||||
|
||||
25
apps/app-frontend/src/store/notifications.js
Normal file
25
apps/app-frontend/src/store/notifications.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useNotifications = defineStore('notificationsStore', {
|
||||
state: () => ({
|
||||
notificationsWrapper: null,
|
||||
}),
|
||||
actions: {
|
||||
setNotifs(notifs) {
|
||||
this.notificationsWrapper = notifs
|
||||
},
|
||||
addNotification(notif) {
|
||||
this.notificationsWrapper.addNotification(notif)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const handleError = (err) => {
|
||||
const notifs = useNotifications()
|
||||
notifs.addNotification({
|
||||
title: 'An error occurred',
|
||||
text: err.message ?? err,
|
||||
type: 'error',
|
||||
})
|
||||
console.error(err)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useBreadcrumbs } from './breadcrumbs'
|
||||
import { useInstall } from './install'
|
||||
import { useLoading } from './loading'
|
||||
import { useTheming } from './theme.ts'
|
||||
import { useBreadcrumbs } from './breadcrumbs'
|
||||
import { useLoading } from './loading'
|
||||
import { useNotifications, handleError } from './notifications'
|
||||
import { useInstall } from './install'
|
||||
|
||||
export { useBreadcrumbs, useInstall, useLoading, useTheming }
|
||||
export { useTheming, useBreadcrumbs, useLoading, useNotifications, handleError, useInstall }
|
||||
|
||||
@@ -3,55 +3,37 @@ title: Labrinth (API)
|
||||
description: Guide for contributing to Modrinth's backend
|
||||
---
|
||||
|
||||
This project is part of our [monorepo](https://github.com/modrinth/code). You can find it in the `apps/labrinth` directory.
|
||||
This project is part of our [monorepo](https://github.com/modrinth/code). You can find it in the `apps/labrinth` directory. The instructions below assume that you have switched your working directory to the `apps/labrinth` subdirectory.
|
||||
|
||||
[labrinth] is the Rust-based backend serving Modrinth's API with the help of the [Actix](https://actix.rs) framework. To get started with a labrinth instance, install docker, docker-compose (which comes with Docker), and [Rust]. The initial startup can be done simply with the command `docker-compose up`, or with `docker compose up` (Compose V2 and later). That will deploy a PostgreSQL database on port 5432 and a MeiliSearch instance on port 7700. To run the API itself, you'll need to use the `cargo run` command, this will deploy the API on port 8000.
|
||||
[Labrinth] is the Rust-based backend serving Modrinth's API with the help of the [Actix](https://actix.rs) framework. To get started with a labrinth instance, install docker, docker-compose (which comes with Docker), and [Rust]. The initial startup can be done simply with the command `docker-compose up`, or with `docker compose up` (Compose V2 and later). That will deploy a PostgreSQL database on port 5432 and a MeiliSearch instance on port 7700. To run the API itself, you'll need to use the `cargo run` command, this will deploy the API on port 8000.
|
||||
|
||||
To get a basic configuration, copy the `.env.local` file to `.env`. Now, you'll have to install the sqlx CLI, which can be done with cargo:
|
||||
|
||||
```bash
|
||||
cargo install --git https://github.com/launchbadge/sqlx sqlx-cli --no-default-features --features postgres,rustls
|
||||
```sh
|
||||
cargo install sqlx-cli --no-default-features --features mysql,sqlite,postgres,rustls,completions
|
||||
```
|
||||
|
||||
From there, you can create the database and perform all database migrations with one simple command:
|
||||
From there, you can create the database and set up its schema with one simple command:
|
||||
|
||||
```bash
|
||||
sqlx database setup
|
||||
```sh
|
||||
cargo sqlx database setup
|
||||
```
|
||||
|
||||
To enable labrinth to create a project, you need to add two things.
|
||||
To enable Labrinth to create projects and serve useful metadata to the frontend build scripts, you'll need to seed the database with several key entities:
|
||||
|
||||
1. An entry in the `loaders` table.
|
||||
2. An entry in the `loaders_project_types` table.
|
||||
1. Categories, in the `categories` table.
|
||||
2. Loaders and their fields, in the `loaders`, `loader_fields`, `loader_field_enums`, `loader_field_enum_values`, and `loader_fields_loaders` tables.
|
||||
3. Project types and their allowed loaders and games, in the `project_types`, `loaders_project_types`, and `loaders_project_types_games` tables.
|
||||
4. Optionally, to moderate projects from the frontend, an admin user, in the `users` table.
|
||||
|
||||
A minimal setup can be done from the command line with [psql](https://www.postgresql.org/docs/current/app-psql.html):
|
||||
The most convenient way to do this seeding is with the [psql](https://www.postgresql.org/docs/current/app-psql.html) command line tool and the pre-existing seed data fixture. This fixture was generated by dumping the official staging environment database at a specific point in time, and defines an admin user with email `admin@modrinth.invalid` and password `admin`:
|
||||
|
||||
```bash
|
||||
psql --host=localhost --port=5432 -U <username, default is labrinth> -W
|
||||
```sh
|
||||
source .env
|
||||
psql "$DATABASE_URL" < fixtures/labrinth-seed-data-202508052143.sql
|
||||
```
|
||||
|
||||
The default password for the database is `labrinth`. Once you've connected, run
|
||||
|
||||
```sql
|
||||
INSERT INTO loaders VALUES (0, 'placeholder_loader');
|
||||
INSERT INTO loaders_project_types VALUES (0, 1); -- modloader id, supported type id
|
||||
INSERT INTO categories VALUES (0, 'placeholder_category', 1); -- category id, category, project type id
|
||||
```
|
||||
|
||||
This will initialize your database with a modloader called 'placeholder_loader', with id 0, and marked as supporting mods only. It will also create a category called 'placeholder_category' that is marked as supporting mods only
|
||||
If you would like 'placeholder_loader' to be marked as supporting modpacks too, run
|
||||
|
||||
```sql
|
||||
INSERT INTO loaders_project_types VALUES (0, 2); -- modloader id, supported type id
|
||||
```
|
||||
|
||||
If you would like 'placeholder_category' to be marked as supporting modpacks too, run
|
||||
|
||||
```sql
|
||||
INSERT INTO categories VALUES (0, 'placeholder_category', 2); -- modloader id, supported type id
|
||||
```
|
||||
|
||||
You can find more example SQL statements for seeding the database in the `apps/labrinth/tests/files/dummy_data.sql` file.
|
||||
You can find more example SQL statements for seeding the database in the `tests/files/dummy_data.sql` file.
|
||||
|
||||
The majority of configuration is done at runtime using [dotenvy](https://crates.io/crates/dotenvy) and the `.env` file. Each of the variables and what they do can be found in the dropdown below. Additionally, there are three command line options that can be used to specify to MeiliSearch what you want to do.
|
||||
|
||||
@@ -109,14 +91,13 @@ The OAuth configuration options are fairly self-explanatory. For help setting up
|
||||
|
||||
If you're prepared to contribute by submitting a pull request, ensure you have met the following criteria:
|
||||
|
||||
- `cargo fmt` has been run.
|
||||
- `cargo clippy` has been run.
|
||||
- `cargo check` has been run.
|
||||
- `cargo fmt --all` has been run.
|
||||
- `cargo clippy --all-targets` has been run.
|
||||
- `cargo sqlx prepare` has been run.
|
||||
|
||||
> Note: If you encounter issues with `sqlx` saying 'no queries found' after running `cargo sqlx prepare`, you may need to ensure the installed version of `sqlx-cli` matches the current version of `sqlx` used [in labrinth](https://github.com/modrinth/labrinth/blob/master/Cargo.toml).
|
||||
|
||||
[Discord]: https://discord.modrinth.com
|
||||
[GitHub]: https://github.com/modrinth
|
||||
[labrinth]: https://github.com/modrinth/labrinth
|
||||
[Labrinth]: https://github.com/modrinth/code/tree/main/apps/labrinth
|
||||
[Rust]: https://www.rust-lang.org/tools/install
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
<template>
|
||||
<NuxtLayout>
|
||||
<ModrinthLoadingIndicator />
|
||||
<NotificationPanel />
|
||||
<Notifications />
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { NotificationPanel, provideNotificationManager } from "@modrinth/ui";
|
||||
import { FrontendNotificationManager } from "./providers/frontend-notifications.ts";
|
||||
import ModrinthLoadingIndicator from "~/components/ui/modrinth-loading-indicator.ts";
|
||||
|
||||
provideNotificationManager(new FrontendNotificationManager());
|
||||
import Notifications from "~/components/ui/Notifications.vue";
|
||||
</script>
|
||||
|
||||
@@ -51,9 +51,7 @@
|
||||
<script setup>
|
||||
import { PlusIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const router = useNativeRouter();
|
||||
|
||||
const name = ref("");
|
||||
@@ -89,6 +87,7 @@ async function create() {
|
||||
await router.push(`/collection/${result.id}`);
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err?.data?.description || err?.message || err,
|
||||
type: "error",
|
||||
|
||||
@@ -84,11 +84,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { PlusIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, DropdownSelect, NewModal } from "@modrinth/ui";
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
import { NewModal, ButtonStyled, DropdownSelect } from "@modrinth/ui";
|
||||
import { XIcon, PlusIcon } from "@modrinth/assets";
|
||||
|
||||
const router = useRouter();
|
||||
const app = useNuxtApp();
|
||||
@@ -183,7 +180,8 @@ async function createProject() {
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -319,21 +319,30 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { renderString } from "@modrinth/utils";
|
||||
import {
|
||||
BellIcon,
|
||||
CalendarIcon,
|
||||
CheckCircleIcon,
|
||||
CheckIcon,
|
||||
ExternalIcon,
|
||||
ScaleIcon,
|
||||
UserPlusIcon,
|
||||
ScaleIcon,
|
||||
BellIcon,
|
||||
CheckCircleIcon,
|
||||
CalendarIcon,
|
||||
VersionIcon,
|
||||
CheckIcon,
|
||||
XIcon,
|
||||
ExternalIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
import { Avatar, ProjectStatusBadge, CopyCode, useRelativeTime } from "@modrinth/ui";
|
||||
import ThreadSummary from "~/components/ui/thread/ThreadSummary.vue";
|
||||
import { getProjectLink, getVersionLink } from "~/helpers/projects.js";
|
||||
import { getUserLink } from "~/helpers/users.js";
|
||||
import { acceptTeamInvite, removeSelfFromTeam } from "~/helpers/teams.js";
|
||||
import { markAsRead } from "~/helpers/notifications.ts";
|
||||
import DoubleIcon from "~/components/ui/DoubleIcon.vue";
|
||||
import Categories from "~/components/ui/search/Categories.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const app = useNuxtApp();
|
||||
const emit = defineEmits(["update:notifications"]);
|
||||
|
||||
const formatRelativeTime = useRelativeTime();
|
||||
|
||||
const props = defineProps({
|
||||
@@ -398,7 +407,8 @@ async function read() {
|
||||
const newNotifs = updateNotifs(props.notifications);
|
||||
emit("update:notifications", newNotifs);
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error marking notification as read",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -417,7 +427,8 @@ async function performAction(notification, actionIndex) {
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
class="vue-notification-group experimental-styles-within"
|
||||
:class="{
|
||||
'intercom-present': isIntercomPresent,
|
||||
'location-left': notificationLocation === 'left',
|
||||
'location-right': notificationLocation === 'right',
|
||||
'has-sidebar': hasSidebar,
|
||||
rightwards: moveNotificationsRight,
|
||||
}"
|
||||
>
|
||||
<transition-group name="notifs">
|
||||
@@ -55,7 +53,7 @@
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled circular size="small">
|
||||
<button v-tooltip="`Dismiss`" @click="dismissNotification(index)">
|
||||
<button v-tooltip="`Dismiss`" @click="notifications.splice(index, 1)">
|
||||
<XIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
@@ -75,117 +73,106 @@
|
||||
</transition-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup>
|
||||
import { ButtonStyled } from "@modrinth/ui";
|
||||
import {
|
||||
XCircleIcon,
|
||||
CheckCircleIcon,
|
||||
CheckIcon,
|
||||
CopyIcon,
|
||||
InfoIcon,
|
||||
IssuesIcon,
|
||||
XCircleIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { injectNotificationManager, type WebNotification } from '../../providers'
|
||||
import ButtonStyled from '../base/ButtonStyled.vue'
|
||||
CopyIcon,
|
||||
} from "@modrinth/assets";
|
||||
const notifications = useNotifications();
|
||||
const { isVisible: moveNotificationsRight } = useNotificationRightwards();
|
||||
|
||||
const notificationManager = injectNotificationManager()
|
||||
const notifications = computed<WebNotification[]>(() => notificationManager.getNotifications())
|
||||
const notificationLocation = computed(() => notificationManager.getNotificationLocation())
|
||||
const isIntercomPresent = ref(false);
|
||||
|
||||
const isIntercomPresent = ref<boolean>(false)
|
||||
const copied = ref<Record<string, boolean>>({})
|
||||
|
||||
const stopTimer = (n: WebNotification) => notificationManager.stopNotificationTimer(n)
|
||||
const setNotificationTimer = (n: WebNotification) => notificationManager.setNotificationTimer(n)
|
||||
const dismissNotification = (n: number) => notificationManager.removeNotificationByIndex(n)
|
||||
|
||||
function createNotifText(notif: WebNotification): string {
|
||||
return [notif.title, notif.text, notif.errorCode].filter(Boolean).join('\n')
|
||||
function stopTimer(notif) {
|
||||
clearTimeout(notif.timer);
|
||||
}
|
||||
|
||||
function checkIntercomPresence(): void {
|
||||
isIntercomPresent.value = !!document.querySelector('.intercom-lightweight-app')
|
||||
}
|
||||
const copied = ref({});
|
||||
|
||||
function copyToClipboard(notif: WebNotification): void {
|
||||
const text = createNotifText(notif)
|
||||
const createNotifText = (notif) => {
|
||||
let text = "";
|
||||
if (notif.title) {
|
||||
text += notif.title;
|
||||
}
|
||||
if (notif.text) {
|
||||
if (text.length > 0) {
|
||||
text += "\n";
|
||||
}
|
||||
text += notif.text;
|
||||
}
|
||||
if (notif.errorCode) {
|
||||
if (text.length > 0) {
|
||||
text += "\n";
|
||||
}
|
||||
text += notif.errorCode;
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
copied.value[text] = true
|
||||
navigator.clipboard.writeText(text)
|
||||
|
||||
setTimeout(() => {
|
||||
const { [text]: _, ...rest } = copied.value
|
||||
copied.value = rest
|
||||
}, 2000)
|
||||
function checkIntercomPresence() {
|
||||
isIntercomPresent.value = !!document.querySelector(".intercom-lightweight-app");
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
checkIntercomPresence()
|
||||
checkIntercomPresence();
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
checkIntercomPresence()
|
||||
})
|
||||
checkIntercomPresence();
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
})
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
observer.disconnect()
|
||||
})
|
||||
})
|
||||
observer.disconnect();
|
||||
});
|
||||
});
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
hasSidebar?: boolean
|
||||
}>(),
|
||||
{
|
||||
hasSidebar: false,
|
||||
},
|
||||
)
|
||||
function copyToClipboard(notif) {
|
||||
const text = createNotifText(notif);
|
||||
|
||||
copied.value[text] = true;
|
||||
navigator.clipboard.writeText(text);
|
||||
setTimeout(() => {
|
||||
delete copied.value[text];
|
||||
}, 2000);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vue-notification-group {
|
||||
position: fixed;
|
||||
right: 1.5rem;
|
||||
bottom: 1.5rem;
|
||||
z-index: 200;
|
||||
width: 450px;
|
||||
|
||||
&.location-right {
|
||||
right: 1.5rem;
|
||||
|
||||
&.has-sidebar {
|
||||
right: 325px;
|
||||
}
|
||||
}
|
||||
|
||||
&.location-left {
|
||||
left: 1.5rem;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
width: calc(100% - 0.75rem * 2);
|
||||
right: 0.75rem;
|
||||
bottom: 0.75rem;
|
||||
|
||||
&.location-right {
|
||||
right: 0.75rem;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
&.location-left {
|
||||
left: 0.75rem;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.intercom-present {
|
||||
bottom: 5rem;
|
||||
}
|
||||
|
||||
&.rightwards {
|
||||
right: unset !important;
|
||||
left: 1.5rem;
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
left: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.vue-notification-wrapper {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
@@ -221,12 +208,6 @@ withDefaults(
|
||||
}
|
||||
|
||||
.notifs-leave-to {
|
||||
.location-right & {
|
||||
transform: translateX(100%) scale(0.8);
|
||||
}
|
||||
|
||||
.location-left & {
|
||||
transform: translateX(-100%) scale(0.8);
|
||||
}
|
||||
transform: translateX(100%) scale(0.8);
|
||||
}
|
||||
</style>
|
||||
@@ -15,7 +15,7 @@
|
||||
maxlength="64"
|
||||
:placeholder="`Enter organization name...`"
|
||||
autocomplete="off"
|
||||
@input="updateSlug"
|
||||
@input="updateSlug()"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -33,7 +33,7 @@
|
||||
type="text"
|
||||
maxlength="64"
|
||||
autocomplete="off"
|
||||
@input="setManualSlug"
|
||||
@input="manualSlug = true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -61,7 +61,7 @@
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button @click="hide">
|
||||
<button @click="modal.hide()">
|
||||
<XIcon aria-hidden="true" />
|
||||
Cancel
|
||||
</button>
|
||||
@@ -70,22 +70,20 @@
|
||||
</div>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PlusIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, NewModal, injectNotificationManager } from "@modrinth/ui";
|
||||
import { ref } from "vue";
|
||||
<script setup>
|
||||
import { XIcon, PlusIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
|
||||
const router = useNativeRouter();
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const name = ref<string>("");
|
||||
const slug = ref<string>("");
|
||||
const description = ref<string>("");
|
||||
const manualSlug = ref<boolean>(false);
|
||||
const modal = ref<InstanceType<typeof NewModal>>();
|
||||
const name = ref("");
|
||||
const slug = ref("");
|
||||
const description = ref("");
|
||||
const manualSlug = ref(false);
|
||||
|
||||
async function createOrganization(): Promise<void> {
|
||||
const modal = ref();
|
||||
|
||||
async function createOrganization() {
|
||||
startLoading();
|
||||
try {
|
||||
const value = {
|
||||
@@ -94,18 +92,19 @@ async function createOrganization(): Promise<void> {
|
||||
slug: slug.value.trim().replace(/ +/g, ""),
|
||||
};
|
||||
|
||||
const result: any = await useBaseFetch("organization", {
|
||||
const result = await useBaseFetch("organization", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(value),
|
||||
apiVersion: 3,
|
||||
});
|
||||
|
||||
modal.value?.hide();
|
||||
modal.value.hide();
|
||||
|
||||
await router.push(`/organization/${result.slug}`);
|
||||
} catch (err: any) {
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -113,18 +112,13 @@ async function createOrganization(): Promise<void> {
|
||||
}
|
||||
stopLoading();
|
||||
}
|
||||
|
||||
function show(event?: MouseEvent): void {
|
||||
function show(event) {
|
||||
name.value = "";
|
||||
description.value = "";
|
||||
modal.value?.show(event);
|
||||
modal.value.show(event);
|
||||
}
|
||||
|
||||
function hide(): void {
|
||||
modal.value?.hide();
|
||||
}
|
||||
|
||||
function updateSlug(): void {
|
||||
function updateSlug() {
|
||||
if (!manualSlug.value) {
|
||||
slug.value = name.value
|
||||
.trim()
|
||||
@@ -135,10 +129,6 @@ function updateSlug(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function setManualSlug(): void {
|
||||
manualSlug.value = true;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
|
||||
@@ -109,16 +109,15 @@
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
AsteriskIcon,
|
||||
CheckIcon,
|
||||
ChevronRightIcon,
|
||||
DropdownIcon,
|
||||
LightBulbIcon,
|
||||
ScaleIcon,
|
||||
SendIcon,
|
||||
CheckIcon,
|
||||
XIcon,
|
||||
AsteriskIcon,
|
||||
LightBulbIcon,
|
||||
SendIcon,
|
||||
ScaleIcon,
|
||||
DropdownIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
import { formatProjectType } from "@modrinth/utils";
|
||||
import { acceptTeamInvite, removeTeamMember } from "~/helpers/teams.js";
|
||||
|
||||
@@ -165,8 +164,8 @@ const props = defineProps({
|
||||
type: Function,
|
||||
default() {
|
||||
return () => {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: "setProcessing function not found",
|
||||
type: "error",
|
||||
@@ -178,8 +177,8 @@ const props = defineProps({
|
||||
type: Function,
|
||||
default() {
|
||||
return () => {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: "toggleCollapsed function not found",
|
||||
type: "error",
|
||||
@@ -191,8 +190,8 @@ const props = defineProps({
|
||||
type: Function,
|
||||
default() {
|
||||
return () => {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: "updateMembers function not found",
|
||||
type: "error",
|
||||
|
||||
@@ -118,25 +118,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ClipboardCopyIcon,
|
||||
EllipsisVerticalIcon,
|
||||
EyeIcon,
|
||||
LinkIcon,
|
||||
OrganizationIcon,
|
||||
} from "@modrinth/assets";
|
||||
import type { ExtendedDelphiReport } from "@modrinth/moderation";
|
||||
import dayjs from "dayjs";
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
useRelativeTime,
|
||||
OverflowMenu,
|
||||
type OverflowMenuOption,
|
||||
ButtonStyled,
|
||||
} from "@modrinth/ui";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
import {
|
||||
EllipsisVerticalIcon,
|
||||
OrganizationIcon,
|
||||
EyeIcon,
|
||||
ClipboardCopyIcon,
|
||||
LinkIcon,
|
||||
} from "@modrinth/assets";
|
||||
import type { ExtendedDelphiReport } from "@modrinth/moderation";
|
||||
|
||||
const props = defineProps<{
|
||||
report: ExtendedDelphiReport;
|
||||
|
||||
@@ -135,31 +135,28 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ClipboardCopyIcon,
|
||||
Avatar,
|
||||
useRelativeTime,
|
||||
OverflowMenu,
|
||||
type OverflowMenuOption,
|
||||
CollapsibleRegion,
|
||||
ButtonStyled,
|
||||
} from "@modrinth/ui";
|
||||
import {
|
||||
EllipsisVerticalIcon,
|
||||
EyeIcon,
|
||||
LinkIcon,
|
||||
OrganizationIcon,
|
||||
EyeIcon,
|
||||
ClipboardCopyIcon,
|
||||
LinkIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
type ExtendedReport,
|
||||
reportQuickReplies,
|
||||
type ReportQuickReply,
|
||||
} from "@modrinth/moderation";
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
CollapsibleRegion,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
type OverflowMenuOption,
|
||||
useRelativeTime,
|
||||
} from "@modrinth/ui";
|
||||
import ChevronDownIcon from "../servers/icons/ChevronDownIcon.vue";
|
||||
import ReportThread from "../thread/ReportThread.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
report: ExtendedReport;
|
||||
}>();
|
||||
|
||||
@@ -313,66 +313,65 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
LeftArrowIcon,
|
||||
RightArrowIcon,
|
||||
DropdownIcon,
|
||||
XIcon,
|
||||
ScaleIcon,
|
||||
ListBulletedIcon,
|
||||
FileTextIcon,
|
||||
BrushCleaningIcon,
|
||||
CheckIcon,
|
||||
DropdownIcon,
|
||||
EyeOffIcon,
|
||||
FileTextIcon,
|
||||
KeyboardIcon,
|
||||
LeftArrowIcon,
|
||||
ListBulletedIcon,
|
||||
RightArrowIcon,
|
||||
ScaleIcon,
|
||||
XIcon,
|
||||
EyeOffIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
type Action,
|
||||
type ButtonAction,
|
||||
type ConditionalButtonAction,
|
||||
type DropdownAction,
|
||||
type MultiSelectChipsAction,
|
||||
type Stage,
|
||||
type ToggleAction,
|
||||
checklist,
|
||||
deserializeActionStates,
|
||||
expandVariables,
|
||||
finalPermissionMessages,
|
||||
findMatchingVariant,
|
||||
flattenProjectVariables,
|
||||
getActionIdForStage,
|
||||
getActionMessage,
|
||||
getVisibleInputs,
|
||||
handleKeybind,
|
||||
initializeActionState,
|
||||
kebabToTitleCase,
|
||||
keybinds,
|
||||
getActionMessage,
|
||||
findMatchingVariant,
|
||||
processMessage,
|
||||
getVisibleInputs,
|
||||
serializeActionStates,
|
||||
deserializeActionStates,
|
||||
kebabToTitleCase,
|
||||
flattenProjectVariables,
|
||||
expandVariables,
|
||||
handleKeybind,
|
||||
keybinds,
|
||||
} from "@modrinth/moderation";
|
||||
import {
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
Collapsible,
|
||||
DropdownSelect,
|
||||
MarkdownEditor,
|
||||
OverflowMenu,
|
||||
type OverflowMenuOption,
|
||||
injectNotificationManager,
|
||||
Checkbox,
|
||||
DropdownSelect,
|
||||
MarkdownEditor,
|
||||
} from "@modrinth/ui";
|
||||
import {
|
||||
type ModerationJudgements,
|
||||
type ModerationModpackItem,
|
||||
type Project,
|
||||
renderHighlightedString,
|
||||
type ModerationJudgements,
|
||||
type ModerationModpackItem,
|
||||
type ProjectStatus,
|
||||
} from "@modrinth/utils";
|
||||
import { computedAsync, useLocalStorage } from "@vueuse/core";
|
||||
import {
|
||||
type Action,
|
||||
type MultiSelectChipsAction,
|
||||
type DropdownAction,
|
||||
type ButtonAction,
|
||||
type ToggleAction,
|
||||
type ConditionalButtonAction,
|
||||
type Stage,
|
||||
finalPermissionMessages,
|
||||
} from "@modrinth/moderation";
|
||||
import * as prettier from "prettier";
|
||||
import { useModerationStore } from "~/store/moderation.ts";
|
||||
import KeybindsModal from "./ChecklistKeybindsModal.vue";
|
||||
import ModpackPermissionsFlow from "./ModpackPermissionsFlow.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
import KeybindsModal from "./ChecklistKeybindsModal.vue";
|
||||
import { useModerationStore } from "~/store/moderation.ts";
|
||||
|
||||
const keybindsModal = ref<InstanceType<typeof KeybindsModal>>();
|
||||
|
||||
|
||||
@@ -42,14 +42,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, computed } from "vue";
|
||||
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
import { IssuesIcon, PlusIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, injectNotificationManager, NewModal } from "@modrinth/ui";
|
||||
import { ModrinthServersFetchError, type ServerBackup } from "@modrinth/utils";
|
||||
import { computed, nextTick, ref } from "vue";
|
||||
import { ModrinthServer } from "~/composables/servers/modrinth-servers.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
server: ModrinthServer;
|
||||
}>();
|
||||
|
||||
@@ -45,14 +45,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { IssuesIcon, SaveIcon, SpinnerIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, injectNotificationManager, NewModal } from "@modrinth/ui";
|
||||
import { ref, nextTick, computed } from "vue";
|
||||
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
import { SpinnerIcon, SaveIcon, XIcon, IssuesIcon } from "@modrinth/assets";
|
||||
import type { Backup } from "@modrinth/utils";
|
||||
import { computed, nextTick, ref } from "vue";
|
||||
import { ModrinthServer } from "~/composables/servers/modrinth-servers.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
server: ModrinthServer;
|
||||
}>();
|
||||
|
||||
@@ -17,14 +17,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ConfirmModal, injectNotificationManager, NewModal } from "@modrinth/ui";
|
||||
import type { Backup } from "@modrinth/utils";
|
||||
import { ref } from "vue";
|
||||
import { ConfirmModal, NewModal } from "@modrinth/ui";
|
||||
import type { Backup } from "@modrinth/utils";
|
||||
import BackupItem from "~/components/ui/servers/BackupItem.vue";
|
||||
import { ModrinthServer } from "~/composables/servers/modrinth-servers.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
server: ModrinthServer;
|
||||
}>();
|
||||
|
||||
@@ -56,13 +56,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SaveIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, injectNotificationManager, NewModal } from "@modrinth/ui";
|
||||
import { computed, ref } from "vue";
|
||||
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
import { XIcon, SaveIcon } from "@modrinth/assets";
|
||||
import { ref, computed } from "vue";
|
||||
import { ModrinthServer } from "~/composables/servers/modrinth-servers.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
server: ModrinthServer;
|
||||
}>();
|
||||
@@ -112,6 +110,7 @@ const fetchSettings = async () => {
|
||||
} catch (error) {
|
||||
console.error("Error fetching backup settings:", error);
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Error",
|
||||
text: "Failed to load backup settings",
|
||||
type: "error",
|
||||
@@ -136,6 +135,7 @@ const saveSettings = async () => {
|
||||
};
|
||||
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Success",
|
||||
text: "Backup settings updated successfully",
|
||||
type: "success",
|
||||
@@ -145,6 +145,7 @@ const saveSettings = async () => {
|
||||
} catch (error) {
|
||||
console.error("Error saving backup settings:", error);
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Error",
|
||||
text: "Failed to save backup settings",
|
||||
type: "error",
|
||||
|
||||
@@ -101,13 +101,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { CheckCircleIcon, FolderOpenIcon, XCircleIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, injectNotificationManager } from "@modrinth/ui";
|
||||
import { computed, nextTick, ref, watch } from "vue";
|
||||
import { FolderOpenIcon, CheckCircleIcon, XCircleIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled } from "@modrinth/ui";
|
||||
import { ref, computed, watch, nextTick } from "vue";
|
||||
import { FSModule } from "~/composables/servers/modules/fs.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
interface UploadItem {
|
||||
file: File;
|
||||
progress: number;
|
||||
@@ -284,6 +282,7 @@ const uploadFile = async (file: File) => {
|
||||
|
||||
if (error instanceof Error && error.message !== "Upload cancelled") {
|
||||
addNotification({
|
||||
group: "files",
|
||||
title: "Upload failed",
|
||||
text: `Failed to upload ${file.name}`,
|
||||
type: "error",
|
||||
|
||||
@@ -67,13 +67,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
import { DownloadIcon, XIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, injectNotificationManager, NewModal } from "@modrinth/ui";
|
||||
import { ModrinthServersFetchError } from "@modrinth/utils";
|
||||
import { ModrinthServer } from "~/composables/servers/modrinth-servers.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
server: ModrinthServer;
|
||||
project: any;
|
||||
@@ -114,12 +112,14 @@ const handleReinstall = async () => {
|
||||
} catch (error) {
|
||||
if (error instanceof ModrinthServersFetchError && error.statusCode === 429) {
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Cannot reinstall server",
|
||||
text: "You are being rate limited. Please try again later.",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Reinstall Failed",
|
||||
text: "An unexpected error occurred while reinstalling. Please try again later.",
|
||||
type: "error",
|
||||
|
||||
@@ -144,20 +144,18 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BackupWarning, ButtonStyled, NewModal } from "@modrinth/ui";
|
||||
import {
|
||||
ArrowBigRightDashIcon,
|
||||
RightArrowIcon,
|
||||
ServerIcon,
|
||||
UploadIcon,
|
||||
RightArrowIcon,
|
||||
XIcon,
|
||||
ServerIcon,
|
||||
ArrowBigRightDashIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { BackupWarning, ButtonStyled, injectNotificationManager, NewModal } from "@modrinth/ui";
|
||||
import { formatBytes, ModrinthServersFetchError } from "@modrinth/utils";
|
||||
import { onMounted, onUnmounted } from "vue";
|
||||
import type { ModrinthServer } from "~/composables/servers/modrinth-servers";
|
||||
import type { BackupInProgressReason } from "~/pages/servers/manage/[id].vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
import type { ModrinthServer } from "~/composables/servers/modrinth-servers";
|
||||
|
||||
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
|
||||
if (isLoading.value) {
|
||||
@@ -252,6 +250,7 @@ const handleReinstall = async () => {
|
||||
|
||||
if (!mrpackFile.value) {
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "No file selected",
|
||||
text: "Choose a .mrpack file before installing.",
|
||||
type: "error",
|
||||
@@ -302,12 +301,14 @@ const handleReinstall = async () => {
|
||||
} catch (error) {
|
||||
if (error instanceof ModrinthServersFetchError && error.statusCode === 429) {
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Cannot upload and install modpack to server",
|
||||
text: "You are being rate limited. Please try again later.",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Modpack upload and install failed",
|
||||
text: "An unexpected error occurred while uploading/installing. Please try again later.",
|
||||
type: "error",
|
||||
|
||||
@@ -197,20 +197,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BackupWarning, ButtonStyled, NewModal, Toggle } from "@modrinth/ui";
|
||||
import { DropdownIcon, RightArrowIcon, ServerIcon, XIcon } from "@modrinth/assets";
|
||||
import {
|
||||
BackupWarning,
|
||||
ButtonStyled,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Toggle,
|
||||
} from "@modrinth/ui";
|
||||
import { type Loaders, ModrinthServersFetchError } from "@modrinth/utils";
|
||||
import { $fetch } from "ofetch";
|
||||
import { ModrinthServer } from "~/composables/servers/modrinth-servers.ts";
|
||||
import { type Loaders, ModrinthServersFetchError } from "@modrinth/utils";
|
||||
import type { BackupInProgressReason } from "~/pages/servers/manage/[id].vue";
|
||||
import { ModrinthServer } from "~/composables/servers/modrinth-servers.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const { formatMessage } = useVIntl();
|
||||
|
||||
interface LoaderVersion {
|
||||
@@ -482,12 +475,14 @@ const handleReinstall = async () => {
|
||||
} catch (error) {
|
||||
if (error instanceof ModrinthServersFetchError && (error as any)?.statusCode === 429) {
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Cannot reinstall server",
|
||||
text: "You are being rate limited. Please try again later.",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
addNotification({
|
||||
group: "server",
|
||||
title: "Reinstall Failed",
|
||||
text: "An unexpected error occurred while reinstalling. Please try again later.",
|
||||
type: "error",
|
||||
|
||||
@@ -20,11 +20,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LinkIcon } from "@modrinth/assets";
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
import { useStorage } from "@vueuse/core";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
subdomain: string;
|
||||
noSeparator?: boolean;
|
||||
@@ -33,6 +30,7 @@ const props = defineProps<{
|
||||
const copySubdomain = () => {
|
||||
navigator.clipboard.writeText(props.subdomain + ".modrinth.gg");
|
||||
addNotification({
|
||||
group: "servers",
|
||||
title: "Custom URL copied",
|
||||
text: "Your server's URL has been copied to your clipboard.",
|
||||
type: "success",
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { Accordion, ButtonStyled, NewModal, ServerNotice, TagItem } from "@modrinth/ui";
|
||||
import { PlusIcon, XIcon } from "@modrinth/assets";
|
||||
import {
|
||||
Accordion,
|
||||
ButtonStyled,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
ServerNotice,
|
||||
TagItem,
|
||||
} from "@modrinth/ui";
|
||||
import { type ServerNotice as ServerNoticeType } from "@modrinth/utils";
|
||||
import type { ServerNotice as ServerNoticeType } from "@modrinth/utils";
|
||||
import { ref } from "vue";
|
||||
import { useServersFetch } from "~/composables/servers/servers-fetch.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const app = useNuxtApp() as unknown as { $notify: any };
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>();
|
||||
|
||||
@@ -46,14 +39,16 @@ async function assign(server: boolean = true) {
|
||||
method: "PUT",
|
||||
},
|
||||
).catch((err) => {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error assigning notice",
|
||||
text: err,
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error assigning notice",
|
||||
text: "No server or node specified",
|
||||
type: "error",
|
||||
@@ -69,7 +64,8 @@ async function unassignDetect() {
|
||||
const node = assignedNodes.value.some((assigned) => assigned.id === input);
|
||||
|
||||
if (!server && !node) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error unassigning notice",
|
||||
text: "ID is not an assigned server or node",
|
||||
type: "error",
|
||||
@@ -88,7 +84,8 @@ async function unassign(id: string, server: boolean = true) {
|
||||
method: "PUT",
|
||||
},
|
||||
).catch((err) => {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error unassigning notice",
|
||||
text: err,
|
||||
type: "error",
|
||||
|
||||
@@ -251,25 +251,23 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { CopyCode, OverflowMenu, MarkdownEditor } from "@modrinth/ui";
|
||||
import {
|
||||
CheckCircleIcon,
|
||||
CheckIcon,
|
||||
DropdownIcon,
|
||||
EyeOffIcon,
|
||||
ReplyIcon,
|
||||
ScaleIcon,
|
||||
SendIcon,
|
||||
CheckCircleIcon,
|
||||
XIcon,
|
||||
EyeOffIcon,
|
||||
CheckIcon,
|
||||
ScaleIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { CopyCode, MarkdownEditor, OverflowMenu, injectNotificationManager } from "@modrinth/ui";
|
||||
import Checkbox from "~/components/ui/Checkbox.vue";
|
||||
import Modal from "~/components/ui/Modal.vue";
|
||||
import ThreadMessage from "~/components/ui/thread/ThreadMessage.vue";
|
||||
import { useImageUpload } from "~/composables/image-upload.ts";
|
||||
import { isApproved, isRejected } from "~/helpers/projects.js";
|
||||
import ThreadMessage from "~/components/ui/thread/ThreadMessage.vue";
|
||||
import { isStaff } from "~/helpers/users.js";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
import { isApproved, isRejected } from "~/helpers/projects.js";
|
||||
import Modal from "~/components/ui/Modal.vue";
|
||||
import Checkbox from "~/components/ui/Checkbox.vue";
|
||||
|
||||
const props = defineProps({
|
||||
thread: {
|
||||
@@ -390,7 +388,8 @@ async function sendReply(status = null, privateMessage = false) {
|
||||
props.setStatus(status);
|
||||
}
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error sending message",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -412,7 +411,8 @@ async function closeReport(reply) {
|
||||
});
|
||||
await updateThreadLocal();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error closing report",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -430,7 +430,8 @@ async function reopenReport() {
|
||||
});
|
||||
await updateThreadLocal();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error reopening report",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -110,15 +110,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { CheckCircleIcon, ReplyIcon, ScaleIcon, SendIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, CopyCode, injectNotificationManager, MarkdownEditor } from "@modrinth/ui";
|
||||
import type { Report, Thread, ThreadMessage as TypeThreadMessage, User } from "@modrinth/utils";
|
||||
import { CopyCode, MarkdownEditor, ButtonStyled } from "@modrinth/ui";
|
||||
import { ReplyIcon, SendIcon, CheckCircleIcon, ScaleIcon } from "@modrinth/assets";
|
||||
import type { Thread, Report, User, ThreadMessage as TypeThreadMessage } from "@modrinth/utils";
|
||||
import dayjs from "dayjs";
|
||||
import ThreadMessage from "./ThreadMessage.vue";
|
||||
import { useImageUpload } from "~/composables/image-upload.ts";
|
||||
import { isStaff } from "~/helpers/users.js";
|
||||
import ThreadMessage from "./ThreadMessage.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps<{
|
||||
thread: Thread;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
|
||||
export const useAuth = async (oldToken = null) => {
|
||||
const auth = useState("auth", () => ({
|
||||
user: null,
|
||||
@@ -130,8 +128,9 @@ export const removeAuthProvider = async (provider) => {
|
||||
});
|
||||
await useAuth(auth.value.token);
|
||||
} catch (err) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
const data = useNuxtApp();
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data.description,
|
||||
type: "error",
|
||||
|
||||
38
apps/frontend/src/composables/notifs.js
Normal file
38
apps/frontend/src/composables/notifs.js
Normal file
@@ -0,0 +1,38 @@
|
||||
export const useNotifications = () => useState("notifications", () => []);
|
||||
|
||||
export const addNotification = (notification) => {
|
||||
const notifications = useNotifications();
|
||||
|
||||
const existingNotif = notifications.value.find(
|
||||
(x) =>
|
||||
x.text === notification.text &&
|
||||
x.title === notification.title &&
|
||||
x.type === notification.type,
|
||||
);
|
||||
if (existingNotif) {
|
||||
setNotificationTimer(existingNotif);
|
||||
existingNotif.count++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
notification.id = new Date();
|
||||
notification.count = 1;
|
||||
|
||||
setNotificationTimer(notification);
|
||||
notifications.value.push(notification);
|
||||
};
|
||||
|
||||
export const setNotificationTimer = (notification) => {
|
||||
if (!notification) return;
|
||||
|
||||
const notifications = useNotifications();
|
||||
|
||||
if (notification.timer) {
|
||||
clearTimeout(notification.timer);
|
||||
}
|
||||
|
||||
notification.timer = setTimeout(() => {
|
||||
notifications.value.splice(notifications.value.indexOf(notification), 1);
|
||||
}, 30000);
|
||||
};
|
||||
@@ -1,20 +1,18 @@
|
||||
import type { JWTAuth, ModuleError, ModuleName } from "@modrinth/utils";
|
||||
import { ModrinthServerError } from "@modrinth/utils";
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
import type { JWTAuth, ModuleError, ModuleName } from "@modrinth/utils";
|
||||
import { useServersFetch } from "./servers-fetch.ts";
|
||||
|
||||
import {
|
||||
BackupsModule,
|
||||
ContentModule,
|
||||
FSModule,
|
||||
GeneralModule,
|
||||
ContentModule,
|
||||
BackupsModule,
|
||||
NetworkModule,
|
||||
StartupModule,
|
||||
WSModule,
|
||||
FSModule,
|
||||
} from "./modules/index.ts";
|
||||
|
||||
export function handleError(err: any) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
if (err instanceof ModrinthServerError && err.v1Error) {
|
||||
addNotification({
|
||||
title: err.v1Error?.context ?? `An error occurred`,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
|
||||
type AsyncFunction<TArgs extends any[], TResult> = (...args: TArgs) => Promise<TResult>;
|
||||
type ErrorFunction = (err: any) => void | Promise<void>;
|
||||
type VoidFunction = () => void | Promise<void>;
|
||||
@@ -11,8 +9,8 @@ type useClientTry = <TArgs extends any[], TResult>(
|
||||
) => (...args: TArgs) => Promise<TResult | undefined>;
|
||||
|
||||
const defaultOnError: ErrorFunction = (error) => {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: error?.data?.description || error.message || error || "Unknown error",
|
||||
type: "error",
|
||||
|
||||
@@ -135,8 +135,7 @@ export const userFollowProject = async (project) => {
|
||||
}
|
||||
};
|
||||
export const resendVerifyEmail = async () => {
|
||||
// const { injectNotificationManager } = await import("@modrinth/ui");
|
||||
// const { addNotification } = injectNotificationManager();
|
||||
const app = useNuxtApp();
|
||||
|
||||
startLoading();
|
||||
try {
|
||||
@@ -145,13 +144,15 @@ export const resendVerifyEmail = async () => {
|
||||
});
|
||||
|
||||
const auth = await useAuth();
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Email sent",
|
||||
text: `An email with a link to verify your account has been sent to ${auth.value.user.email}.`,
|
||||
type: "success",
|
||||
});
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data.description,
|
||||
type: "error",
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
import type { Organization, Project, Report, User, Version } from "@modrinth/utils";
|
||||
import { useNuxtApp } from "#imports";
|
||||
|
||||
// TODO: There needs to be a standardized way to get these types, eg; @modrinth/types generated from api schema. Later problem.
|
||||
type Project = { id: string };
|
||||
type Version = { id: string; project_id: string };
|
||||
type Report = { id: string; item_type: "project" | "user" | "version"; item_id: string };
|
||||
type Thread = { id: string };
|
||||
type User = { id: string };
|
||||
type Organization = { id: string };
|
||||
|
||||
export type PlatformNotificationAction = {
|
||||
export type NotificationAction = {
|
||||
title: string;
|
||||
action_route: [string, string];
|
||||
};
|
||||
|
||||
export type PlatformNotificationBody = {
|
||||
export type NotificationBody = {
|
||||
project_id?: string;
|
||||
version_id?: string;
|
||||
report_id?: string;
|
||||
@@ -17,7 +22,7 @@ export type PlatformNotificationBody = {
|
||||
organization_id?: string;
|
||||
};
|
||||
|
||||
export type PlatformNotification = {
|
||||
export type Notification = {
|
||||
id: string;
|
||||
user_id: string;
|
||||
type: "project_update" | "team_invite" | "status_change" | "moderator_message";
|
||||
@@ -26,10 +31,10 @@ export type PlatformNotification = {
|
||||
link: string;
|
||||
read: boolean;
|
||||
created: string;
|
||||
actions: PlatformNotificationAction[];
|
||||
body?: PlatformNotificationBody;
|
||||
actions: NotificationAction[];
|
||||
body?: NotificationBody;
|
||||
extra_data?: Record<string, unknown>;
|
||||
grouped_notifs?: PlatformNotification[];
|
||||
grouped_notifs?: Notification[];
|
||||
};
|
||||
|
||||
async function getBulk<T extends { id: string }>(
|
||||
@@ -50,8 +55,8 @@ async function getBulk<T extends { id: string }>(
|
||||
}
|
||||
|
||||
export async function fetchExtraNotificationData(
|
||||
notifications: PlatformNotification[],
|
||||
): Promise<PlatformNotification[]> {
|
||||
notifications: Notification[],
|
||||
): Promise<Notification[]> {
|
||||
const bulk = {
|
||||
projects: [] as string[],
|
||||
reports: [] as string[],
|
||||
@@ -128,8 +133,8 @@ export async function fetchExtraNotificationData(
|
||||
return notifications;
|
||||
}
|
||||
|
||||
export function groupNotifications(notifications: PlatformNotification[]): PlatformNotification[] {
|
||||
const grouped: PlatformNotification[] = [];
|
||||
export function groupNotifications(notifications: Notification[]): Notification[] {
|
||||
const grouped: Notification[] = [];
|
||||
for (let i = 0; i < notifications.length; i++) {
|
||||
const current = notifications[i];
|
||||
const next = notifications[i + 1];
|
||||
@@ -149,18 +154,18 @@ export function groupNotifications(notifications: PlatformNotification[]): Platf
|
||||
return grouped;
|
||||
}
|
||||
|
||||
function isSimilar(a: PlatformNotification, b: PlatformNotification | undefined): boolean {
|
||||
function isSimilar(a: Notification, b: Notification | undefined): boolean {
|
||||
return !!a?.body?.project_id && a.body!.project_id === b?.body?.project_id;
|
||||
}
|
||||
|
||||
export async function markAsRead(
|
||||
ids: string[],
|
||||
): Promise<(notifications: PlatformNotification[]) => PlatformNotification[]> {
|
||||
): Promise<(notifications: Notification[]) => Notification[]> {
|
||||
try {
|
||||
await useBaseFetch(`notifications?ids=${JSON.stringify([...new Set(ids)])}`, {
|
||||
method: "PATCH",
|
||||
});
|
||||
return (notifications: PlatformNotification[]) => {
|
||||
return (notifications: Notification[]) => {
|
||||
const newNotifs = notifications ?? [];
|
||||
newNotifs.forEach((n) => {
|
||||
if (ids.includes(n.id)) n.read = true;
|
||||
@@ -168,8 +173,9 @@ export async function markAsRead(
|
||||
return newNotifs;
|
||||
};
|
||||
} catch (err: any) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
const app: any = useNuxtApp();
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error marking notification as read",
|
||||
text: err?.data?.description ?? err,
|
||||
type: "error",
|
||||
@@ -666,65 +666,65 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import {
|
||||
ArrowBigUpDashIcon,
|
||||
BellIcon,
|
||||
BlueskyIcon,
|
||||
BookmarkIcon,
|
||||
BoxIcon,
|
||||
BracesIcon,
|
||||
ChartIcon,
|
||||
CollectionIcon,
|
||||
CompassIcon,
|
||||
CurrencyIcon,
|
||||
DiscordIcon,
|
||||
DownloadIcon,
|
||||
DropdownIcon,
|
||||
GithubIcon,
|
||||
GlassesIcon,
|
||||
HamburgerIcon,
|
||||
HomeIcon,
|
||||
IssuesIcon,
|
||||
LibraryIcon,
|
||||
LogInIcon,
|
||||
LogOutIcon,
|
||||
MastodonIcon,
|
||||
ModrinthIcon,
|
||||
ArrowBigUpDashIcon,
|
||||
BookmarkIcon,
|
||||
ServerIcon,
|
||||
LogInIcon,
|
||||
DownloadIcon,
|
||||
LibraryIcon,
|
||||
XIcon,
|
||||
IssuesIcon,
|
||||
ReportIcon,
|
||||
CompassIcon,
|
||||
HamburgerIcon,
|
||||
SearchIcon,
|
||||
BellIcon,
|
||||
SettingsIcon,
|
||||
HomeIcon,
|
||||
MoonIcon,
|
||||
OrganizationIcon,
|
||||
PackageOpenIcon,
|
||||
PaintbrushIcon,
|
||||
SunIcon,
|
||||
PlugIcon,
|
||||
PlusIcon,
|
||||
ReportIcon,
|
||||
ScaleIcon,
|
||||
SearchIcon,
|
||||
ServerIcon,
|
||||
SettingsIcon,
|
||||
SunIcon,
|
||||
TwitterIcon,
|
||||
DropdownIcon,
|
||||
LogOutIcon,
|
||||
ChartIcon,
|
||||
BoxIcon,
|
||||
CollectionIcon,
|
||||
OrganizationIcon,
|
||||
UserIcon,
|
||||
XIcon,
|
||||
CurrencyIcon,
|
||||
BracesIcon,
|
||||
GlassesIcon,
|
||||
PaintbrushIcon,
|
||||
PackageOpenIcon,
|
||||
DiscordIcon,
|
||||
BlueskyIcon,
|
||||
TwitterIcon,
|
||||
MastodonIcon,
|
||||
GithubIcon,
|
||||
ScaleIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
injectNotificationManager,
|
||||
OverflowMenu,
|
||||
PagewideBanner,
|
||||
Avatar,
|
||||
commonMessages,
|
||||
} from "@modrinth/ui";
|
||||
import { isAdmin, isStaff } from "@modrinth/utils";
|
||||
import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue";
|
||||
import { errors as generatedStateErrors } from "~/generated/state.json";
|
||||
|
||||
import ModalCreation from "~/components/ui/ModalCreation.vue";
|
||||
import { getProjectTypeMessage } from "~/utils/i18n-project-type.ts";
|
||||
import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue";
|
||||
import OrganizationCreateModal from "~/components/ui/OrganizationCreateModal.vue";
|
||||
import TeleportOverflowMenu from "~/components/ui/servers/TeleportOverflowMenu.vue";
|
||||
import { errors as generatedStateErrors } from "~/generated/state.json";
|
||||
import { getProjectTypeMessage } from "~/utils/i18n-project-type.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const { formatMessage } = useVIntl();
|
||||
|
||||
const app = useNuxtApp();
|
||||
const auth = await useAuth();
|
||||
const user = await useUser();
|
||||
|
||||
@@ -1079,13 +1079,15 @@ function developerModeIncrement() {
|
||||
developerModeCounter.value = 0;
|
||||
saveFeatureFlags();
|
||||
if (flags.value.developerMode) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Developer mode activated",
|
||||
text: "Developer mode has been enabled",
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Developer mode deactivated",
|
||||
text: "Developer mode has been disabled",
|
||||
type: "success",
|
||||
|
||||
@@ -890,7 +890,6 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { navigateTo } from "#app";
|
||||
import {
|
||||
BookmarkIcon,
|
||||
BookTextIcon,
|
||||
@@ -907,7 +906,6 @@ import {
|
||||
HeartIcon,
|
||||
InfoIcon,
|
||||
LinkIcon as LinksIcon,
|
||||
ModrinthIcon,
|
||||
MoreVerticalIcon,
|
||||
PlusIcon,
|
||||
ReportIcon,
|
||||
@@ -919,13 +917,13 @@ import {
|
||||
UsersIcon,
|
||||
VersionIcon,
|
||||
WrenchIcon,
|
||||
ModrinthIcon,
|
||||
XIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
OverflowMenu,
|
||||
PopoutMenu,
|
||||
@@ -937,37 +935,36 @@ import {
|
||||
ProjectSidebarLinks,
|
||||
ProjectStatusBadge,
|
||||
ScrollablePanel,
|
||||
ServersPromo,
|
||||
TagItem,
|
||||
ServersPromo,
|
||||
useRelativeTime,
|
||||
} from "@modrinth/ui";
|
||||
import VersionSummary from "@modrinth/ui/src/components/version/VersionSummary.vue";
|
||||
import { formatCategory, formatProjectType, renderString } from "@modrinth/utils";
|
||||
import { useLocalStorage } from "@vueuse/core";
|
||||
import dayjs from "dayjs";
|
||||
import { Tooltip } from "floating-vue";
|
||||
import { useLocalStorage } from "@vueuse/core";
|
||||
import { navigateTo } from "#app";
|
||||
import Accordion from "~/components/ui/Accordion.vue";
|
||||
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
|
||||
import AutomaticAccordion from "~/components/ui/AutomaticAccordion.vue";
|
||||
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
|
||||
import CollectionCreateModal from "~/components/ui/CollectionCreateModal.vue";
|
||||
import MessageBanner from "~/components/ui/MessageBanner.vue";
|
||||
import ModerationChecklist from "~/components/ui/moderation/checklist/ModerationChecklist.vue";
|
||||
import NavStack from "~/components/ui/NavStack.vue";
|
||||
import NavStackItem from "~/components/ui/NavStackItem.vue";
|
||||
import NavTabs from "~/components/ui/NavTabs.vue";
|
||||
import ProjectMemberHeader from "~/components/ui/ProjectMemberHeader.vue";
|
||||
import { saveFeatureFlags } from "~/composables/featureFlags.ts";
|
||||
import { userCollectProject } from "~/composables/user.js";
|
||||
import { useModerationStore } from "~/store/moderation.ts";
|
||||
import { reportProject } from "~/utils/report-helpers.ts";
|
||||
import { saveFeatureFlags } from "~/composables/featureFlags.ts";
|
||||
import ModerationChecklist from "~/components/ui/moderation/checklist/ModerationChecklist.vue";
|
||||
import { useModerationStore } from "~/store/moderation.ts";
|
||||
|
||||
const data = useNuxtApp();
|
||||
const route = useNativeRoute();
|
||||
const config = useRuntimeConfig();
|
||||
const moderationStore = useModerationStore();
|
||||
const notifications = injectNotificationManager();
|
||||
const { addNotification } = notifications;
|
||||
|
||||
const auth = await useAuth();
|
||||
const user = await useUser();
|
||||
@@ -977,6 +974,7 @@ const flags = useFeatureFlags();
|
||||
const cosmetics = useCosmetics();
|
||||
|
||||
const { formatMessage } = useVIntl();
|
||||
const { setVisible } = useNotificationRightwards();
|
||||
|
||||
const settingsModal = ref();
|
||||
const downloadModal = ref();
|
||||
@@ -1427,7 +1425,8 @@ async function setProcessing() {
|
||||
|
||||
project.value.status = "processing";
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -1460,7 +1459,8 @@ async function patchProject(resData, quiet = false) {
|
||||
|
||||
result = true;
|
||||
if (!quiet) {
|
||||
addNotification({
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: "Project updated",
|
||||
text: "Your project has been updated.",
|
||||
type: "success",
|
||||
@@ -1468,7 +1468,8 @@ async function patchProject(resData, quiet = false) {
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
}
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -1497,13 +1498,15 @@ async function patchIcon(icon) {
|
||||
);
|
||||
await resetProject();
|
||||
result = true;
|
||||
addNotification({
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: "Project icon updated",
|
||||
text: "Your project's icon has been updated.",
|
||||
type: "success",
|
||||
});
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -1552,15 +1555,11 @@ const collapsedModerationChecklist = useLocalStorage("collapsed-moderation-check
|
||||
watch(
|
||||
showModerationChecklist,
|
||||
(newValue) => {
|
||||
notifications.setNotificationLocation(newValue ? "left" : "right");
|
||||
setVisible(newValue);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
notifications.setNotificationLocation("right");
|
||||
});
|
||||
|
||||
if (import.meta.client && history && history.state && history.state.showChecklist) {
|
||||
showModerationChecklist.value = true;
|
||||
}
|
||||
|
||||
@@ -278,26 +278,26 @@
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
CalendarIcon,
|
||||
ContractIcon,
|
||||
EditIcon,
|
||||
ExpandIcon,
|
||||
ExternalIcon,
|
||||
ImageIcon,
|
||||
InfoIcon,
|
||||
LeftArrowIcon,
|
||||
PlusIcon,
|
||||
RightArrowIcon,
|
||||
CalendarIcon,
|
||||
EditIcon,
|
||||
TrashIcon,
|
||||
SaveIcon,
|
||||
StarIcon,
|
||||
TransferIcon,
|
||||
TrashIcon,
|
||||
UploadIcon,
|
||||
XIcon,
|
||||
RightArrowIcon,
|
||||
LeftArrowIcon,
|
||||
ExternalIcon,
|
||||
ExpandIcon,
|
||||
ContractIcon,
|
||||
UploadIcon,
|
||||
InfoIcon,
|
||||
ImageIcon,
|
||||
TransferIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { ConfirmModal, injectNotificationManager } from "@modrinth/ui";
|
||||
import DropArea from "~/components/ui/DropArea.vue";
|
||||
import { ConfirmModal } from "@modrinth/ui";
|
||||
import FileInput from "~/components/ui/FileInput.vue";
|
||||
import DropArea from "~/components/ui/DropArea.vue";
|
||||
import Modal from "~/components/ui/Modal.vue";
|
||||
|
||||
import { isPermission } from "~/utils/permissions.ts";
|
||||
@@ -425,8 +425,6 @@ export default defineNuxtComponent({
|
||||
this.shouldPreventActions = true;
|
||||
startLoading();
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
try {
|
||||
let url = `project/${this.project.id}/gallery?ext=${
|
||||
this.editFile
|
||||
@@ -452,7 +450,8 @@ export default defineNuxtComponent({
|
||||
|
||||
this.$refs.modal_edit_item.hide();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -466,8 +465,6 @@ export default defineNuxtComponent({
|
||||
this.shouldPreventActions = true;
|
||||
startLoading();
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
try {
|
||||
let url = `project/${this.project.id}/gallery?url=${encodeURIComponent(
|
||||
this.project.gallery[this.editIndex].url,
|
||||
@@ -490,7 +487,8 @@ export default defineNuxtComponent({
|
||||
await this.resetProject();
|
||||
this.$refs.modal_edit_item.hide();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -503,8 +501,6 @@ export default defineNuxtComponent({
|
||||
async deleteGalleryImage() {
|
||||
startLoading();
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
try {
|
||||
await useBaseFetch(
|
||||
`project/${this.project.id}/gallery?url=${encodeURIComponent(
|
||||
@@ -517,7 +513,8 @@ export default defineNuxtComponent({
|
||||
|
||||
await this.resetProject();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckIcon, IssuesIcon, XIcon } from "@modrinth/assets";
|
||||
import { Badge, injectNotificationManager } from "@modrinth/ui";
|
||||
import { XIcon, CheckIcon, IssuesIcon } from "@modrinth/assets";
|
||||
import { Badge } from "@modrinth/ui";
|
||||
import ConversationThread from "~/components/ui/thread/ConversationThread.vue";
|
||||
import {
|
||||
getProjectLink,
|
||||
@@ -111,7 +111,6 @@ import {
|
||||
isUnderReview,
|
||||
} from "~/helpers/projects.js";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const props = defineProps({
|
||||
project: {
|
||||
type: Object,
|
||||
@@ -132,6 +131,7 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const app = useNuxtApp();
|
||||
const auth = await useAuth();
|
||||
|
||||
const { data: thread } = await useAsyncData(`thread/${props.project.thread_id}`, () =>
|
||||
@@ -153,7 +153,8 @@ async function setStatus(status) {
|
||||
await props.resetProject();
|
||||
thread.value = await useBaseFetch(`thread/${thread.value.id}`);
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -239,14 +239,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { CheckIcon, IssuesIcon, SaveIcon, TrashIcon, UploadIcon, XIcon } from "@modrinth/assets";
|
||||
import { Avatar, ConfirmModal, injectNotificationManager } from "@modrinth/ui";
|
||||
import { formatProjectStatus, formatProjectType } from "@modrinth/utils";
|
||||
import { UploadIcon, SaveIcon, TrashIcon, XIcon, IssuesIcon, CheckIcon } from "@modrinth/assets";
|
||||
import { Multiselect } from "vue-multiselect";
|
||||
import { ConfirmModal, Avatar } from "@modrinth/ui";
|
||||
import FileInput from "~/components/ui/FileInput.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps({
|
||||
project: {
|
||||
type: Object,
|
||||
@@ -376,6 +374,7 @@ const deleteProject = async () => {
|
||||
await initUserProjects();
|
||||
await router.push("/dashboard/projects");
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "Project deleted",
|
||||
text: "Your project has been deleted.",
|
||||
type: "success",
|
||||
@@ -394,6 +393,7 @@ const deleteIcon = async () => {
|
||||
});
|
||||
await props.resetProject();
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "Project icon removed",
|
||||
text: "Your project's icon has been removed.",
|
||||
type: "success",
|
||||
|
||||
@@ -518,30 +518,21 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
CheckIcon,
|
||||
CrownIcon,
|
||||
DropdownIcon,
|
||||
OrganizationIcon,
|
||||
SaveIcon,
|
||||
TransferIcon,
|
||||
UserPlusIcon,
|
||||
UsersIcon,
|
||||
UserXIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
Avatar,
|
||||
Badge,
|
||||
Card,
|
||||
Checkbox,
|
||||
ConfirmModal,
|
||||
injectNotificationManager,
|
||||
} from "@modrinth/ui";
|
||||
import { Multiselect } from "vue-multiselect";
|
||||
import {
|
||||
TransferIcon,
|
||||
CheckIcon,
|
||||
UsersIcon,
|
||||
DropdownIcon,
|
||||
SaveIcon,
|
||||
UserPlusIcon,
|
||||
UserXIcon,
|
||||
OrganizationIcon,
|
||||
CrownIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { Avatar, Badge, Card, Checkbox, ConfirmModal } from "@modrinth/ui";
|
||||
import { removeSelfFromTeam } from "~/helpers/teams.js";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const props = defineProps({
|
||||
project: {
|
||||
type: Object,
|
||||
@@ -663,6 +654,7 @@ const onAddToOrg = useClientTry(async () => {
|
||||
await updateMembers();
|
||||
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "Project transferred",
|
||||
text: "Your project has been transferred to the organization.",
|
||||
type: "success",
|
||||
@@ -683,6 +675,7 @@ const onRemoveFromOrg = useClientTry(async () => {
|
||||
await updateMembers();
|
||||
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "Project removed",
|
||||
text: "Your project has been removed from the organization.",
|
||||
type: "success",
|
||||
@@ -710,6 +703,7 @@ const inviteTeamMember = async () => {
|
||||
await updateMembers();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err?.data?.description || err?.message || err || "Unknown error",
|
||||
type: "error",
|
||||
@@ -732,6 +726,7 @@ const removeTeamMember = async (index) => {
|
||||
await updateMembers();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err?.data?.description || err?.message || err || "Unknown error",
|
||||
type: "error",
|
||||
@@ -765,12 +760,14 @@ const updateTeamMember = async (index) => {
|
||||
);
|
||||
await updateMembers();
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "Member(s) updated",
|
||||
text: "Your project's member(s) has been updated.",
|
||||
type: "success",
|
||||
});
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err?.data?.description || err?.message || err || "Unknown error",
|
||||
type: "error",
|
||||
@@ -793,6 +790,7 @@ const transferOwnership = async (index) => {
|
||||
await updateMembers();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err?.data?.description || err?.message || err || "Unknown error",
|
||||
type: "error",
|
||||
@@ -839,6 +837,7 @@ async function updateOrgMember(index) {
|
||||
await updateMembers();
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err?.data?.description || err?.message || err || "Unknown error",
|
||||
type: "error",
|
||||
|
||||
@@ -113,8 +113,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { SaveIcon, StarIcon } from "@modrinth/assets";
|
||||
import { injectNotificationManager } from "@modrinth/ui";
|
||||
import { StarIcon, SaveIcon } from "@modrinth/assets";
|
||||
import { formatCategory, formatCategoryHeader, formatProjectType } from "@modrinth/utils";
|
||||
import Checkbox from "~/components/ui/Checkbox.vue";
|
||||
|
||||
@@ -147,8 +146,8 @@ export default defineNuxtComponent({
|
||||
type: Function,
|
||||
default() {
|
||||
return () => {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: "Patch project function not found",
|
||||
type: "error",
|
||||
|
||||
@@ -630,47 +630,46 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
BoxIcon,
|
||||
ChevronRightIcon,
|
||||
DownloadIcon,
|
||||
EditIcon,
|
||||
FileIcon,
|
||||
HashIcon,
|
||||
PlusIcon,
|
||||
ReportIcon,
|
||||
RightArrowIcon,
|
||||
SaveIcon,
|
||||
StarIcon,
|
||||
TransferIcon,
|
||||
TrashIcon,
|
||||
UploadIcon,
|
||||
XIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
Avatar,
|
||||
Badge,
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
ConfirmModal,
|
||||
CopyCode,
|
||||
injectNotificationManager,
|
||||
Checkbox,
|
||||
ButtonStyled,
|
||||
ConfirmModal,
|
||||
MarkdownEditor,
|
||||
} from "@modrinth/ui";
|
||||
import { formatBytes, formatCategory } from "@modrinth/utils";
|
||||
import {
|
||||
FileIcon,
|
||||
TrashIcon,
|
||||
EditIcon,
|
||||
DownloadIcon,
|
||||
StarIcon,
|
||||
ReportIcon,
|
||||
SaveIcon,
|
||||
XIcon,
|
||||
HashIcon,
|
||||
PlusIcon,
|
||||
TransferIcon,
|
||||
UploadIcon,
|
||||
BoxIcon,
|
||||
RightArrowIcon,
|
||||
ChevronRightIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { Multiselect } from "vue-multiselect";
|
||||
import { useImageUpload } from "~/composables/image-upload.ts";
|
||||
import { formatBytes, formatCategory } from "@modrinth/utils";
|
||||
import { acceptFileFromProjectType } from "~/helpers/fileUtils.js";
|
||||
import { renderHighlightedString } from "~/helpers/highlight.js";
|
||||
import { inferVersionInfo } from "~/helpers/infer.js";
|
||||
import { createDataPackVersion } from "~/helpers/package.js";
|
||||
import { renderHighlightedString } from "~/helpers/highlight.js";
|
||||
import { reportVersion } from "~/utils/report-helpers.ts";
|
||||
import { useImageUpload } from "~/composables/image-upload.ts";
|
||||
|
||||
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
|
||||
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
|
||||
import Categories from "~/components/ui/search/Categories.vue";
|
||||
import FileInput from "~/components/ui/FileInput.vue";
|
||||
import Modal from "~/components/ui/Modal.vue";
|
||||
import Categories from "~/components/ui/search/Categories.vue";
|
||||
|
||||
export default defineNuxtComponent({
|
||||
components: {
|
||||
@@ -998,8 +997,8 @@ export default defineNuxtComponent({
|
||||
const project = await useBaseFetch(`project/${newDependencyId}`);
|
||||
|
||||
if (this.version.dependencies.some((dep) => project.id === dep.project_id)) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "Dependency already added",
|
||||
text: "You cannot add the same dependency twice.",
|
||||
type: "error",
|
||||
@@ -1023,8 +1022,8 @@ export default defineNuxtComponent({
|
||||
const project = await useBaseFetch(`project/${version.project_id}`);
|
||||
|
||||
if (this.version.dependencies.some((dep) => version.id === dep.version_id)) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "Dependency already added",
|
||||
text: "You cannot add the same dependency twice.",
|
||||
type: "error",
|
||||
@@ -1051,8 +1050,8 @@ export default defineNuxtComponent({
|
||||
this.newDependencyId = "";
|
||||
} catch {
|
||||
if (!hideErrors) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "Invalid Dependency",
|
||||
text: "The specified dependency could not be found",
|
||||
type: "error",
|
||||
@@ -1145,8 +1144,8 @@ export default defineNuxtComponent({
|
||||
)}`,
|
||||
);
|
||||
} catch (err) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -1170,8 +1169,8 @@ export default defineNuxtComponent({
|
||||
try {
|
||||
await this.createVersionRaw(this.version);
|
||||
} catch (err) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -1294,15 +1293,15 @@ export default defineNuxtComponent({
|
||||
|
||||
this.$refs.modal_package_mod.hide();
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "Packaging Success",
|
||||
text: "Your data pack was successfully packaged as a mod! Make sure to playtest to check for errors.",
|
||||
type: "success",
|
||||
});
|
||||
} catch (err) {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -251,31 +251,28 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {
|
||||
CheckIcon,
|
||||
CurrencyIcon,
|
||||
ExternalIcon,
|
||||
ModrinthPlusIcon,
|
||||
ServerIcon,
|
||||
UserIcon,
|
||||
XIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
CopyCode,
|
||||
DropdownSelect,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Toggle,
|
||||
useRelativeTime,
|
||||
} from "@modrinth/ui";
|
||||
import { formatCategory, formatPrice } from "@modrinth/utils";
|
||||
import {
|
||||
CheckIcon,
|
||||
XIcon,
|
||||
UserIcon,
|
||||
ModrinthPlusIcon,
|
||||
ServerIcon,
|
||||
ExternalIcon,
|
||||
CurrencyIcon,
|
||||
} from "@modrinth/assets";
|
||||
import dayjs from "dayjs";
|
||||
import ModrinthServersIcon from "~/components/ui/servers/ModrinthServersIcon.vue";
|
||||
import { products } from "~/generated/state.json";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
import ModrinthServersIcon from "~/components/ui/servers/ModrinthServersIcon.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const vintl = useVIntl();
|
||||
|
||||
@@ -258,31 +258,31 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { EditIcon, PlusIcon, SaveIcon, SettingsIcon, TrashIcon, XIcon } from "@modrinth/assets";
|
||||
import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
CopyCode,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
ServerNotice,
|
||||
TagItem,
|
||||
ButtonStyled,
|
||||
ServerNotice,
|
||||
commonMessages,
|
||||
NewModal,
|
||||
TeleportDropdownMenu,
|
||||
Toggle,
|
||||
useRelativeTime,
|
||||
} from "@modrinth/ui";
|
||||
import { NOTICE_LEVELS } from "@modrinth/ui/src/utils/notices.ts";
|
||||
import type { ServerNotice as ServerNoticeType } from "@modrinth/utils";
|
||||
import { useVIntl } from "@vintl/vintl";
|
||||
import { SettingsIcon, PlusIcon, SaveIcon, TrashIcon, EditIcon, XIcon } from "@modrinth/assets";
|
||||
import dayjs from "dayjs";
|
||||
import { useVIntl } from "@vintl/vintl";
|
||||
import type { ServerNotice as ServerNoticeType } from "@modrinth/utils";
|
||||
import { computed } from "vue";
|
||||
import AssignNoticeModal from "~/components/ui/servers/notice/AssignNoticeModal.vue";
|
||||
import { NOTICE_LEVELS } from "@modrinth/ui/src/utils/notices.ts";
|
||||
import { useServersFetch } from "~/composables/servers/servers-fetch.ts";
|
||||
import AssignNoticeModal from "~/components/ui/servers/notice/AssignNoticeModal.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const { formatMessage } = useVIntl();
|
||||
const formatRelativeTime = useRelativeTime();
|
||||
|
||||
const app = useNuxtApp() as unknown as { $notify: any };
|
||||
|
||||
const notices = ref<ServerNoticeType[]>([]);
|
||||
const createNoticeModal = ref<InstanceType<typeof NewModal>>();
|
||||
const assignNoticeModal = ref<InstanceType<typeof AssignNoticeModal>>();
|
||||
@@ -351,13 +351,15 @@ async function deleteNotice(notice: ServerNoticeType) {
|
||||
method: "DELETE",
|
||||
})
|
||||
.then(() => {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: `Successfully deleted notice #${notice.id}`,
|
||||
type: "success",
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error deleting notice",
|
||||
text: err,
|
||||
type: "error",
|
||||
@@ -384,6 +386,7 @@ const noticeSubmitError = computed(() => {
|
||||
function validateSubmission(message: string) {
|
||||
if (noticeSubmitError.value) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: message,
|
||||
text: noticeSubmitError.value,
|
||||
type: "error",
|
||||
@@ -413,7 +416,8 @@ async function saveChanges() {
|
||||
: undefined,
|
||||
},
|
||||
}).catch((err) => {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error saving changes to notice",
|
||||
text: err,
|
||||
type: "error",
|
||||
@@ -443,7 +447,8 @@ async function createNotice() {
|
||||
: undefined,
|
||||
},
|
||||
}).catch((err) => {
|
||||
addNotification({
|
||||
app.$notify({
|
||||
group: "main",
|
||||
title: "Error creating notice",
|
||||
text: err,
|
||||
type: "error",
|
||||
|
||||
@@ -32,10 +32,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ButtonStyled } from "@modrinth/ui";
|
||||
import { MailIcon } from "@modrinth/assets";
|
||||
import { ButtonStyled, injectNotificationManager } from "@modrinth/ui";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
const userEmail = ref("");
|
||||
|
||||
@@ -52,6 +50,7 @@ async function getUserFromEmail() {
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data.description,
|
||||
type: "error",
|
||||
|
||||
@@ -80,14 +80,13 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { CheckIcon, XIcon } from "@modrinth/assets";
|
||||
import { Avatar, Button, commonMessages, injectNotificationManager } from "@modrinth/ui";
|
||||
import { useAuth } from "@/composables/auth.js";
|
||||
import { Button, Avatar, commonMessages } from "@modrinth/ui";
|
||||
import { XIcon, CheckIcon } from "@modrinth/assets";
|
||||
import { useBaseFetch } from "@/composables/fetch.js";
|
||||
import { useAuth } from "@/composables/auth.js";
|
||||
|
||||
import { useScopes } from "@/composables/auth/scopes.ts";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const { formatMessage } = useVIntl();
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -118,6 +117,8 @@ const messages = defineMessages({
|
||||
},
|
||||
});
|
||||
|
||||
const data = useNuxtApp();
|
||||
|
||||
const router = useNativeRoute();
|
||||
const auth = await useAuth();
|
||||
const { scopesToDefinitions } = useScopes();
|
||||
@@ -195,7 +196,8 @@ const onAuthorize = async () => {
|
||||
|
||||
throw new Error(formatMessage(messages.noRedirectUrlError));
|
||||
} catch {
|
||||
addNotification({
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -221,7 +223,8 @@ const onReject = async () => {
|
||||
|
||||
throw new Error(formatMessage(messages.noRedirectUrlError));
|
||||
} catch {
|
||||
addNotification({
|
||||
data.$notify({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -67,11 +67,10 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { KeyIcon, MailIcon, SendIcon } from "@modrinth/assets";
|
||||
import { commonMessages, injectNotificationManager } from "@modrinth/ui";
|
||||
import { SendIcon, MailIcon, KeyIcon } from "@modrinth/assets";
|
||||
import { commonMessages } from "@modrinth/ui";
|
||||
import HCaptcha from "@/components/ui/HCaptcha.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const { formatMessage } = useVIntl();
|
||||
|
||||
const methodChoiceMessages = defineMessages({
|
||||
@@ -180,12 +179,14 @@ async function recovery() {
|
||||
});
|
||||
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(emailSentNotificationMessages.title),
|
||||
text: formatMessage(emailSentNotificationMessages.text),
|
||||
type: "success",
|
||||
});
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -210,6 +211,7 @@ async function changePassword() {
|
||||
});
|
||||
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(passwordResetNotificationMessages.title),
|
||||
text: formatMessage(passwordResetNotificationMessages.text),
|
||||
type: "success",
|
||||
@@ -217,6 +219,7 @@ async function changePassword() {
|
||||
await navigateTo("/auth/sign-in");
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -130,20 +130,19 @@
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
KeyIcon,
|
||||
MailIcon,
|
||||
RightArrowIcon,
|
||||
SSODiscordIcon,
|
||||
SSOGitHubIcon,
|
||||
SSOGitLabIcon,
|
||||
SSOGoogleIcon,
|
||||
SSOMicrosoftIcon,
|
||||
SSOSteamIcon,
|
||||
SSOGoogleIcon,
|
||||
SSODiscordIcon,
|
||||
SSOGitLabIcon,
|
||||
KeyIcon,
|
||||
MailIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { commonMessages, injectNotificationManager } from "@modrinth/ui";
|
||||
import { commonMessages } from "@modrinth/ui";
|
||||
import HCaptcha from "@/components/ui/HCaptcha.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const { formatMessage } = useVIntl();
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -233,6 +232,7 @@ async function beginPasswordSignIn() {
|
||||
}
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
@@ -257,6 +257,7 @@ async function begin2FASignIn() {
|
||||
await finishSignIn(res.session);
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -134,21 +134,20 @@
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
RightArrowIcon,
|
||||
UserIcon,
|
||||
SSOGitHubIcon,
|
||||
SSOMicrosoftIcon,
|
||||
SSOGoogleIcon,
|
||||
SSOSteamIcon,
|
||||
SSODiscordIcon,
|
||||
KeyIcon,
|
||||
MailIcon,
|
||||
RightArrowIcon,
|
||||
SSODiscordIcon,
|
||||
SSOGitHubIcon,
|
||||
SSOGitLabIcon,
|
||||
SSOGoogleIcon,
|
||||
SSOMicrosoftIcon,
|
||||
SSOSteamIcon,
|
||||
UserIcon,
|
||||
} from "@modrinth/assets";
|
||||
import { Checkbox, commonMessages, injectNotificationManager } from "@modrinth/ui";
|
||||
import { Checkbox, commonMessages } from "@modrinth/ui";
|
||||
import HCaptcha from "@/components/ui/HCaptcha.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const { formatMessage } = useVIntl();
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -226,6 +225,7 @@ async function createAccount() {
|
||||
try {
|
||||
if (confirmPassword.value !== password.value) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: formatMessage({
|
||||
id: "auth.sign-up.notification.password-mismatch.text",
|
||||
@@ -262,6 +262,7 @@ async function createAccount() {
|
||||
}
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -367,7 +367,6 @@ import {
|
||||
BoxIcon,
|
||||
CalendarIcon,
|
||||
EditIcon,
|
||||
GlobeIcon,
|
||||
GridIcon,
|
||||
ImageIcon,
|
||||
LibraryIcon,
|
||||
@@ -379,6 +378,7 @@ import {
|
||||
UpdatedIcon,
|
||||
UploadIcon,
|
||||
XIcon,
|
||||
GlobeIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
Avatar,
|
||||
@@ -387,17 +387,17 @@ import {
|
||||
ConfirmModal,
|
||||
DropdownSelect,
|
||||
FileInput,
|
||||
injectNotificationManager,
|
||||
PopoutMenu,
|
||||
useRelativeTime,
|
||||
} from "@modrinth/ui";
|
||||
|
||||
import { isAdmin } from "@modrinth/utils";
|
||||
import UpToDate from "assets/images/illustrations/up_to_date.svg";
|
||||
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
|
||||
import { addNotification } from "~/composables/notifs.js";
|
||||
import NavRow from "~/components/ui/NavRow.vue";
|
||||
import ProjectCard from "~/components/ui/ProjectCard.vue";
|
||||
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
|
||||
|
||||
const { addNotification } = injectNotificationManager();
|
||||
const vintl = useVIntl();
|
||||
const { formatMessage } = vintl;
|
||||
const formatRelativeTime = useRelativeTime();
|
||||
@@ -664,6 +664,7 @@ async function saveChanges() {
|
||||
isEditing.value = false;
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err,
|
||||
type: "error",
|
||||
@@ -687,6 +688,7 @@ async function deleteCollection() {
|
||||
}
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: formatMessage(commonMessages.errorNotificationTitle),
|
||||
text: err.data ? err.data.description : err,
|
||||
type: "error",
|
||||
|
||||
@@ -99,10 +99,7 @@
|
||||
import { ChevronRightIcon, HistoryIcon } from "@modrinth/assets";
|
||||
import { Avatar } from "@modrinth/ui";
|
||||
import NotificationItem from "~/components/ui/NotificationItem.vue";
|
||||
import {
|
||||
fetchExtraNotificationData,
|
||||
groupNotifications,
|
||||
} from "~/helpers/platform-notifications.ts";
|
||||
import { fetchExtraNotificationData, groupNotifications } from "~/helpers/notifications.ts";
|
||||
|
||||
useHead({
|
||||
title: "Dashboard - Modrinth",
|
||||
|
||||
@@ -56,16 +56,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckCheckIcon, HistoryIcon } from "@modrinth/assets";
|
||||
import { Button, Chips, Pagination } from "@modrinth/ui";
|
||||
import { Button, Pagination, Chips } from "@modrinth/ui";
|
||||
import { HistoryIcon, CheckCheckIcon } from "@modrinth/assets";
|
||||
import { formatProjectType } from "@modrinth/utils";
|
||||
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
|
||||
import NotificationItem from "~/components/ui/NotificationItem.vue";
|
||||
import {
|
||||
fetchExtraNotificationData,
|
||||
groupNotifications,
|
||||
markAsRead,
|
||||
} from "~/helpers/platform-notifications.ts";
|
||||
} from "~/helpers/notifications.ts";
|
||||
import NotificationItem from "~/components/ui/NotificationItem.vue";
|
||||
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
|
||||
|
||||
useHead({
|
||||
title: "Notifications - Modrinth",
|
||||
|
||||
@@ -301,16 +301,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Multiselect } from "vue-multiselect";
|
||||
import {
|
||||
EditIcon,
|
||||
IssuesIcon,
|
||||
PlusIcon,
|
||||
SaveIcon,
|
||||
SettingsIcon,
|
||||
TrashIcon,
|
||||
PlusIcon,
|
||||
XIcon,
|
||||
IssuesIcon,
|
||||
EditIcon,
|
||||
SaveIcon,
|
||||
SortAscIcon,
|
||||
SortDescIcon,
|
||||
TrashIcon,
|
||||
XIcon,
|
||||
} from "@modrinth/assets";
|
||||
import {
|
||||
Avatar,
|
||||
@@ -319,10 +320,8 @@ import {
|
||||
CopyCode,
|
||||
ProjectStatusBadge,
|
||||
commonMessages,
|
||||
injectNotificationManager,
|
||||
} from "@modrinth/ui";
|
||||
import { formatProjectType } from "@modrinth/utils";
|
||||
import { Multiselect } from "vue-multiselect";
|
||||
|
||||
import Modal from "~/components/ui/Modal.vue";
|
||||
import ModalCreation from "~/components/ui/ModalCreation.vue";
|
||||
@@ -445,8 +444,6 @@ export default defineNuxtComponent({
|
||||
return sortedArray;
|
||||
},
|
||||
async bulkEditLinks() {
|
||||
const { addNotification } = injectNotificationManager();
|
||||
|
||||
try {
|
||||
const baseData = {
|
||||
issues_url: this.editLinks.issues.clear ? null : this.editLinks.issues.val.trim(),
|
||||
@@ -480,7 +477,8 @@ export default defineNuxtComponent({
|
||||
);
|
||||
|
||||
this.$refs.editLinksModal.hide();
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "Success",
|
||||
text: "Bulk edited selected project's links.",
|
||||
type: "success",
|
||||
@@ -496,7 +494,8 @@ export default defineNuxtComponent({
|
||||
this.editLinks.wiki.clear = false;
|
||||
this.editLinks.discord.clear = false;
|
||||
} catch (e) {
|
||||
addNotification({
|
||||
this.$notify({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: e,
|
||||
type: "error",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user