Compare commits

...

24 Commits

Author SHA1 Message Date
IMB11
35b016c0bd Merge branch 'main' into cal/dev-136
Signed-off-by: IMB11 <hendersoncal117@gmail.com>
2025-08-08 11:57:27 +01:00
Alejandro González
d22c9e24f4 tweak(frontend): improve Nuxt build state generation logging and caching (#4133) 2025-08-06 22:05:33 +00:00
IMB11
167ddb1429 Merge branch 'main' into cal/dev-136 2025-08-06 14:00:40 +01:00
fishstiz
e31197f649 feat(app): pass selected version to incompatibility warning modal (#4115)
Co-authored-by: IMB11 <hendersoncal117@gmail.com>
2025-08-05 11:10:02 +00:00
Calum H.
7aa47f9473 fix: lint issues 2025-08-05 11:52:58 +01:00
Calum H. (IMB11)
3f91b55636 fix: prettier frontend 2025-08-05 11:51:07 +01:00
Calum H. (IMB11)
e7f940daa1 chore: fix util lint issues 2025-08-05 11:51:07 +01:00
Calum H. (IMB11)
75b00bec3d chore: fix ui lint issues 2025-08-05 11:51:07 +01:00
Calum H. (IMB11)
2376bea510 chore: fix blog lint issues 2025-08-05 11:51:07 +01:00
Calum H. (IMB11)
981cf159bf chore: fix moderation lint issues 2025-08-05 11:51:07 +01:00
Calum H. (IMB11)
52720ce06a chore: fix assets lint 2025-08-05 11:51:07 +01:00
Calum H. (IMB11)
34e65ace1e chore: fix frontend lint issues 2025-08-05 11:51:07 +01:00
Calum H. (IMB11)
f7fc208b15 chore: lint frontend 2025-08-05 11:49:34 +01:00
Calum H. (IMB11)
5b97f1e9b8 refactor: lint pass over app-frontend 2025-08-05 11:49:02 +01:00
Calum H. (IMB11)
73a353ab8c refactor: migrate to common eslint+prettier configs 2025-08-05 11:47:16 +01:00
Emma Alexia
0dee21814d Change "Billing" link on dashboard for admins (#3951)
* Change "Billing" link on dashboard for admins

Requires an archon change before merging

* change order

* steal changes from prospector's old PR

supersedes #3234

Co-authored-by: Prospector <prospectordev@gmail.com>

* lint?

---------

Co-authored-by: Prospector <prospectordev@gmail.com>
2025-08-04 20:13:33 +00:00
Josiah Glosson
0657e4466f Allow direct joining servers on old instances (#4094)
* Implement direct server joining for 1.6.2 through 1.19.4

* Implement direct server joining for versions before 1.6.2

* Ignore methods with a $ in them

* Run intl:extract

* Improve code of MinecraftTransformer

* Support showing last played time for profiles before 1.7

* Reorganize QuickPlayVersion a bit to prepare for singleplayer

* Only inject quick play checking in versions where it's needed

* Optimize agent some and fix error on NeoForge

* Remove some code for quickplay singleplayer support before 1.20, as we can't reasonably support that with an agent

* Invert the default hasServerQuickPlaySupport return value

* Remove Play Anyway button

* Fix "Server couldn't be contacted" on singleplayer worlds

* Fix "Jump back in" section not working
2025-08-04 19:29:20 +00:00
Josiah Glosson
13dbb4c57e Fix most packs showing as "Optimization" on the app homepage (#4119) 2025-08-04 19:21:37 +00:00
Prospector
99493b9917 Updated changelog 2025-08-01 21:31:22 -04:00
IMB11
72a52eb7b1 fix: improve error message for rate limiting (#4101)
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
2025-08-01 21:27:25 +00:00
IMB11
b33e12c71d fix: startup settings not visible on hard page refresh/direct load (#4100)
* fix: startup settings not visible on hard page refresh/direct load

* refactor: const func => named
2025-08-01 21:22:22 +00:00
IMB11
82d86839c7 fix: approve status incorrect (#4104) 2025-08-01 20:24:40 +00:00
coolbot
3a20e15340 Coolbot/moderation updates aug1 (#4103)
* oop, all commas!

* Only show slug stuff when needed.

* Move status alerts to top of message, getting rid of separators.

* redist libs message altered, and now shows on plugins too

* Update versions.ts

remove unnecessary import

Signed-off-by: coolbot <76798835+coolbot100s@users.noreply.github.com>

* Tweak summary formatting msg

* Update license messages to use flink

* reorder link text to match the settings page

* add Description clarity button

---------

Signed-off-by: coolbot <76798835+coolbot100s@users.noreply.github.com>
2025-08-01 20:21:28 +00:00
jade
1c89b84314 fix(moderation): Replace dead modpack link with a valid one in side-types message (#4095) 2025-07-31 17:50:33 +00:00
576 changed files with 18223 additions and 18488 deletions

3
.idea/code.iml generated
View File

@@ -10,11 +10,10 @@
<sourceFolder url="file://$MODULE_DIR$/apps/labrinth/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/apps/labrinth/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/apps/labrinth/tests" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/apps/labrinth/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/packages/app-lib/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/packages/app-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/packages/rust-common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/packages/ariadne/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/packages/ariadne/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View File

@@ -1,22 +1,2 @@
import { createConfigForNuxt } from '@nuxt/eslint-config/flat' import config from '@modrinth/tooling-config/eslint/nuxt.mjs'
import { fixupPluginRules } from '@eslint/compat' export default config
import turboPlugin from 'eslint-plugin-turbo'
export default createConfigForNuxt().append([
{
name: 'turbo',
plugins: {
turbo: fixupPluginRules(turboPlugin),
},
rules: {
'turbo/no-undeclared-env-vars': 'error',
},
},
{
name: 'modrinth',
rules: {
'vue/html-self-closing': 'off',
'vue/multi-word-component-names': 'off',
},
},
])

View File

@@ -9,7 +9,7 @@
"tsc:check": "vue-tsc --noEmit", "tsc:check": "vue-tsc --noEmit",
"lint": "eslint . && prettier --check .", "lint": "eslint . && prettier --check .",
"fix": "eslint . --fix && prettier --write .", "fix": "eslint . --fix && prettier --write .",
"intl:extract": "formatjs extract \"{,src/components,src/composables,src/helpers,src/pages,src/store}/**/*.{vue,ts,tsx,js,jsx,mts,cts,mjs,cjs}\" --ignore '**/*.d.ts' --ignore 'node_modules' --out-file src/locales/en-US/index.json --format crowdin --preserve-whitespace", "intl:extract": "formatjs extract \"src/**/*.{vue,ts,tsx,js,jsx,mts,cts,mjs,cjs}\" --ignore \"**/*.d.ts\" --ignore node_modules --out-file src/locales/en-US/index.json --format crowdin --preserve-whitespace",
"test": "vue-tsc --noEmit" "test": "vue-tsc --noEmit"
}, },
"dependencies": { "dependencies": {
@@ -41,6 +41,7 @@
"vue-virtual-scroller": "v2.0.0-beta.8" "vue-virtual-scroller": "v2.0.0-beta.8"
}, },
"devDependencies": { "devDependencies": {
"@modrinth/tooling-config": "workspace:*",
"@eslint/compat": "^1.1.1", "@eslint/compat": "^1.1.1",
"@formatjs/cli": "^6.2.12", "@formatjs/cli": "^6.2.12",
"@nuxt/eslint-config": "^0.5.6", "@nuxt/eslint-config": "^0.5.6",
@@ -48,13 +49,11 @@
"@vitejs/plugin-vue": "^5.0.4", "@vitejs/plugin-vue": "^5.0.4",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"eslint": "^9.9.1", "eslint": "^9.9.1",
"eslint-config-custom": "workspace:*",
"eslint-plugin-turbo": "^2.5.4", "eslint-plugin-turbo": "^2.5.4",
"postcss": "^8.4.39", "postcss": "^8.4.39",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"sass": "^1.74.1", "sass": "^1.74.1",
"tailwindcss": "^3.4.4", "tailwindcss": "^3.4.4",
"tsconfig": "workspace:*",
"typescript": "^5.5.4", "typescript": "^5.5.4",
"vite": "^5.4.6", "vite": "^5.4.6",
"vue-tsc": "^2.1.6" "vue-tsc": "^2.1.6"

View File

@@ -1,6 +1,4 @@
<script setup> <script setup>
import { computed, onMounted, onUnmounted, ref, watch, provide } from 'vue'
import { RouterView, useRoute, useRouter } from 'vue-router'
import { import {
ArrowBigUpDashIcon, ArrowBigUpDashIcon,
ChangeSkinIcon, ChangeSkinIcon,
@@ -13,65 +11,69 @@ import {
LogOutIcon, LogOutIcon,
MaximizeIcon, MaximizeIcon,
MinimizeIcon, MinimizeIcon,
NewspaperIcon,
PlusIcon, PlusIcon,
RestoreIcon, RestoreIcon,
RightArrowIcon, RightArrowIcon,
SettingsIcon, SettingsIcon,
WorldIcon, WorldIcon,
XIcon, XIcon,
NewspaperIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { import {
Avatar, Avatar,
Button, Button,
ButtonStyled, ButtonStyled,
NewsArticleCard,
Notifications, Notifications,
OverflowMenu, OverflowMenu,
NewsArticleCard,
} from '@modrinth/ui' } from '@modrinth/ui'
import { useLoading, useTheming } from '@/store/state' import { renderString } from '@modrinth/utils'
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 { 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 { getVersion } from '@tauri-apps/api/app'
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue' import { invoke } from '@tauri-apps/api/core'
import { create_profile_and_install_from_file } from './helpers/pack' import { getCurrentWindow } from '@tauri-apps/api/window'
import { useError } from '@/store/error.js' import { openUrl } from '@tauri-apps/plugin-opener'
import { useCheckDisableMouseover } from '@/composables/macCssFix.js' import { type } from '@tauri-apps/plugin-os'
import ModInstallModal from '@/components/ui/install_flow/ModInstallModal.vue' 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 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 IncompatibilityWarningModal from '@/components/ui/install_flow/IncompatibilityWarningModal.vue'
import InstallConfirmModal from '@/components/ui/install_flow/InstallConfirmModal.vue' import InstallConfirmModal from '@/components/ui/install_flow/InstallConfirmModal.vue'
import { useInstall } from '@/store/install.js' import ModInstallModal from '@/components/ui/install_flow/ModInstallModal.vue'
import { invoke } from '@tauri-apps/api/core' import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
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 AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue'
import AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue' import AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue'
import NavButton from '@/components/ui/NavButton.vue'
import PromotionWrapper from '@/components/ui/PromotionWrapper.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 QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
import { get_available_capes, get_available_skins } from './helpers/skins' 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 { handleError, useNotifications } from '@/store/notifications.js'
import { useLoading, useTheming } from '@/store/state'
import { create_profile_and_install_from_file } from './helpers/pack'
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer' import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
import { get_available_capes, get_available_skins } from './helpers/skins'
const themeStore = useTheming() const themeStore = useTheming()

View File

@@ -1,18 +1,18 @@
export { default as ATLauncherIcon } from './atlauncher.svg'
export { default as BuyMeACoffeeIcon } from './bmac.svg' export { default as BuyMeACoffeeIcon } from './bmac.svg'
export { default as DiscordIcon } from './discord.svg' export { default as DiscordIcon } from './discord.svg'
export { default as GDLauncherIcon } from './gdlauncher.png'
export { default as GithubIcon } from './github.svg'
export { default as GitLabIcon } from './gitlab.svg'
export { default as GoogleIcon } from './google.svg'
export { default as KoFiIcon } from './kofi.svg' export { default as KoFiIcon } from './kofi.svg'
export { default as MastodonIcon } from './mastodon.svg'
export { default as MicrosoftIcon } from './microsoft.svg'
export { default as MultiMCIcon } from './multimc.webp'
export { default as OpenCollectiveIcon } from './opencollective.svg'
export { default as PatreonIcon } from './patreon.svg' export { default as PatreonIcon } from './patreon.svg'
export { default as PaypalIcon } from './paypal.svg' export { default as PaypalIcon } from './paypal.svg'
export { default as OpenCollectiveIcon } from './opencollective.svg'
export { default as TwitterIcon } from './twitter.svg'
export { default as GithubIcon } from './github.svg'
export { default as MastodonIcon } from './mastodon.svg'
export { default as RedditIcon } from './reddit.svg'
export { default as GoogleIcon } from './google.svg'
export { default as MicrosoftIcon } from './microsoft.svg'
export { default as SteamIcon } from './steam.svg'
export { default as GitLabIcon } from './gitlab.svg'
export { default as ATLauncherIcon } from './atlauncher.svg'
export { default as GDLauncherIcon } from './gdlauncher.png'
export { default as MultiMCIcon } from './multimc.webp'
export { default as PrismIcon } from './prism.svg' export { default as PrismIcon } from './prism.svg'
export { default as RedditIcon } from './reddit.svg'
export { default as SteamIcon } from './steam.svg'
export { default as TwitterIcon } from './twitter.svg'

View File

@@ -1,9 +1,9 @@
export { default as SwapIcon } from './arrow-left-right.svg'
export { default as ToggleIcon } from './toggle.svg'
export { default as PackageIcon } from './package.svg'
export { default as VersionIcon } from './milestone.svg'
export { default as TextInputIcon } from './text-cursor-input.svg'
export { default as AddProjectImage } from './add-project.svg' export { default as AddProjectImage } from './add-project.svg'
export { default as NewInstanceImage } from './new-instance.svg' export { default as SwapIcon } from './arrow-left-right.svg'
export { default as MenuIcon } from './menu.svg' export { default as MenuIcon } from './menu.svg'
export { default as ChatIcon } from './messages-square.svg' export { default as ChatIcon } from './messages-square.svg'
export { default as VersionIcon } from './milestone.svg'
export { default as NewInstanceImage } from './new-instance.svg'
export { default as PackageIcon } from './package.svg'
export { default as TextInputIcon } from './text-cursor-input.svg'
export { default as ToggleIcon } from './toggle.svg'

View File

@@ -1,24 +1,25 @@
<script setup> <script setup>
import Instance from '@/components/ui/Instance.vue'
import { computed, ref } from 'vue'
import { import {
ClipboardCopyIcon, ClipboardCopyIcon,
EyeIcon,
FolderOpenIcon, FolderOpenIcon,
PlayIcon, PlayIcon,
PlusIcon, PlusIcon,
TrashIcon,
StopCircleIcon,
EyeIcon,
SearchIcon, SearchIcon,
StopCircleIcon,
TrashIcon,
XIcon, XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Button, DropdownSelect } from '@modrinth/ui' import { Button, DropdownSelect } from '@modrinth/ui'
import { formatCategoryHeader } from '@modrinth/utils' import { formatCategoryHeader } from '@modrinth/utils'
import ContextMenu from '@/components/ui/ContextMenu.vue'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { computed, ref } from 'vue'
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 { duplicate, remove } from '@/helpers/profile.js'
import { handleError } from '@/store/notifications.js' import { handleError } from '@/store/notifications.js'
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
const props = defineProps({ const props = defineProps({
instances: { instances: {

View File

@@ -1,5 +1,6 @@
<script setup> <script setup>
import { computed, onBeforeUnmount, ref, watch } from 'vue' import { computed, onBeforeUnmount, ref, watch } from 'vue'
import { useLoading } from '@/store/state.js' import { useLoading } from '@/store/state.js'
const props = defineProps({ const props = defineProps({

View File

@@ -1,31 +1,32 @@
<script setup> <script setup>
import { import {
ClipboardCopyIcon, ClipboardCopyIcon,
FolderOpenIcon,
PlayIcon,
PlusIcon,
TrashIcon,
DownloadIcon, DownloadIcon,
GlobeIcon,
StopCircleIcon,
ExternalIcon, ExternalIcon,
EyeIcon, EyeIcon,
FolderOpenIcon,
GlobeIcon,
PlayIcon,
PlusIcon,
StopCircleIcon,
TrashIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue' import { HeadingLink } from '@modrinth/ui'
import Instance from '@/components/ui/Instance.vue' import { openUrl } from '@tauri-apps/plugin-opener'
import { computed, onMounted, onUnmounted, ref } from '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' import { useRouter } from 'vue-router'
import { showProfileInFolder } from '@/helpers/utils.js'
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 { 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 { handleSevereError } from '@/store/error.js'
import { install as installVersion } from '@/store/install.js' import { install as installVersion } from '@/store/install.js'
import { openUrl } from '@tauri-apps/plugin-opener' import { handleError } from '@/store/notifications.js'
import { HeadingLink } from '@modrinth/ui'
const router = useRouter() const router = useRouter()

View File

@@ -73,22 +73,23 @@
</template> </template>
<script setup> <script setup>
import { DropdownIcon, PlusIcon, TrashIcon, LogInIcon, SpinnerIcon } from '@modrinth/assets' import { DropdownIcon, LogInIcon, PlusIcon, SpinnerIcon, TrashIcon } from '@modrinth/assets'
import { Avatar, Button, Card } from '@modrinth/ui' import { Avatar, Button, Card } from '@modrinth/ui'
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue' import { computed, onBeforeUnmount, onMounted, onUnmounted, ref } from 'vue'
import { trackEvent } from '@/helpers/analytics'
import { import {
users, get_default_user,
login as login_flow,
remove_user, remove_user,
set_default_user, set_default_user,
login as login_flow, users,
get_default_user,
} from '@/helpers/auth' } from '@/helpers/auth'
import { handleError } from '@/store/state.js'
import { trackEvent } from '@/helpers/analytics'
import { process_listener } from '@/helpers/events' import { process_listener } from '@/helpers/events'
import { handleSevereError } from '@/store/error.js'
import { get_available_skins } from '@/helpers/skins'
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts' import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
import { get_available_skins } from '@/helpers/skins'
import { handleSevereError } from '@/store/error.js'
import { handleError } from '@/store/state.js'
defineProps({ defineProps({
mode: { mode: {

View File

@@ -1,10 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { DropdownIcon, PlusIcon, FolderOpenIcon } from '@modrinth/assets' import { DropdownIcon, FolderOpenIcon, PlusIcon } from '@modrinth/assets'
import { ButtonStyled, OverflowMenu } from '@modrinth/ui' import { ButtonStyled, OverflowMenu } from '@modrinth/ui'
import { open } from '@tauri-apps/plugin-dialog' import { open } from '@tauri-apps/plugin-dialog'
import { useRouter } from 'vue-router'
import { add_project_from_path } from '@/helpers/profile.js' import { add_project_from_path } from '@/helpers/profile.js'
import { handleError } from '@/store/notifications.js' import { handleError } from '@/store/notifications.js'
import { useRouter } from 'vue-router'
const props = defineProps({ const props = defineProps({
instance: { instance: {

View File

@@ -42,11 +42,12 @@
</template> </template>
<script setup> <script setup>
import { ChevronRightIcon, ChevronLeftIcon } from '@modrinth/assets' import { ChevronLeftIcon, ChevronRightIcon } from '@modrinth/assets'
import { Button } from '@modrinth/ui' import { Button } from '@modrinth/ui'
import { useBreadcrumbs } from '@/store/breadcrumbs'
import { useRoute } from 'vue-router'
import { computed } from 'vue' import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useBreadcrumbs } from '@/store/breadcrumbs'
const route = useRoute() const route = useRoute()

View File

@@ -1,23 +1,24 @@
<script setup> <script setup>
import { import {
CheckIcon, CheckIcon,
CopyIcon,
DropdownIcon, DropdownIcon,
XIcon,
HammerIcon, HammerIcon,
LogInIcon, LogInIcon,
UpdatedIcon, UpdatedIcon,
CopyIcon, XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { ChatIcon } from '@/assets/icons'
import { ButtonStyled, Collapsible } from '@modrinth/ui' import { ButtonStyled, Collapsible } from '@modrinth/ui'
import { ref, computed } from 'vue' import { computed, ref } from 'vue'
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
import { handleError } from '@/store/notifications.js' import { ChatIcon } from '@/assets/icons'
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' 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 { handleError } from '@/store/notifications.js'
const errorModal = ref() const errorModal = ref()
const error = ref() const error = ref()

View File

@@ -1,12 +1,13 @@
<script setup> <script setup>
import { XIcon, PlusIcon } from '@modrinth/assets' import { PlusIcon, XIcon } from '@modrinth/assets'
import { Button, Checkbox } from '@modrinth/ui' import { Button, Checkbox } from '@modrinth/ui'
import { PackageIcon, VersionIcon } from '@/assets/icons'
import { ref } from 'vue'
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
import { open } from '@tauri-apps/plugin-dialog' import { open } from '@tauri-apps/plugin-dialog'
import { handleError } from '@/store/notifications.js' import { ref } from 'vue'
import { PackageIcon, VersionIcon } from '@/assets/icons'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
import { handleError } from '@/store/notifications.js'
const props = defineProps({ const props = defineProps({
instance: { instance: {

View File

@@ -1,6 +1,4 @@
<script setup> <script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { import {
DownloadIcon, DownloadIcon,
GameIcon, GameIcon,
@@ -11,14 +9,17 @@ import {
} from '@modrinth/assets' } from '@modrinth/assets'
import { Avatar, ButtonStyled, useRelativeTime } from '@modrinth/ui' import { Avatar, ButtonStyled, useRelativeTime } from '@modrinth/ui'
import { convertFileSrc } from '@tauri-apps/api/core' import { convertFileSrc } from '@tauri-apps/api/core'
import { finish_install, kill, run } from '@/helpers/profile' import dayjs from 'dayjs'
import { get_by_profile_path } from '@/helpers/process' import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { trackEvent } from '@/helpers/analytics'
import { process_listener } from '@/helpers/events' import { process_listener } from '@/helpers/events'
import { handleError } from '@/store/state.js' import { get_by_profile_path } from '@/helpers/process'
import { finish_install, kill, run } from '@/helpers/profile'
import { showProfileInFolder } from '@/helpers/utils.js' import { showProfileInFolder } from '@/helpers/utils.js'
import { handleSevereError } from '@/store/error.js' import { handleSevereError } from '@/store/error.js'
import { trackEvent } from '@/helpers/analytics' import { handleError } from '@/store/state.js'
import dayjs from 'dayjs'
const formatRelativeTime = useRelativeTime() const formatRelativeTime = useRelativeTime()

View File

@@ -197,7 +197,6 @@
</template> </template>
<script setup> <script setup>
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { import {
CodeIcon, CodeIcon,
FolderOpenIcon, FolderOpenIcon,
@@ -209,23 +208,25 @@ import {
XIcon, XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Avatar, Button, Checkbox, Chips } from '@modrinth/ui' 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 { convertFileSrc } from '@tauri-apps/api/core'
import { get_game_versions, get_loader_versions } from '@/helpers/metadata' import { getCurrentWebview } from '@tauri-apps/api/webview'
import { handleError } from '@/store/notifications.js' import { open } from '@tauri-apps/plugin-dialog'
import { computed, onUnmounted, ref, shallowRef } from 'vue'
import Multiselect from 'vue-multiselect' import Multiselect from 'vue-multiselect'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import ProgressBar from '@/components/ui/ProgressBar.vue'
import { trackEvent } from '@/helpers/analytics' import { trackEvent } from '@/helpers/analytics'
import { create_profile_and_install_from_file } from '@/helpers/pack.js'
import { import {
get_default_launcher_path, get_default_launcher_path,
get_importable_instances, get_importable_instances,
import_instance, import_instance,
} from '@/helpers/import.js' } from '@/helpers/import.js'
import ProgressBar from '@/components/ui/ProgressBar.vue' import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
import { getCurrentWebview } from '@tauri-apps/api/webview' import { create_profile_and_install_from_file } from '@/helpers/pack.js'
import { create } from '@/helpers/profile'
import { get_loaders } from '@/helpers/tags'
import { handleError } from '@/store/notifications.js'
const profile_name = ref('') const profile_name = ref('')
const game_version = ref('') const game_version = ref('')

View File

@@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { convertFileSrc } from '@tauri-apps/api/core'
import { formatCategory } from '@modrinth/utils'
import { GameIcon, LeftArrowIcon } from '@modrinth/assets' import { GameIcon, LeftArrowIcon } from '@modrinth/assets'
import { Avatar, ButtonStyled } from '@modrinth/ui' import { Avatar, ButtonStyled } from '@modrinth/ui'
import { formatCategory } from '@modrinth/utils'
import { convertFileSrc } from '@tauri-apps/api/core'
type Instance = { type Instance = {
game_version: string game_version: string

View File

@@ -35,13 +35,14 @@
</ModalWrapper> </ModalWrapper>
</template> </template>
<script setup> <script setup>
import { PlusIcon, CheckIcon, XIcon } from '@modrinth/assets' import { CheckIcon, PlusIcon, XIcon } from '@modrinth/assets'
import { Button } from '@modrinth/ui' import { Button } from '@modrinth/ui'
import { ref } from 'vue' import { ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { trackEvent } from '@/helpers/analytics'
import { find_filtered_jres } from '@/helpers/jre.js' import { find_filtered_jres } from '@/helpers/jre.js'
import { handleError } from '@/store/notifications.js' import { handleError } from '@/store/notifications.js'
import { trackEvent } from '@/helpers/analytics'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
const chosenInstallOptions = ref([]) const chosenInstallOptions = ref([])
const detectJavaModal = ref(null) const detectJavaModal = ref(null)

View File

@@ -53,20 +53,21 @@
<script setup> <script setup>
import { import {
SearchIcon,
PlayIcon,
CheckIcon, CheckIcon,
XIcon,
FolderSearchIcon,
DownloadIcon, DownloadIcon,
FolderSearchIcon,
PlayIcon,
SearchIcon,
XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Button } from '@modrinth/ui' import { Button } from '@modrinth/ui'
import { auto_install_java, find_filtered_jres, get_jre, test_jre } from '@/helpers/jre.js'
import { ref } from 'vue'
import { open } from '@tauri-apps/plugin-dialog' import { open } from '@tauri-apps/plugin-dialog'
import { ref } from 'vue'
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue' import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
import { handleError } from '@/store/state.js'
import { trackEvent } from '@/helpers/analytics' import { trackEvent } from '@/helpers/analytics'
import { auto_install_java, find_filtered_jres, get_jre, test_jre } from '@/helpers/jre.js'
import { handleError } from '@/store/state.js'
const props = defineProps({ const props = defineProps({
version: { version: {

View File

@@ -1,11 +1,12 @@
<script setup> <script setup>
import { CheckIcon } from '@modrinth/assets' import { CheckIcon } from '@modrinth/assets'
import { Button, Badge } from '@modrinth/ui' import { Badge, Button } from '@modrinth/ui'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { update_managed_modrinth_version } from '@/helpers/profile'
import { releaseColor } from '@/helpers/utils'
import { SwapIcon } from '@/assets/icons/index.js' import { SwapIcon } from '@/assets/icons/index.js'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { update_managed_modrinth_version } from '@/helpers/profile'
import { releaseColor } from '@/helpers/utils'
const props = defineProps({ const props = defineProps({
versions: { versions: {

View File

@@ -30,7 +30,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from 'vue' import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import type { RouteLocationRaw } from 'vue-router' import type { RouteLocationRaw } from 'vue-router'
import { useRoute, RouterLink } from 'vue-router' import { RouterLink, useRoute } from 'vue-router'
const route = useRoute() const route = useRoute()

View File

@@ -1,10 +1,10 @@
<script setup> <script setup>
import { Avatar, TagItem } from '@modrinth/ui'
import { DownloadIcon, HeartIcon, TagIcon } from '@modrinth/assets' import { DownloadIcon, HeartIcon, TagIcon } from '@modrinth/assets'
import { formatNumber, formatCategory } from '@modrinth/utils' import { Avatar, TagItem } from '@modrinth/ui'
import { computed } from 'vue' import { formatCategory, formatNumber } from '@modrinth/utils'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
import { computed } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
dayjs.extend(relativeTime) dayjs.extend(relativeTime)
@@ -21,14 +21,11 @@ const props = defineProps({
}) })
const featuredCategory = computed(() => { const featuredCategory = computed(() => {
if (props.project.categories.includes('optimization')) { if (props.project.display_categories.includes('optimization')) {
return 'optimization' return 'optimization'
} }
if (props.project.categories.length > 0) { return props.project.display_categories[0] ?? props.project.categories[0]
return props.project.categories[0]
}
return undefined
}) })
const toColor = computed(() => { const toColor = computed(() => {

View File

@@ -1,5 +1,6 @@
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { onMounted, ref } from 'vue'
import { init_ads_window } from '@/helpers/ads.js' import { init_ads_window } from '@/helpers/ads.js'
const adsWrapper = ref(null) const adsWrapper = ref(null)

View File

@@ -1,13 +1,14 @@
<script setup> <script setup>
import { list } from '@/helpers/profile' import { SpinnerIcon } from '@modrinth/assets'
import { handleError } from '@/store/notifications'
import dayjs from 'dayjs'
import { onUnmounted, ref } from 'vue'
import { profile_listener } from '@/helpers/events.js'
import NavButton from '@/components/ui/NavButton.vue'
import { Avatar } from '@modrinth/ui' import { Avatar } from '@modrinth/ui'
import { convertFileSrc } from '@tauri-apps/api/core' import { convertFileSrc } from '@tauri-apps/api/core'
import { SpinnerIcon } from '@modrinth/assets' import dayjs from 'dayjs'
import { onUnmounted, ref } from 'vue'
import NavButton from '@/components/ui/NavButton.vue'
import { profile_listener } from '@/helpers/events.js'
import { list } from '@/helpers/profile'
import { handleError } from '@/store/notifications'
const recentInstances = ref([]) const recentInstances = ref([])
const getInstances = async () => { const getInstances = async () => {

View File

@@ -96,21 +96,22 @@
<script setup> <script setup>
import { import {
DownloadIcon, DownloadIcon,
DropdownIcon,
StopCircleIcon, StopCircleIcon,
TerminalSquareIcon, TerminalSquareIcon,
DropdownIcon,
UnplugIcon, UnplugIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Button, ButtonStyled, Card } from '@modrinth/ui' import { Button, ButtonStyled, Card } from '@modrinth/ui'
import { onBeforeUnmount, onMounted, ref } from 'vue' 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' import { useRouter } from 'vue-router'
import { progress_bars_list } from '@/helpers/state.js'
import ProgressBar from '@/components/ui/ProgressBar.vue' 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' 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 { handleError } from '@/store/notifications.js'
const router = useRouter() const router = useRouter()
const card = ref(null) const card = ref(null)

View File

@@ -117,14 +117,15 @@
</template> </template>
<script setup> <script setup>
import { TagsIcon, DownloadIcon, HeartIcon, PlusIcon, CheckIcon } from '@modrinth/assets' import { CheckIcon, DownloadIcon, HeartIcon, PlusIcon, TagsIcon } from '@modrinth/assets'
import { ButtonStyled, Avatar } from '@modrinth/ui' import { Avatar, ButtonStyled } from '@modrinth/ui'
import { formatNumber, formatCategory } from '@modrinth/utils' import { formatCategory, formatNumber } from '@modrinth/utils'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
import { ref, computed } from 'vue' import { computed, ref } from 'vue'
import { install as installVersion } from '@/store/install.js'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { install as installVersion } from '@/store/install.js'
dayjs.extend(relativeTime) dayjs.extend(relativeTime)
const router = useRouter() const router = useRouter()

View File

@@ -82,11 +82,12 @@
</template> </template>
<script setup> <script setup>
import { MaximizeIcon, MinimizeIcon, XIcon } from '@modrinth/assets'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import ProgressBar from '@/components/ui/ProgressBar.vue' import ProgressBar from '@/components/ui/ProgressBar.vue'
import { loading_listener } from '@/helpers/events.js' import { loading_listener } from '@/helpers/events.js'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { XIcon, MaximizeIcon, MinimizeIcon } from '@modrinth/assets'
import { getOS } from '@/helpers/utils.js' import { getOS } from '@/helpers/utils.js'
import { useLoading } from '@/store/loading.js' import { useLoading } from '@/store/loading.js'

View File

@@ -1,12 +1,13 @@
<script setup> <script setup>
import { Button } from '@modrinth/ui' import { Button } from '@modrinth/ui'
import { ref } from 'vue' import { ref } from 'vue'
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' 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 { handleError } from '@/store/notifications.js'
const confirmModal = ref(null) const confirmModal = ref(null)
const project = ref(null) const project = ref(null)

View File

@@ -1,22 +1,23 @@
<script setup lang="ts"> <script setup lang="ts">
import { Avatar, ButtonStyled, OverflowMenu, useRelativeTime } from '@modrinth/ui'
import { import {
UserPlusIcon,
MoreVerticalIcon,
MailIcon, MailIcon,
MoreVerticalIcon,
SettingsIcon, SettingsIcon,
TrashIcon, TrashIcon,
UserPlusIcon,
XIcon, XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { ref, onUnmounted, watch, computed } from 'vue' import { Avatar, ButtonStyled, OverflowMenu, useRelativeTime } from '@modrinth/ui'
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 type { Dayjs } from 'dayjs'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { computed, onUnmounted, ref, watch } from 'vue'
import ContextMenu from '@/components/ui/ContextMenu.vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.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 { handleError } from '@/store/notifications.js'
const formatRelativeTime = useRelativeTime() const formatRelativeTime = useRelativeTime()

View File

@@ -56,16 +56,17 @@
</template> </template>
<script setup> <script setup>
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' import { DownloadIcon, XIcon } from '@modrinth/assets'
import { XIcon, DownloadIcon } from '@modrinth/assets'
import { Button } from '@modrinth/ui' import { Button } from '@modrinth/ui'
import { formatCategory } from '@modrinth/utils' import { formatCategory } from '@modrinth/utils'
import { add_project_from_version as installMod } from '@/helpers/profile'
import { ref } from 'vue' import { ref } from 'vue'
import { handleError } from '@/store/state.js'
import { trackEvent } from '@/helpers/analytics'
import Multiselect from 'vue-multiselect' import Multiselect from 'vue-multiselect'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { trackEvent } from '@/helpers/analytics'
import { add_project_from_version as installMod } from '@/helpers/profile'
import { handleError } from '@/store/state.js'
const instance = ref(null) const instance = ref(null)
const project = ref(null) const project = ref(null)
const versions = ref(null) const versions = ref(null)
@@ -76,10 +77,10 @@ const installing = ref(false)
const onInstall = ref(() => {}) const onInstall = ref(() => {})
defineExpose({ defineExpose({
show: (instanceVal, projectVal, projectVersions, callback) => { show: (instanceVal, projectVal, projectVersions, selected, callback) => {
instance.value = instanceVal instance.value = instanceVal
versions.value = projectVersions versions.value = projectVersions
selectedVersion.value = projectVersions[0] selectedVersion.value = selected ?? projectVersions[0]
project.value = projectVal project.value = projectVal

View File

@@ -1,11 +1,12 @@
<script setup> <script setup>
import { DownloadIcon, XIcon } from '@modrinth/assets' import { DownloadIcon, XIcon } from '@modrinth/assets'
import { Button } from '@modrinth/ui' import { Button } from '@modrinth/ui'
import { create_profile_and_install as pack_install } from '@/helpers/pack'
import { ref } from 'vue' import { ref } from 'vue'
import { trackEvent } from '@/helpers/analytics'
import { handleError } from '@/store/state.js'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' 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 { handleError } from '@/store/state.js'
const versionId = ref() const versionId = ref()
const project = ref() const project = ref()

View File

@@ -1,28 +1,29 @@
<script setup> <script setup>
import { import {
CheckIcon,
DownloadIcon, DownloadIcon,
PlusIcon, PlusIcon,
RightArrowIcon,
UploadIcon, UploadIcon,
XIcon, XIcon,
RightArrowIcon,
CheckIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Avatar, Button, Card } from '@modrinth/ui' import { Avatar, Button, Card } from '@modrinth/ui'
import { convertFileSrc } from '@tauri-apps/api/core'
import { open } from '@tauri-apps/plugin-dialog'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { trackEvent } from '@/helpers/analytics'
import { import {
add_project_from_version as installMod, add_project_from_version as installMod,
check_installed, check_installed,
create,
get, get,
list, list,
create,
} from '@/helpers/profile' } from '@/helpers/profile'
import { open } from '@tauri-apps/plugin-dialog'
import { installVersionDependencies } from '@/store/install.js' import { installVersionDependencies } from '@/store/install.js'
import { handleError } from '@/store/notifications.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 router = useRouter() const router = useRouter()

View File

@@ -1,16 +1,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { CopyIcon, EditIcon, PlusIcon, SpinnerIcon, TrashIcon, UploadIcon } from '@modrinth/assets'
import { Avatar, ButtonStyled, Checkbox, OverflowMenu } from '@modrinth/ui'
import { convertFileSrc } from '@tauri-apps/api/core' 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 { open } from '@tauri-apps/plugin-dialog'
import { defineMessages, useVIntl } from '@vintl/vintl' import { defineMessages, useVIntl } from '@vintl/vintl'
import { computed, type Ref, ref, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue' import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
import type { InstanceSettingsTabProps, GameInstance } from '../../../helpers/types' import { trackEvent } from '@/helpers/analytics'
import { duplicate, edit, edit_icon, list, remove } from '@/helpers/profile'
import { handleError } from '@/store/notifications'
import type { GameInstance, InstanceSettingsTabProps } from '../../../helpers/types'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()
const router = useRouter() const router = useRouter()

View File

@@ -1,11 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { Checkbox } from '@modrinth/ui' import { Checkbox } from '@modrinth/ui'
import { computed, ref, watch } from 'vue'
import { handleError } from '@/store/notifications'
import { defineMessages, useVIntl } from '@vintl/vintl' import { defineMessages, useVIntl } from '@vintl/vintl'
import { get } from '@/helpers/settings.ts' import { computed, ref, watch } from 'vue'
import { edit } from '@/helpers/profile' import { edit } from '@/helpers/profile'
import type { InstanceSettingsTabProps, AppSettings, Hooks } from '../../../helpers/types' import { get } from '@/helpers/settings.ts'
import { handleError } from '@/store/notifications'
import type { AppSettings, Hooks, InstanceSettingsTabProps } from '../../../helpers/types'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,23 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
TransferIcon,
IssuesIcon,
HammerIcon,
DownloadIcon, DownloadIcon,
WrenchIcon, HammerIcon,
UndoIcon, IssuesIcon,
SpinnerIcon, SpinnerIcon,
UnplugIcon, TransferIcon,
UndoIcon,
UnlinkIcon, UnlinkIcon,
UnplugIcon,
WrenchIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Avatar, Checkbox, Chips, ButtonStyled, TeleportDropdownMenu } from '@modrinth/ui' import { Avatar, ButtonStyled, Checkbox, Chips, 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 { import {
formatCategory, formatCategory,
type GameVersionTag, type GameVersionTag,
@@ -25,14 +18,23 @@ import {
type Project, type Project,
type Version, type Version,
} from '@modrinth/utils' } from '@modrinth/utils'
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue' import { defineMessages, useVIntl } from '@vintl/vintl'
import { get_project, get_version_many } from '@/helpers/cache'
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { computed, type ComputedRef, type Ref, ref, shallowRef, watch } from 'vue'
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 { handleError } from '@/store/notifications'
import type { import type {
InstanceSettingsTabProps, InstanceSettingsTabProps,
ManifestLoaderVersion,
Manifest, Manifest,
ManifestLoaderVersion,
} from '../../../helpers/types' } from '../../../helpers/types'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,14 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import { Checkbox, Slider } from '@modrinth/ui'
import { CheckCircleIcon, XCircleIcon } from '@modrinth/assets' import { CheckCircleIcon, XCircleIcon } from '@modrinth/assets'
import { computed, readonly, ref, watch } from 'vue' import { Checkbox, Slider } from '@modrinth/ui'
import { edit, get_optimal_jre_key } from '@/helpers/profile'
import { handleError } from '@/store/notifications'
import { defineMessages, useVIntl } from '@vintl/vintl' import { defineMessages, useVIntl } from '@vintl/vintl'
import { computed, readonly, ref, watch } from 'vue'
import JavaSelector from '@/components/ui/JavaSelector.vue' 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' import useMemorySlider from '@/composables/useMemorySlider'
import { edit, get_optimal_jre_key } from '@/helpers/profile'
import { get } from '@/helpers/settings.ts'
import { handleError } from '@/store/notifications'
import type { AppSettings, InstanceSettingsTabProps, MemorySettings } from '../../../helpers/types'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,10 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { Checkbox, Toggle } from '@modrinth/ui' 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 { defineMessages, useVIntl } from '@vintl/vintl'
import { get } from '@/helpers/settings.ts' import { computed, type Ref, ref, watch } from 'vue'
import { edit } from '@/helpers/profile' import { edit } from '@/helpers/profile'
import { get } from '@/helpers/settings.ts'
import { handleError } from '@/store/notifications'
import type { AppSettings, InstanceSettingsTabProps } from '../../../helpers/types' import type { AppSettings, InstanceSettingsTabProps } from '../../../helpers/types'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,28 +1,29 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
ReportIcon,
ModrinthIcon,
ShieldIcon,
SettingsIcon,
GaugeIcon,
PaintbrushIcon,
GameIcon,
CoffeeIcon, CoffeeIcon,
GameIcon,
GaugeIcon,
ModrinthIcon,
PaintbrushIcon,
ReportIcon,
SettingsIcon,
ShieldIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { TabbedModal } from '@modrinth/ui' import { TabbedModal } from '@modrinth/ui'
import { computed, ref, watch } from 'vue'
import { useVIntl, defineMessage } from '@vintl/vintl'
import AppearanceSettings from '@/components/ui/settings/AppearanceSettings.vue'
import JavaSettings from '@/components/ui/settings/JavaSettings.vue'
import ResourceManagementSettings from '@/components/ui/settings/ResourceManagementSettings.vue'
import PrivacySettings from '@/components/ui/settings/PrivacySettings.vue'
import DefaultInstanceSettings from '@/components/ui/settings/DefaultInstanceSettings.vue'
import { getVersion } from '@tauri-apps/api/app' import { getVersion } from '@tauri-apps/api/app'
import { version as getOsVersion, platform as getOsPlatform } from '@tauri-apps/plugin-os' import { platform as getOsPlatform, version as getOsVersion } from '@tauri-apps/plugin-os'
import { useTheming } from '@/store/state' import { defineMessage, useVIntl } from '@vintl/vintl'
import FeatureFlagSettings from '@/components/ui/settings/FeatureFlagSettings.vue' import { computed, ref, watch } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import AppearanceSettings from '@/components/ui/settings/AppearanceSettings.vue'
import DefaultInstanceSettings from '@/components/ui/settings/DefaultInstanceSettings.vue'
import FeatureFlagSettings from '@/components/ui/settings/FeatureFlagSettings.vue'
import JavaSettings from '@/components/ui/settings/JavaSettings.vue'
import PrivacySettings from '@/components/ui/settings/PrivacySettings.vue'
import ResourceManagementSettings from '@/components/ui/settings/ResourceManagementSettings.vue'
import { get, set } from '@/helpers/settings.ts' import { get, set } from '@/helpers/settings.ts'
import { useTheming } from '@/store/state'
const themeStore = useTheming() const themeStore = useTheming()

View File

@@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { LogInIcon, SpinnerIcon } from '@modrinth/assets' import { LogInIcon, SpinnerIcon } from '@modrinth/assets'
import { ref } from 'vue' import { ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
defineProps({ defineProps({

View File

@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'
import { ConfirmModal } from '@modrinth/ui' import { ConfirmModal } from '@modrinth/ui'
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js' import { ref } from 'vue'
import { hide_ads_window, show_ads_window } from '@/helpers/ads.js'
import { useTheming } from '@/store/theme.ts' import { useTheming } from '@/store/theme.ts'
const themeStore = useTheming() const themeStore = useTheming()

View File

@@ -2,6 +2,7 @@
import { ChevronRightIcon } from '@modrinth/assets' import { ChevronRightIcon } from '@modrinth/assets'
import { Avatar } from '@modrinth/ui' import { Avatar } from '@modrinth/ui'
import { convertFileSrc } from '@tauri-apps/api/core' import { convertFileSrc } from '@tauri-apps/api/core'
import type { GameInstance } from '@/helpers/types' import type { GameInstance } from '@/helpers/types'
defineProps<{ defineProps<{

View File

@@ -1,22 +1,24 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
ChevronRightIcon, ChevronRightIcon,
CodeIcon,
CoffeeIcon, CoffeeIcon,
InfoIcon, InfoIcon,
WrenchIcon,
MonitorIcon, MonitorIcon,
CodeIcon, WrenchIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Avatar, TabbedModal, type TabbedModalTab } from '@modrinth/ui' import { Avatar, TabbedModal, type TabbedModalTab } from '@modrinth/ui'
import { ref } from 'vue'
import { defineMessage, useVIntl } from '@vintl/vintl'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import GeneralSettings from '@/components/ui/instance_settings/GeneralSettings.vue'
import { convertFileSrc } from '@tauri-apps/api/core' import { convertFileSrc } from '@tauri-apps/api/core'
import { defineMessage, useVIntl } from '@vintl/vintl'
import { ref } from 'vue'
import GeneralSettings from '@/components/ui/instance_settings/GeneralSettings.vue'
import HooksSettings from '@/components/ui/instance_settings/HooksSettings.vue'
import InstallationSettings from '@/components/ui/instance_settings/InstallationSettings.vue' import InstallationSettings from '@/components/ui/instance_settings/InstallationSettings.vue'
import JavaSettings from '@/components/ui/instance_settings/JavaSettings.vue' import JavaSettings from '@/components/ui/instance_settings/JavaSettings.vue'
import WindowSettings from '@/components/ui/instance_settings/WindowSettings.vue' import WindowSettings from '@/components/ui/instance_settings/WindowSettings.vue'
import HooksSettings from '@/components/ui/instance_settings/HooksSettings.vue' import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import type { InstanceSettingsTabProps } from '../../../helpers/types' import type { InstanceSettingsTabProps } from '../../../helpers/types'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTemplateRef } from 'vue'
import { NewModal as Modal } from '@modrinth/ui' import { NewModal as Modal } from '@modrinth/ui'
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js' import { useTemplateRef } from 'vue'
import { hide_ads_window, show_ads_window } from '@/helpers/ads.js'
import { useTheming } from '@/store/theme.ts' import { useTheming } from '@/store/theme.ts'
const themeStore = useTheming() const themeStore = useTheming()

View File

@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'
import { ShareModal } from '@modrinth/ui' import { ShareModal } from '@modrinth/ui'
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js' import { ref } from 'vue'
import { hide_ads_window, show_ads_window } from '@/helpers/ads.js'
import { useTheming } from '@/store/theme.ts' import { useTheming } from '@/store/theme.ts'
const themeStore = useTheming() const themeStore = useTheming()

View File

@@ -1,9 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { TeleportDropdownMenu, ThemeSelector, Toggle } from '@modrinth/ui' import { TeleportDropdownMenu, ThemeSelector, Toggle } from '@modrinth/ui'
import { useTheming } from '@/store/state'
import { get, set } from '@/helpers/settings.ts'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { get, set } from '@/helpers/settings.ts'
import { getOS } from '@/helpers/utils' import { getOS } from '@/helpers/utils'
import { useTheming } from '@/store/state'
import type { ColorTheme } from '@/store/theme.ts' import type { ColorTheme } from '@/store/theme.ts'
const themeStore = useTheming() const themeStore = useTheming()

View File

@@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { get, set } from '@/helpers/settings.ts'
import { ref, watch } from 'vue'
import { Slider, Toggle } from '@modrinth/ui' import { Slider, Toggle } from '@modrinth/ui'
import { ref, watch } from 'vue'
import useMemorySlider from '@/composables/useMemorySlider' import useMemorySlider from '@/composables/useMemorySlider'
import { get, set } from '@/helpers/settings.ts'
const fetchSettings = await get() const fetchSettings = await get()
fetchSettings.launchArgs = fetchSettings.extra_launch_args.join(' ') fetchSettings.launchArgs = fetchSettings.extra_launch_args.join(' ')

View File

@@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { Toggle } from '@modrinth/ui' import { Toggle } from '@modrinth/ui'
import { useTheming } from '@/store/state'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { get as getSettings, set as setSettings } from '@/helpers/settings.ts' import { get as getSettings, set as setSettings } from '@/helpers/settings.ts'
import { useTheming } from '@/store/state'
import { DEFAULT_FEATURE_FLAGS, type FeatureFlag } from '@/store/theme.ts' import { DEFAULT_FEATURE_FLAGS, type FeatureFlag } from '@/store/theme.ts'
const themeStore = useTheming() const themeStore = useTheming()

View File

@@ -1,8 +1,9 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import JavaSelector from '@/components/ui/JavaSelector.vue'
import { get_java_versions, set_java_version } from '@/helpers/jre' import { get_java_versions, set_java_version } from '@/helpers/jre'
import { handleError } from '@/store/notifications' import { handleError } from '@/store/notifications'
import JavaSelector from '@/components/ui/JavaSelector.vue'
const javaVersions = ref(await get_java_versions().catch(handleError)) const javaVersions = ref(await get_java_versions().catch(handleError))
async function updateJavaVersion(version) { async function updateJavaVersion(version) {

View File

@@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue'
import { get, set } from '@/helpers/settings.ts'
import { Toggle } from '@modrinth/ui' import { Toggle } from '@modrinth/ui'
import { ref, watch } from 'vue'
import { optInAnalytics, optOutAnalytics } from '@/helpers/analytics' import { optInAnalytics, optOutAnalytics } from '@/helpers/analytics'
import { get, set } from '@/helpers/settings.ts'
const settings = ref(await get()) const settings = ref(await get())

View File

@@ -1,12 +1,13 @@
<script setup> <script setup>
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 { BoxIcon, FolderSearchIcon, TrashIcon } from '@modrinth/assets'
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue' import { Button, Slider } from '@modrinth/ui'
import { open } from '@tauri-apps/plugin-dialog' import { open } from '@tauri-apps/plugin-dialog'
import { ref, watch } from 'vue'
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
import { purge_cache_types } from '@/helpers/cache.js'
import { get, set } from '@/helpers/settings.ts'
import { handleError } from '@/store/notifications.js'
const settings = ref(await get()) const settings = ref(await get())

View File

@@ -100,37 +100,38 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, useTemplateRef } from 'vue'
import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue'
import { import {
SkinPreviewRenderer, CheckIcon,
ChevronRightIcon,
SaveIcon,
SpinnerIcon,
UploadIcon,
XIcon,
} from '@modrinth/assets'
import {
Button, Button,
RadioButtons, ButtonStyled,
CapeButton, CapeButton,
CapeLikeTextButton, CapeLikeTextButton,
ButtonStyled, RadioButtons,
SkinPreviewRenderer,
} from '@modrinth/ui' } from '@modrinth/ui'
import { computed, ref, useTemplateRef, watch } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue'
import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue'
import { import {
add_and_equip_custom_skin, add_and_equip_custom_skin,
remove_custom_skin,
unequip_skin,
type Skin,
type Cape, type Cape,
type SkinModel,
get_normalized_skin_texture,
determineModelType, determineModelType,
get_normalized_skin_texture,
remove_custom_skin,
type Skin,
type SkinModel,
unequip_skin,
} from '@/helpers/skins.ts' } from '@/helpers/skins.ts'
import { handleError } from '@/store/notifications' 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 modal = useTemplateRef('modal')
const selectCapeModal = useTemplateRef('selectCapeModal') const selectCapeModal = useTemplateRef('selectCapeModal')

View File

@@ -1,15 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTemplateRef, ref, computed } from 'vue' import { CheckIcon, XIcon } from '@modrinth/assets'
import type { Cape, SkinModel } from '@/helpers/skins.ts'
import { import {
ButtonStyled, ButtonStyled,
ScrollablePanel,
CapeButton, CapeButton,
CapeLikeTextButton, CapeLikeTextButton,
ScrollablePanel,
SkinPreviewRenderer, SkinPreviewRenderer,
} from '@modrinth/ui' } from '@modrinth/ui'
import { CheckIcon, XIcon } from '@modrinth/assets' import { computed, ref, useTemplateRef } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import type { Cape, SkinModel } from '@/helpers/skins.ts'
const modal = useTemplateRef('modal') const modal = useTemplateRef('modal')

View File

@@ -27,12 +27,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onBeforeUnmount, watch } from 'vue'
import { UploadIcon } from '@modrinth/assets' import { UploadIcon } from '@modrinth/assets'
import { useNotifications } from '@/store/state'
import { getCurrentWebview } from '@tauri-apps/api/webview' import { getCurrentWebview } from '@tauri-apps/api/webview'
import { onBeforeUnmount, ref, watch } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue' import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { get_dragged_skin_data } from '@/helpers/skins' import { get_dragged_skin_data } from '@/helpers/skins'
import { useNotifications } from '@/store/state'
const notifications = useNotifications() const notifications = useNotifications()

View File

@@ -1,6 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Dayjs } from 'dayjs'
import dayjs from 'dayjs'
import { import {
EyeIcon, EyeIcon,
FolderOpenIcon, FolderOpenIcon,
@@ -17,20 +15,23 @@ import {
SmartClickable, SmartClickable,
useRelativeTime, useRelativeTime,
} from '@modrinth/ui' } from '@modrinth/ui'
import { useVIntl } from '@vintl/vintl'
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 { capitalizeString } from '@modrinth/utils'
import { kill, run } from '@/helpers/profile' import { convertFileSrc } from '@tauri-apps/api/core'
import { handleSevereError } from '@/store/error' import { useVIntl } from '@vintl/vintl'
import type { Dayjs } from 'dayjs'
import dayjs from 'dayjs'
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { trackEvent } from '@/helpers/analytics' import { trackEvent } from '@/helpers/analytics'
import { get_by_profile_path } from '@/helpers/process' import { get_project } from '@/helpers/cache'
import { handleError } from '@/store/notifications'
import { process_listener } from '@/helpers/events' 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 { handleError } from '@/store/notifications'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()
const formatRelativeTime = useRelativeTime() const formatRelativeTime = useRelativeTime()

View File

@@ -1,30 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { import { GAME_MODES, HeadingLink } from '@modrinth/ui'
type ProtocolVersion,
type ServerWorld,
type ServerData,
type WorldWithProfile,
get_recent_worlds,
getWorldIdentifier,
get_profile_protocol_version,
refreshServerData,
start_join_server,
start_join_singleplayer_world,
} from '@/helpers/worlds.ts'
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 type { Dayjs } from 'dayjs'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { useTheming } from '@/store/theme.ts' import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { kill, run } from '@/helpers/profile'
import { handleError } from '@/store/notifications' import InstanceItem from '@/components/ui/world/InstanceItem.vue'
import WorldItem from '@/components/ui/world/WorldItem.vue'
import { trackEvent } from '@/helpers/analytics' import { trackEvent } from '@/helpers/analytics'
import { process_listener, profile_listener } from '@/helpers/events' import { process_listener, profile_listener } from '@/helpers/events'
import { get_all } from '@/helpers/process' import { get_all } from '@/helpers/process'
import { kill, run } from '@/helpers/profile'
import type { GameInstance } from '@/helpers/types' import type { GameInstance } from '@/helpers/types'
import {
get_profile_protocol_version,
get_recent_worlds,
getWorldIdentifier,
type ProtocolVersion,
refreshServerData,
type ServerData,
type ServerWorld,
start_join_server,
start_join_singleplayer_world,
type WorldWithProfile,
} from '@/helpers/worlds.ts'
import { handleSevereError } from '@/store/error' import { handleSevereError } from '@/store/error'
import { handleError } from '@/store/notifications'
import { useTheming } from '@/store/theme.ts'
const props = defineProps<{ const props = defineProps<{
recentInstances: GameInstance[] recentInstances: GameInstance[]

View File

@@ -1,29 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs'
import type {
ProtocolVersion,
ServerStatus,
ServerWorld,
SingleplayerWorld,
World,
set_world_display_status,
getWorldIdentifier,
} from '@/helpers/worlds.ts'
import { formatNumber, getPingLevel } from '@modrinth/utils'
import { import {
useRelativeTime,
Avatar,
ButtonStyled,
commonMessages,
OverflowMenu,
SmartClickable,
} from '@modrinth/ui'
import {
IssuesIcon,
EyeIcon,
ClipboardCopyIcon, ClipboardCopyIcon,
EditIcon, EditIcon,
EyeIcon,
FolderOpenIcon, FolderOpenIcon,
IssuesIcon,
MoreVerticalIcon, MoreVerticalIcon,
NoSignalIcon, NoSignalIcon,
PlayIcon, PlayIcon,
@@ -36,14 +17,33 @@ import {
UserIcon, UserIcon,
XIcon, XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import {
Avatar,
ButtonStyled,
commonMessages,
OverflowMenu,
SmartClickable,
useRelativeTime,
} from '@modrinth/ui'
import { formatNumber, getPingLevel } from '@modrinth/utils'
import { convertFileSrc } from '@tauri-apps/api/core'
import type { MessageDescriptor } from '@vintl/vintl' import type { MessageDescriptor } from '@vintl/vintl'
import { defineMessages, useVIntl } from '@vintl/vintl' import { defineMessages, useVIntl } from '@vintl/vintl'
import dayjs from 'dayjs'
import { Tooltip } from 'floating-vue'
import type { Component } from 'vue' import type { Component } from 'vue'
import { computed } from 'vue' import { computed } from 'vue'
import { copyToClipboard } from '@/helpers/utils'
import { convertFileSrc } from '@tauri-apps/api/core'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { Tooltip } from 'floating-vue'
import { copyToClipboard } from '@/helpers/utils'
import type {
ProtocolVersion,
ServerStatus,
ServerWorld,
SingleplayerWorld,
World,
} from '@/helpers/worlds.ts'
import { getWorldIdentifier, set_world_display_status } from '@/helpers/worlds.ts'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()
const formatRelativeTime = useRelativeTime() const formatRelativeTime = useRelativeTime()
@@ -61,7 +61,8 @@ const props = withDefaults(
playingInstance?: boolean playingInstance?: boolean
playingWorld?: boolean playingWorld?: boolean
startingInstance?: boolean startingInstance?: boolean
supportsQuickPlay?: boolean supportsServerQuickPlay?: boolean
supportsWorldQuickPlay?: boolean
currentProtocol?: ProtocolVersion | null currentProtocol?: ProtocolVersion | null
highlighted?: boolean highlighted?: boolean
@@ -85,7 +86,8 @@ const props = withDefaults(
playingInstance: false, playingInstance: false,
playingWorld: false, playingWorld: false,
startingInstance: false, startingInstance: false,
supportsQuickPlay: false, supportsServerQuickPlay: true,
supportsWorldQuickPlay: false,
currentProtocol: null, currentProtocol: null,
refreshing: false, refreshing: false,
@@ -128,9 +130,13 @@ const messages = defineMessages({
id: 'instance.worlds.a_minecraft_server', id: 'instance.worlds.a_minecraft_server',
defaultMessage: 'A Minecraft Server', defaultMessage: 'A Minecraft Server',
}, },
noQuickPlay: { noServerQuickPlay: {
id: 'instance.worlds.no_quick_play', id: 'instance.worlds.no_server_quick_play',
defaultMessage: 'You can only jump straight into worlds on Minecraft 1.20+', defaultMessage: 'You can only jump straight into servers on Minecraft Alpha 1.0.5+',
},
noSingleplayerQuickPlay: {
id: 'instance.worlds.no_singleplayer_quick_play',
defaultMessage: 'You can only jump straight into singleplayer worlds on Minecraft 1.20+',
}, },
gameAlreadyOpen: { gameAlreadyOpen: {
id: 'instance.worlds.game_already_open', id: 'instance.worlds.game_already_open',
@@ -152,10 +158,6 @@ const messages = defineMessages({
id: 'instance.worlds.view_instance', id: 'instance.worlds.view_instance',
defaultMessage: 'View instance', defaultMessage: 'View instance',
}, },
playAnyway: {
id: 'instance.worlds.play_anyway',
defaultMessage: 'Play anyway',
},
playInstance: { playInstance: {
id: 'instance.worlds.play_instance', id: 'instance.worlds.play_instance',
defaultMessage: 'Play instance', defaultMessage: 'Play instance',
@@ -330,17 +332,24 @@ const messages = defineMessages({
<ButtonStyled v-else> <ButtonStyled v-else>
<button <button
v-tooltip=" v-tooltip="
!serverStatus world.type == 'server' && !supportsServerQuickPlay
? formatMessage(messages.noContact) ? formatMessage(messages.noServerQuickPlay)
: serverIncompatible : world.type == 'singleplayer' && !supportsWorldQuickPlay
? formatMessage(messages.incompatibleServer) ? formatMessage(messages.noSingleplayerQuickPlay)
: !supportsQuickPlay : playingOtherWorld || locked
? formatMessage(messages.noQuickPlay) ? formatMessage(messages.gameAlreadyOpen)
: playingOtherWorld || locked : !serverStatus
? formatMessage(messages.gameAlreadyOpen) ? formatMessage(messages.noContact)
: null : serverIncompatible
? formatMessage(messages.incompatibleServer)
: null
"
:disabled="
playingOtherWorld ||
startingInstance ||
(world.type == 'server' && !supportsServerQuickPlay) ||
(world.type == 'singleplayer' && !supportsWorldQuickPlay)
" "
:disabled="!supportsQuickPlay || playingOtherWorld || startingInstance"
@click="emit('play')" @click="emit('play')"
> >
<SpinnerIcon v-if="startingInstance && playingWorld" class="animate-spin" /> <SpinnerIcon v-if="startingInstance && playingWorld" class="animate-spin" />
@@ -357,11 +366,6 @@ const messages = defineMessages({
disabled: playingInstance, disabled: playingInstance,
action: () => emit('play-instance'), action: () => emit('play-instance'),
}, },
{
id: 'play-anyway',
shown: serverIncompatible && !playingInstance && supportsQuickPlay,
action: () => emit('play'),
},
{ {
id: 'open-instance', id: 'open-instance',
shown: !!instancePath, shown: !!instancePath,
@@ -427,10 +431,6 @@ const messages = defineMessages({
<PlayIcon aria-hidden="true" /> <PlayIcon aria-hidden="true" />
{{ formatMessage(messages.playInstance) }} {{ formatMessage(messages.playInstance) }}
</template> </template>
<template #play-anyway>
<PlayIcon aria-hidden="true" />
{{ formatMessage(messages.playAnyway) }}
</template>
<template #open-instance> <template #open-instance>
<EyeIcon aria-hidden="true" /> <EyeIcon aria-hidden="true" />
{{ formatMessage(messages.viewInstance) }} {{ formatMessage(messages.viewInstance) }}

View File

@@ -1,14 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { PlayIcon, PlusIcon, XIcon } from '@modrinth/assets' import { PlayIcon, PlusIcon, XIcon } from '@modrinth/assets'
import { ButtonStyled, commonMessages } from '@modrinth/ui' 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 { defineMessages, useVIntl } from '@vintl/vintl'
import { handleError } from '@/store/notifications' import { ref } from 'vue'
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 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 { handleError } from '@/store/notifications'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,20 +1,21 @@
<script setup lang="ts"> <script setup lang="ts">
import { SaveIcon, XIcon } from '@modrinth/assets' import { SaveIcon, XIcon } from '@modrinth/assets'
import { ButtonStyled, commonMessages } from '@modrinth/ui' import { ButtonStyled, commonMessages } from '@modrinth/ui'
import { defineMessage, useVIntl } from '@vintl/vintl'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.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 { GameInstance } from '@/helpers/types'
import { import {
type ServerPackStatus, type DisplayStatus,
edit_server_in_profile, edit_server_in_profile,
type ServerPackStatus,
type ServerWorld, type ServerWorld,
set_world_display_status, set_world_display_status,
type DisplayStatus,
} from '@/helpers/worlds.ts' } from '@/helpers/worlds.ts'
import { defineMessage, useVIntl } from '@vintl/vintl'
import { handleError } from '@/store/notifications' import { handleError } from '@/store/notifications'
import ServerModalBody from '@/components/ui/world/modal/ServerModalBody.vue'
import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.vue'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,14 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { ChevronRightIcon, SaveIcon, XIcon, UndoIcon } from '@modrinth/assets' import { ChevronRightIcon, SaveIcon, UndoIcon, XIcon } from '@modrinth/assets'
import { Avatar, ButtonStyled, commonMessages } from '@modrinth/ui' import { Avatar, ButtonStyled, commonMessages } from '@modrinth/ui'
import { defineMessages, useVIntl } from '@vintl/vintl'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.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 { GameInstance } from '@/helpers/types'
import type { DisplayStatus, SingleplayerWorld } from '@/helpers/worlds.ts' import type { DisplayStatus, SingleplayerWorld } from '@/helpers/worlds.ts'
import { set_world_display_status, rename_world, reset_world_icon } from '@/helpers/worlds.ts' import { rename_world, reset_world_icon, set_world_display_status } from '@/helpers/worlds.ts'
import { defineMessages, useVIntl } from '@vintl/vintl'
import { handleError } from '@/store/notifications' import { handleError } from '@/store/notifications'
import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.vue'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { Checkbox } from '@modrinth/ui'
import { defineMessage, useVIntl } from '@vintl/vintl' import { defineMessage, useVIntl } from '@vintl/vintl'
import { computed } from 'vue' import { computed } from 'vue'
import { Checkbox } from '@modrinth/ui'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()
const value = defineModel<boolean>({ required: true }) const value = defineModel<boolean>({ required: true })

View File

@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { TeleportDropdownMenu } from '@modrinth/ui' import { TeleportDropdownMenu } from '@modrinth/ui'
import { defineMessages, type MessageDescriptor, useVIntl } from '@vintl/vintl'
import type { ServerPackStatus } from '@/helpers/worlds.ts' import type { ServerPackStatus } from '@/helpers/worlds.ts'
import { type MessageDescriptor, defineMessages, useVIntl } from '@vintl/vintl'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,4 +1,5 @@
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import cssContent from '@/assets/stylesheets/macFix.css?inline' import cssContent from '@/assets/stylesheets/macFix.css?inline'
export async function useCheckDisableMouseover() { export async function useCheckDisableMouseover() {

View File

@@ -1,4 +1,5 @@
import { ref, computed } from 'vue' import { computed, ref } from 'vue'
import { get_max_memory } from '@/helpers/jre.js' import { get_max_memory } from '@/helpers/jre.js'
import { handleError } from '@/store/notifications.js' import { handleError } from '@/store/notifications.js'

View File

@@ -1,6 +1,7 @@
import { fetch } from '@tauri-apps/plugin-http'
import { handleError } from '@/store/state.js'
import { getVersion } from '@tauri-apps/api/app' import { getVersion } from '@tauri-apps/api/app'
import { fetch } from '@tauri-apps/plugin-http'
import { handleError } from '@/store/state.js'
export const useFetch = async (url, item, isSilent) => { export const useFetch = async (url, item, isSilent) => {
try { try {

View File

@@ -4,6 +4,7 @@
* and deserialized into a usable JS object. * and deserialized into a usable JS object.
*/ */
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import { create } from './profile' import { create } from './profile'
/* /*

View File

@@ -4,6 +4,7 @@
* and deserialized into a usable JS object. * and deserialized into a usable JS object.
*/ */
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import { create } from './profile' import { create } from './profile'
// Installs pack from a version ID // Installs pack from a version ID

View File

@@ -4,6 +4,7 @@
* and deserialized into a usable JS object. * and deserialized into a usable JS object.
*/ */
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import { install_to_existing_profile } from '@/helpers/pack.js' import { install_to_existing_profile } from '@/helpers/pack.js'
import { handleError } from '@/store/notifications.js' import { handleError } from '@/store/notifications.js'

View File

@@ -1,17 +1,18 @@
import * as THREE from 'three' import { ClassicPlayerModel, SlimPlayerModel } from '@modrinth/assets'
import type { Skin, Cape } from '../skins'
import { get_normalized_skin_texture, determineModelType } from '../skins'
import { reactive } from 'vue'
import { import {
setupSkinModel,
disposeCaches,
loadTexture,
applyCapeTexture, applyCapeTexture,
createTransparentTexture, createTransparentTexture,
disposeCaches,
loadTexture,
setupSkinModel,
} from '@modrinth/utils' } from '@modrinth/utils'
import { skinPreviewStorage } from '../storage/skin-preview-storage' import * as THREE from 'three'
import { reactive } from 'vue'
import type { Cape, Skin } from '../skins'
import { determineModelType, get_normalized_skin_texture } from '../skins'
import { headStorage } from '../storage/head-storage' import { headStorage } from '../storage/head-storage'
import { ClassicPlayerModel, SlimPlayerModel } from '@modrinth/assets' import { skinPreviewStorage } from '../storage/skin-preview-storage'
export interface RenderResult { export interface RenderResult {
forwards: string forwards: string

View File

@@ -4,8 +4,9 @@
* and deserialized into a usable JS object. * and deserialized into a usable JS object.
*/ */
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import type { ColorTheme, FeatureFlag } from '@/store/theme.ts'
import type { Hooks, MemorySettings, WindowSize } from '@/helpers/types' import type { Hooks, MemorySettings, WindowSize } from '@/helpers/types'
import type { ColorTheme, FeatureFlag } from '@/store/theme.ts'
// Settings object // Settings object
/* /*

View File

@@ -1,6 +1,7 @@
import { invoke } from '@tauri-apps/api/core'
import { handleError } from '@/store/notifications'
import { arrayBufferToBase64 } from '@modrinth/utils' import { arrayBufferToBase64 } from '@modrinth/utils'
import { invoke } from '@tauri-apps/api/core'
import { handleError } from '@/store/notifications'
export interface Cape { export interface Cape {
id: string id: string

View File

@@ -1,6 +1,7 @@
import { get_full_path, get_mod_full_path } from '@/helpers/profile'
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import { get_full_path, get_mod_full_path } from '@/helpers/profile'
export async function isDev() { export async function isDev() {
return await invoke('is_dev') return await invoke('is_dev')
} }

View File

@@ -1,9 +1,10 @@
import { autoToHTML } from '@geometrically/minecraft-motd-parser'
import type { GameVersion } from '@modrinth/ui'
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import dayjs from 'dayjs'
import { get_full_path } from '@/helpers/profile' import { get_full_path } from '@/helpers/profile'
import { openPath } from '@/helpers/utils' import { openPath } from '@/helpers/utils'
import { autoToHTML } from '@geometrically/minecraft-motd-parser'
import dayjs from 'dayjs'
import type { GameVersion } from '@modrinth/ui'
type BaseWorld = { type BaseWorld = {
name: string name: string
@@ -311,15 +312,24 @@ export async function refreshWorlds(instancePath: string): Promise<World[]> {
return worlds ?? [] return worlds ?? []
} }
const FIRST_QUICK_PLAY_VERSION = '23w14a' export function hasServerQuickPlaySupport(gameVersions: GameVersion[], currentVersion: string) {
if (!gameVersions.length) {
return true
}
export function hasQuickPlaySupport(gameVersions: GameVersion[], currentVersion: string) { const versionIndex = gameVersions.findIndex((v) => v.version === currentVersion)
const targetIndex = gameVersions.findIndex((v) => v.version === 'a1.0.5_01')
return versionIndex === -1 || targetIndex === -1 || versionIndex <= targetIndex
}
export function hasWorldQuickPlaySupport(gameVersions: GameVersion[], currentVersion: string) {
if (!gameVersions.length) { if (!gameVersions.length) {
return false return false
} }
const versionIndex = gameVersions.findIndex((v) => v.version === currentVersion) const versionIndex = gameVersions.findIndex((v) => v.version === currentVersion)
const targetIndex = gameVersions.findIndex((v) => v.version === FIRST_QUICK_PLAY_VERSION) const targetIndex = gameVersions.findIndex((v) => v.version === '23w14a')
return versionIndex !== -1 && targetIndex !== -1 && versionIndex <= targetIndex return versionIndex !== -1 && targetIndex !== -1 && versionIndex <= targetIndex
} }

View File

@@ -383,11 +383,11 @@
"instance.worlds.no_contact": { "instance.worlds.no_contact": {
"message": "Server couldn't be contacted" "message": "Server couldn't be contacted"
}, },
"instance.worlds.no_quick_play": { "instance.worlds.no_server_quick_play": {
"message": "You can only jump straight into worlds on Minecraft 1.20+" "message": "You can only jump straight into servers on Minecraft Alpha 1.0.5+"
}, },
"instance.worlds.play_anyway": { "instance.worlds.no_singleplayer_quick_play": {
"message": "Play anyway" "message": "You can only jump straight into singleplayer worlds on Minecraft 1.20+"
}, },
"instance.worlds.play_instance": { "instance.worlds.play_instance": {
"message": "Play instance" "message": "Play instance"

View File

@@ -1,12 +1,14 @@
import { createApp } from 'vue'
import router from '@/routes'
import App from '@/App.vue'
import { createPinia } from 'pinia'
import FloatingVue from 'floating-vue'
import 'floating-vue/dist/style.css' import 'floating-vue/dist/style.css'
import { createPlugin } from '@vintl/vintl/plugin'
import * as Sentry from '@sentry/vue' import * as Sentry from '@sentry/vue'
import { VueScanPlugin } from '@taijased/vue-render-tracker' import { VueScanPlugin } from '@taijased/vue-render-tracker'
import { createPlugin } from '@vintl/vintl/plugin'
import FloatingVue from 'floating-vue'
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from '@/App.vue'
import router from '@/routes'
const VIntlPlugin = createPlugin({ const VIntlPlugin = createPlugin({
controllerOpts: { controllerOpts: {

View File

@@ -1,32 +1,33 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, nextTick, ref, shallowRef, watch } from 'vue' import { ClipboardCopyIcon, ExternalIcon, GlobeIcon, SearchIcon, XIcon } from '@modrinth/assets'
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 type { Category, GameVersion, Platform, ProjectType, SortType, Tags } from '@modrinth/ui'
import { import {
SearchFilterControl,
SearchSidebarFilter,
Button, Button,
Checkbox, Checkbox,
DropdownSelect, DropdownSelect,
LoadingIndicator, LoadingIndicator,
Pagination, Pagination,
SearchFilterControl,
SearchSidebarFilter,
useSearch, useSearch,
} from '@modrinth/ui' } from '@modrinth/ui'
import { handleError } from '@/store/state' import { openUrl } from '@tauri-apps/plugin-opener'
import { useBreadcrumbs } from '@/store/breadcrumbs' import { defineMessages, useVIntl } from '@vintl/vintl'
import { get_categories, get_game_versions, get_loaders } from '@/helpers/tags' import type { Ref } from 'vue'
import { computed, nextTick, ref, shallowRef, watch } from 'vue'
import type { LocationQuery } from 'vue-router' import type { LocationQuery } from 'vue-router'
import { useRoute, useRouter } 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 ContextMenu from '@/components/ui/ContextMenu.vue'
import { get_search_results } from '@/helpers/cache.js'
import NavTabs from '@/components/ui/NavTabs.vue'
import type Instance from '@/components/ui/Instance.vue' import type Instance from '@/components/ui/Instance.vue'
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue' import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
import { defineMessages, useVIntl } from '@vintl/vintl' import NavTabs from '@/components/ui/NavTabs.vue'
import ContextMenu from '@/components/ui/ContextMenu.vue' import SearchCard from '@/components/ui/SearchCard.vue'
import { openUrl } from '@tauri-apps/plugin-opener' 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 { handleError } from '@/store/state'
const { formatMessage } = useVIntl() const { formatMessage } = useVIntl()

View File

@@ -1,16 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onUnmounted, computed } from 'vue' import type { SearchResult } from '@modrinth/utils'
import dayjs from 'dayjs'
import { computed, onUnmounted, ref } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import RowDisplay from '@/components/RowDisplay.vue' import RowDisplay from '@/components/RowDisplay.vue'
import { list } from '@/helpers/profile.js' import RecentWorldsList from '@/components/ui/world/RecentWorldsList.vue'
import { get_search_results } from '@/helpers/cache.js'
import { profile_listener } from '@/helpers/events' import { profile_listener } from '@/helpers/events'
import { list } from '@/helpers/profile.js'
import type { GameInstance } from '@/helpers/types'
import { useBreadcrumbs } from '@/store/breadcrumbs' import { useBreadcrumbs } from '@/store/breadcrumbs'
import { handleError } from '@/store/notifications.js' 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 route = useRoute() const route = useRoute()
const breadcrumbs = useBreadcrumbs() const breadcrumbs = useBreadcrumbs()

View File

@@ -16,33 +16,34 @@ import {
SkinLikeTextButton, SkinLikeTextButton,
SkinPreviewRenderer, SkinPreviewRenderer,
} from '@modrinth/ui' } from '@modrinth/ui'
import { arrayBufferToBase64 } from '@modrinth/utils'
import { computedAsync } from '@vueuse/core' import { computedAsync } from '@vueuse/core'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { computed, inject, onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue' import { computed, inject, onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue'
import type AccountsCard from '@/components/ui/AccountsCard.vue'
import EditSkinModal from '@/components/ui/skin/EditSkinModal.vue' import EditSkinModal from '@/components/ui/skin/EditSkinModal.vue'
import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue' import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue'
import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue' import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue'
import { handleError, useNotifications } from '@/store/notifications' 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 type { Cape, Skin } from '@/helpers/skins.ts'
import { import {
normalize_skin_texture,
equip_skin, equip_skin,
filterDefaultSkins, filterDefaultSkins,
filterSavedSkins, filterSavedSkins,
get_available_capes, get_available_capes,
get_available_skins, get_available_skins,
get_normalized_skin_texture, get_normalized_skin_texture,
normalize_skin_texture,
remove_custom_skin, remove_custom_skin,
set_default_cape, set_default_cape,
} from '@/helpers/skins.ts' } 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 { handleSevereError } from '@/store/error'
import { trackEvent } from '@/helpers/analytics' import { handleError, useNotifications } from '@/store/notifications'
import type AccountsCard from '@/components/ui/AccountsCard.vue'
import { arrayBufferToBase64 } from '@modrinth/utils'
const editSkinModal = useTemplateRef('editSkinModal') const editSkinModal = useTemplateRef('editSkinModal')
const selectCapeModal = useTemplateRef('selectCapeModal') const selectCapeModal = useTemplateRef('selectCapeModal')
const uploadSkinModal = useTemplateRef('uploadSkinModal') const uploadSkinModal = useTemplateRef('uploadSkinModal')

View File

@@ -1,6 +1,6 @@
import Index from './Index.vue'
import Browse from './Browse.vue' import Browse from './Browse.vue'
import Worlds from './Worlds.vue' import Index from './Index.vue'
import Skins from './Skins.vue' import Skins from './Skins.vue'
import Worlds from './Worlds.vue'
export { Index, Browse, Worlds, Skins } export { Browse, Index, Skins, Worlds }

View File

@@ -157,13 +157,6 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import {
Avatar,
ButtonStyled,
ContentPageHeader,
LoadingIndicator,
OverflowMenu,
} from '@modrinth/ui'
import { import {
CheckCircleIcon, CheckCircleIcon,
ClipboardCopyIcon, ClipboardCopyIcon,
@@ -187,24 +180,32 @@ import {
UserPlusIcon, UserPlusIcon,
XIcon, XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { finish_install, get, get_full_path, kill, run } from '@/helpers/profile' import {
import { get_by_profile_path } from '@/helpers/process' Avatar,
import { process_listener, profile_listener } from '@/helpers/events' ButtonStyled,
import { useRoute, useRouter } from 'vue-router' ContentPageHeader,
import { computed, onUnmounted, ref, watch } from 'vue' LoadingIndicator,
import { handleError, useBreadcrumbs, useLoading } from '@/store/state' OverflowMenu,
import { showProfileInFolder } from '@/helpers/utils.js' } from '@modrinth/ui'
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 { 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 dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration' import duration from 'dayjs/plugin/duration'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
import { computed, onUnmounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import ContextMenu from '@/components/ui/ContextMenu.vue'
import ExportModal from '@/components/ui/ExportModal.vue' import ExportModal from '@/components/ui/ExportModal.vue'
import InstanceSettingsModal from '@/components/ui/modal/InstanceSettingsModal.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 { handleError, useBreadcrumbs, useLoading } from '@/store/state'
dayjs.extend(duration) dayjs.extend(duration)
dayjs.extend(relativeTime) dayjs.extend(relativeTime)

View File

@@ -88,26 +88,28 @@
</template> </template>
<script setup> <script setup>
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import { CheckIcon, ClipboardCopyIcon, ShareIcon, TrashIcon } from '@modrinth/assets' import { CheckIcon, ClipboardCopyIcon, ShareIcon, TrashIcon } from '@modrinth/assets'
import { Button, Card, Checkbox, DropdownSelect } from '@modrinth/ui' import { Button, Card, Checkbox, DropdownSelect } from '@modrinth/ui'
import {
delete_logs_by_filename,
get_logs,
get_output_by_filename,
get_latest_log_cursor,
} from '@/helpers/logs.js'
import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import isToday from 'dayjs/plugin/isToday' import isToday from 'dayjs/plugin/isToday'
import isYesterday from 'dayjs/plugin/isYesterday' import isYesterday from 'dayjs/plugin/isYesterday'
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 { ofetch } from 'ofetch'
import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { RecycleScroller } from 'vue-virtual-scroller' import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue' import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
import { process_listener } from '@/helpers/events.js'
import {
delete_logs_by_filename,
get_latest_log_cursor,
get_logs,
get_output_by_filename,
} from '@/helpers/logs.js'
import { get_by_profile_path } from '@/helpers/process.js'
import { handleError } from '@/store/notifications.js'
dayjs.extend(isToday) dayjs.extend(isToday)
dayjs.extend(isYesterday) dayjs.extend(isYesterday)

View File

@@ -276,11 +276,29 @@ import {
RadialHeader, RadialHeader,
Toggle, Toggle,
} from '@modrinth/ui' } from '@modrinth/ui'
import type { ContentItem } from '@modrinth/ui/src/components/content/ContentListItem.vue'
import type { Organization, Project, TeamMember, Version } from '@modrinth/utils' import type { Organization, Project, TeamMember, Version } from '@modrinth/utils'
import { formatProjectType } 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 type { ComputedRef } from 'vue'
import { computed, onUnmounted, ref, watch } from 'vue' import { computed, onUnmounted, ref, watch } from 'vue'
import { defineMessages, useVIntl } from '@vintl/vintl'
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 { import {
add_project_from_path, add_project_from_path,
get_projects, get_projects,
@@ -289,26 +307,9 @@ import {
update_all, update_all,
update_project, update_project,
} from '@/helpers/profile.js' } 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 { CacheBehaviour, ContentFile, GameInstance } from '@/helpers/types'
import type ContextMenu from '@/components/ui/ContextMenu.vue' import { highlightModInProfile } from '@/helpers/utils.js'
import type { ContentItem } from '@modrinth/ui/src/components/content/ContentListItem.vue' import { handleError } from '@/store/notifications.js'
const props = defineProps<{ const props = defineProps<{
instance: GameInstance instance: GameInstance

View File

@@ -1,9 +1,10 @@
<template>{{ instance.name }} overview</template> <template>{{ instance.name }} overview</template>
<script setup lang="ts"> <script setup lang="ts">
import type { GameInstance } from '@/helpers/types'
import type ContextMenu from '@/components/ui/ContextMenu.vue'
import type { Version } from '@modrinth/utils' import type { Version } from '@modrinth/utils'
import type ContextMenu from '@/components/ui/ContextMenu.vue'
import type { GameInstance } from '@/helpers/types'
defineProps<{ defineProps<{
instance: GameInstance instance: GameInstance
options: InstanceType<typeof ContextMenu> options: InstanceType<typeof ContextMenu>

View File

@@ -67,7 +67,8 @@
:key="`world-${world.type}-${world.type == 'singleplayer' ? world.path : `${world.address}-${world.index}`}`" :key="`world-${world.type}-${world.type == 'singleplayer' ? world.path : `${world.address}-${world.index}`}`"
:world="world" :world="world"
:highlighted="highlightedWorld === getWorldIdentifier(world)" :highlighted="highlightedWorld === getWorldIdentifier(world)"
:supports-quick-play="supportsQuickPlay" :supports-server-quick-play="supportsServerQuickPlay"
:supports-world-quick-play="supportsWorldQuickPlay"
:current-protocol="protocolVersion" :current-protocol="protocolVersion"
:playing-instance="playing" :playing-instance="playing"
:playing-world="worldsMatch(world, worldPlaying)" :playing-world="worldsMatch(world, worldPlaying)"
@@ -120,53 +121,54 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onUnmounted, watch } from 'vue' import { PlusIcon, SearchIcon, SpinnerIcon, UpdatedIcon, XIcon } from '@modrinth/assets'
import { useRoute } from 'vue-router'
import type { GameInstance } from '@/helpers/types'
import { import {
Button, Button,
ButtonStyled, ButtonStyled,
RadialHeader,
FilterBar, FilterBar,
type FilterBarOption, type FilterBarOption,
type GameVersion,
GAME_MODES, GAME_MODES,
type GameVersion,
RadialHeader,
} from '@modrinth/ui' } from '@modrinth/ui'
import { PlusIcon, SpinnerIcon, UpdatedIcon, SearchIcon, XIcon } from '@modrinth/assets' import type { Version } from '@modrinth/utils'
import { import { defineMessages } from '@vintl/vintl'
type ProtocolVersion, import { computed, onUnmounted, ref, watch } from 'vue'
type SingleplayerWorld, import { useRoute } from 'vue-router'
type World,
type ServerWorld, import type ContextMenu from '@/components/ui/ContextMenu.vue'
type ServerData, import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
type ProfileEvent,
get_profile_protocol_version,
remove_server_from_profile,
delete_world,
start_join_server,
start_join_singleplayer_world,
getWorldIdentifier,
refreshServerData,
refreshWorld,
sortWorlds,
refreshServers,
hasQuickPlaySupport,
refreshWorlds,
handleDefaultProfileUpdateEvent,
showWorldInFolder,
} from '@/helpers/worlds.ts'
import AddServerModal from '@/components/ui/world/modal/AddServerModal.vue' import AddServerModal from '@/components/ui/world/modal/AddServerModal.vue'
import EditServerModal from '@/components/ui/world/modal/EditServerModal.vue' import EditServerModal from '@/components/ui/world/modal/EditServerModal.vue'
import EditWorldModal from '@/components/ui/world/modal/EditSingleplayerWorldModal.vue' import EditWorldModal from '@/components/ui/world/modal/EditSingleplayerWorldModal.vue'
import WorldItem from '@/components/ui/world/WorldItem.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 { profile_listener } from '@/helpers/events'
import { get_game_versions } from '@/helpers/tags' import { get_game_versions } from '@/helpers/tags'
import { defineMessages } from '@vintl/vintl' import type { GameInstance } from '@/helpers/types'
import {
delete_world,
get_profile_protocol_version,
getWorldIdentifier,
handleDefaultProfileUpdateEvent,
hasServerQuickPlaySupport,
hasWorldQuickPlaySupport,
type ProfileEvent,
type ProtocolVersion,
refreshServerData,
refreshServers,
refreshWorld,
refreshWorlds,
remove_server_from_profile,
type ServerData,
type ServerWorld,
showWorldInFolder,
type SingleplayerWorld,
sortWorlds,
start_join_server,
start_join_singleplayer_world,
type World,
} from '@/helpers/worlds.ts'
import { handleError } from '@/store/notifications'
const route = useRoute() const route = useRoute()
@@ -355,8 +357,11 @@ function worldsMatch(world: World, other: World | undefined) {
} }
const gameVersions = ref<GameVersion[]>(await get_game_versions().catch(() => [])) const gameVersions = ref<GameVersion[]>(await get_game_versions().catch(() => []))
const supportsQuickPlay = computed(() => const supportsServerQuickPlay = computed(() =>
hasQuickPlaySupport(gameVersions.value, instance.value.game_version), hasServerQuickPlaySupport(gameVersions.value, instance.value.game_version),
)
const supportsWorldQuickPlay = computed(() =>
hasWorldQuickPlaySupport(gameVersions.value, instance.value.game_version),
) )
const filterOptions = computed(() => { const filterOptions = computed(() => {

View File

@@ -1,7 +1,7 @@
import Index from './Index.vue' import Index from './Index.vue'
import Logs from './Logs.vue'
import Mods from './Mods.vue'
import Overview from './Overview.vue' import Overview from './Overview.vue'
import Worlds from './Worlds.vue' import Worlds from './Worlds.vue'
import Mods from './Mods.vue'
import Logs from './Logs.vue'
export { Index, Overview, Worlds, Mods, Logs } export { Index, Logs, Mods, Overview, Worlds }

View File

@@ -1,15 +1,16 @@
<script setup> <script setup>
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 { PlusIcon } from '@modrinth/assets'
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue' import { Button } from '@modrinth/ui'
import { onUnmounted, ref, shallowRef } from 'vue'
import { useRoute } from 'vue-router'
import { NewInstanceImage } from '@/assets/icons' import { NewInstanceImage } from '@/assets/icons'
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
import NavTabs from '@/components/ui/NavTabs.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 { handleError } from '@/store/notifications.js'
const route = useRoute() const route = useRoute()
const breadcrumbs = useBreadcrumbs() const breadcrumbs = useBreadcrumbs()

View File

@@ -1,6 +1,6 @@
import Custom from './Custom.vue'
import Downloaded from './Downloaded.vue'
import Index from './Index.vue' import Index from './Index.vue'
import Overview from './Overview.vue' import Overview from './Overview.vue'
import Downloaded from './Downloaded.vue'
import Custom from './Custom.vue'
export { Index, Overview, Downloaded, Custom } export { Custom, Downloaded, Index, Overview }

View File

@@ -83,18 +83,19 @@
<script setup> <script setup>
import { import {
ExpandIcon,
RightArrowIcon,
LeftArrowIcon,
ExternalIcon,
ContractIcon,
XIcon,
CalendarIcon, CalendarIcon,
ContractIcon,
ExpandIcon,
ExternalIcon,
LeftArrowIcon,
RightArrowIcon,
XIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { Button, Card } from '@modrinth/ui' import { Button, Card } from '@modrinth/ui'
import { ref } from 'vue' import { ref } from 'vue'
import { hide_ads_window, show_ads_window } from '@/helpers/ads.js'
import { trackEvent } from '@/helpers/analytics' import { trackEvent } from '@/helpers/analytics'
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
const props = defineProps({ const props = defineProps({
project: { project: {

View File

@@ -131,41 +131,41 @@
<script setup> <script setup>
import { import {
BookmarkIcon, BookmarkIcon,
MoreVerticalIcon,
DownloadIcon,
ReportIcon,
HeartIcon,
ExternalIcon,
CheckIcon, CheckIcon,
GlobeIcon,
ClipboardCopyIcon, ClipboardCopyIcon,
DownloadIcon,
ExternalIcon,
GlobeIcon,
HeartIcon,
MoreVerticalIcon,
ReportIcon,
} from '@modrinth/assets' } from '@modrinth/assets'
import { import {
ProjectHeader,
ProjectSidebarCompatibility,
ButtonStyled, ButtonStyled,
OverflowMenu, OverflowMenu,
ProjectSidebarLinks, ProjectBackgroundGradient,
ProjectHeader,
ProjectSidebarCompatibility,
ProjectSidebarCreators, ProjectSidebarCreators,
ProjectSidebarDetails, ProjectSidebarDetails,
ProjectBackgroundGradient, ProjectSidebarLinks,
} from '@modrinth/ui' } 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 dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
import { useRoute, useRouter } from 'vue-router'
import { ref, shallowRef, watch } from 'vue' import { ref, shallowRef, watch } from 'vue'
import { useBreadcrumbs } from '@/store/breadcrumbs' import { useRoute, useRouter } from 'vue-router'
import { handleError } from '@/store/notifications.js'
import ContextMenu from '@/components/ui/ContextMenu.vue' 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 InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
import { openUrl } from '@tauri-apps/plugin-opener' 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 { handleError } from '@/store/notifications.js'
import { useTheming } from '@/store/state.js'
dayjs.extend(relativeTime) dayjs.extend(relativeTime)

View File

@@ -182,15 +182,16 @@
</template> </template>
<script setup> <script setup>
import { DownloadIcon, FileIcon, ReportIcon, ExternalIcon, CheckIcon } from '@modrinth/assets' import { CheckIcon, DownloadIcon, ExternalIcon, FileIcon, ReportIcon } from '@modrinth/assets'
import { Avatar, Badge, Breadcrumbs, Button, Card, CopyCode } from '@modrinth/ui'
import { formatBytes, renderString } from '@modrinth/utils' import { formatBytes, renderString } from '@modrinth/utils'
import { Breadcrumbs, Badge, Avatar, Card, Button, CopyCode } from '@modrinth/ui' import { computed, ref, watch } from 'vue'
import { releaseColor } from '@/helpers/utils'
import { ref, watch, computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { useBreadcrumbs } from '@/store/breadcrumbs'
import { SwapIcon } from '@/assets/icons' import { SwapIcon } from '@/assets/icons'
import { get_project_many, get_version_many } from '@/helpers/cache.js' import { get_project_many, get_version_many } from '@/helpers/cache.js'
import { releaseColor } from '@/helpers/utils'
import { useBreadcrumbs } from '@/store/breadcrumbs'
const breadcrumbs = useBreadcrumbs() const breadcrumbs = useBreadcrumbs()

View File

@@ -65,9 +65,10 @@
</template> </template>
<script setup> <script setup>
import { ProjectPageVersions, ButtonStyled, OverflowMenu } from '@modrinth/ui'
import { CheckIcon, DownloadIcon, ExternalIcon, MoreVerticalIcon } from '@modrinth/assets' import { CheckIcon, DownloadIcon, ExternalIcon, MoreVerticalIcon } from '@modrinth/assets'
import { ButtonStyled, OverflowMenu, ProjectPageVersions } from '@modrinth/ui'
import { ref } from 'vue' import { ref } from 'vue'
import { SwapIcon } from '@/assets/icons/index.js' import { SwapIcon } from '@/assets/icons/index.js'
import { get_game_versions, get_loaders } from '@/helpers/tags.js' import { get_game_versions, get_loaders } from '@/helpers/tags.js'
import { handleError } from '@/store/notifications.js' import { handleError } from '@/store/notifications.js'

View File

@@ -1,7 +1,7 @@
import Index from './Index.vue'
import Description from './Description.vue' import Description from './Description.vue'
import Versions from './Versions.vue'
import Gallery from './Gallery.vue' import Gallery from './Gallery.vue'
import Index from './Index.vue'
import Version from './Version.vue' import Version from './Version.vue'
import Versions from './Versions.vue'
export { Index, Description, Versions, Gallery, Version } export { Description, Gallery, Index, Version, Versions }

View File

@@ -1,8 +1,9 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import * as Pages from '@/pages' import * as Pages from '@/pages'
import * as Project from '@/pages/project'
import * as Instance from '@/pages/instance' import * as Instance from '@/pages/instance'
import * as Library from '@/pages/library' import * as Library from '@/pages/library'
import * as Project from '@/pages/project'
/** /**
* Configures application routing. Add page to pages/index and then add to route table here. * Configures application routing. Add page to pages/index and then add to route table here.

View File

@@ -1,4 +1,9 @@
import dayjs from 'dayjs'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
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 { import {
add_project_from_version, add_project_from_version,
check_installed, check_installed,
@@ -8,10 +13,6 @@ import {
remove_project, remove_project,
} from '@/helpers/profile.js' } from '@/helpers/profile.js'
import { handleError } from '@/store/notifications.js' 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'
export const useInstall = defineStore('installStore', { export const useInstall = defineStore('installStore', {
state: () => ({ state: () => ({
@@ -29,8 +30,8 @@ export const useInstall = defineStore('installStore', {
setIncompatibilityWarningModal(ref) { setIncompatibilityWarningModal(ref) {
this.incompatibilityWarningModal = ref this.incompatibilityWarningModal = ref
}, },
showIncompatibilityWarningModal(instance, project, versions, onInstall) { showIncompatibilityWarningModal(instance, project, versions, selected, onInstall) {
this.incompatibilityWarningModal.show(instance, project, versions, onInstall) this.incompatibilityWarningModal.show(instance, project, versions, selected, onInstall)
}, },
setModInstallModal(ref) { setModInstallModal(ref) {
this.modInstallModal = ref this.modInstallModal = ref
@@ -133,7 +134,13 @@ export const install = async (
callback(version.id) callback(version.id)
} else { } else {
const install = useInstall() const install = useInstall()
install.showIncompatibilityWarningModal(instance, project, projectVersions, callback) install.showIncompatibilityWarningModal(
instance,
project,
projectVersions,
version,
callback,
)
} }
} else { } else {
const versions = (await get_version_many(project.versions).catch(handleError)).sort( const versions = (await get_version_many(project.versions).catch(handleError)).sort(

View File

@@ -1,7 +1,7 @@
import { useTheming } from './theme.ts'
import { useBreadcrumbs } from './breadcrumbs' import { useBreadcrumbs } from './breadcrumbs'
import { useLoading } from './loading'
import { useNotifications, handleError } from './notifications'
import { useInstall } from './install' import { useInstall } from './install'
import { useLoading } from './loading'
import { handleError, useNotifications } from './notifications'
import { useTheming } from './theme.ts'
export { useTheming, useBreadcrumbs, useLoading, useNotifications, handleError, useInstall } export { handleError, useBreadcrumbs, useInstall, useLoading, useNotifications, useTheming }

View File

@@ -1,9 +1,8 @@
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path' import { resolve } from 'path'
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import svgLoader from 'vite-svg-loader' import svgLoader from 'vite-svg-loader'
import vue from '@vitejs/plugin-vue'
import tauriConf from '../app/tauri.conf.json' import tauriConf from '../app/tauri.conf.json'
const projectRootDir = resolve(__dirname) const projectRootDir = resolve(__dirname)

View File

@@ -250,7 +250,7 @@ pub async fn profile_get_pack_export_candidates(
// invoke('plugin:profile|profile_run', path) // invoke('plugin:profile|profile_run', path)
#[tauri::command] #[tauri::command]
pub async fn profile_run(path: &str) -> Result<ProcessMetadata> { pub async fn profile_run(path: &str) -> Result<ProcessMetadata> {
let process = profile::run(path, &QuickPlayType::None).await?; let process = profile::run(path, QuickPlayType::None).await?;
Ok(process) Ok(process)
} }

View File

@@ -4,6 +4,7 @@ use enumset::EnumSet;
use tauri::{AppHandle, Manager, Runtime}; use tauri::{AppHandle, Manager, Runtime};
use theseus::prelude::ProcessMetadata; use theseus::prelude::ProcessMetadata;
use theseus::profile::{QuickPlayType, get_full_path}; use theseus::profile::{QuickPlayType, get_full_path};
use theseus::server_address::ServerAddress;
use theseus::worlds::{ use theseus::worlds::{
DisplayStatus, ProtocolVersion, ServerPackStatus, ServerStatus, World, DisplayStatus, ProtocolVersion, ServerPackStatus, ServerStatus, World,
WorldType, WorldWithProfile, WorldType, WorldWithProfile,
@@ -203,7 +204,7 @@ pub async fn start_join_singleplayer_world(
world: String, world: String,
) -> Result<ProcessMetadata> { ) -> Result<ProcessMetadata> {
let process = let process =
profile::run(path, &QuickPlayType::Singleplayer(world)).await?; profile::run(path, QuickPlayType::Singleplayer(world)).await?;
Ok(process) Ok(process)
} }
@@ -213,8 +214,11 @@ pub async fn start_join_server(
path: &str, path: &str,
address: &str, address: &str,
) -> Result<ProcessMetadata> { ) -> Result<ProcessMetadata> {
let process = let process = profile::run(
profile::run(path, &QuickPlayType::Server(address.to_owned())).await?; path,
QuickPlayType::Server(ServerAddress::Unresolved(address.to_owned())),
)
.await?;
Ok(process) Ok(process)
} }

View File

@@ -1,7 +0,0 @@
module.exports = {
root: true,
extends: ["../../packages/eslint-config-custom/nuxt.js"],
rules: {
"import/no-unresolved": "off",
},
};

View File

@@ -1,4 +0,0 @@
{
"endOfLine": "auto",
"plugins": ["prettier-plugin-tailwindcss"]
}

View File

@@ -1,6 +1,6 @@
project_id: 518556 project_id: 518556
preserve_hierarchy: true preserve_hierarchy: true
commit_message: "[ci skip]" commit_message: '[ci skip]'
files: files:
- source: /locales/en-US/* - source: /locales/en-US/*

Some files were not shown because too many files have changed in this diff Show More