mirror of
https://github.com/modrinth/code.git
synced 2026-08-01 05:36:39 +00:00
Compare commits
37
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7134af800 | ||
|
|
9dd69dd9bd | ||
|
|
971b1ebf70 | ||
|
|
3e1d0cba2e | ||
|
|
5c282103a6 | ||
|
|
5e737d677d | ||
|
|
2253ada248 | ||
|
|
543cb42210 | ||
|
|
86c6fb8239 | ||
|
|
14e0abb273 | ||
|
|
df653d3e43 | ||
|
|
4aeb6cf9ff | ||
|
|
cb154e205b | ||
|
|
dad5970e8d | ||
|
|
1947d083b3 | ||
|
|
905204cc5f | ||
|
|
8cca911775 | ||
|
|
cafe58dc3c | ||
|
|
13e6ebf4e0 | ||
|
|
1884912126 | ||
|
|
818a9db9f7 | ||
|
|
c431d1fc89 | ||
|
|
4a09ee7ac9 | ||
|
|
31ef22767e | ||
|
|
706d46a6e2 | ||
|
|
ed9394f2f7 | ||
|
|
9e1e8788e2 | ||
|
|
7c4df7442b | ||
|
|
e1556a8ee3 | ||
|
|
1741d12b7b | ||
|
|
0b38cecc74 | ||
|
|
8680e61883 | ||
|
|
ea86db450b | ||
|
|
bbdaa171e3 | ||
|
|
af8daca059 | ||
|
|
2434f0c45b | ||
|
|
332dfe1074 |
@@ -76,6 +76,8 @@ jobs:
|
||||
|
||||
- name: Deploy Storybook preview
|
||||
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
|
||||
Generated
+35
@@ -2133,6 +2133,15 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||
dependencies = [
|
||||
"thiserror 2.0.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.5"
|
||||
@@ -3259,6 +3268,18 @@ version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "1.0.0"
|
||||
@@ -5440,6 +5461,7 @@ dependencies = [
|
||||
"json-patch 4.1.0",
|
||||
"labrinth",
|
||||
"lettre",
|
||||
"lz4_flex",
|
||||
"meilisearch-sdk",
|
||||
"modrinth-content-management",
|
||||
"modrinth-util",
|
||||
@@ -5447,6 +5469,7 @@ dependencies = [
|
||||
"murmur2",
|
||||
"paste",
|
||||
"path-util",
|
||||
"postcard",
|
||||
"prometheus",
|
||||
"quick-xml 0.38.3",
|
||||
"rand 0.8.5",
|
||||
@@ -7492,6 +7515,18 @@ version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
|
||||
|
||||
[[package]]
|
||||
name = "postcard"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"embedded-io 0.4.0",
|
||||
"embedded-io 0.6.1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.3"
|
||||
|
||||
@@ -118,6 +118,12 @@ lettre = { version = "0.11.19", default-features = false, features = [
|
||||
"tokio1",
|
||||
"tokio1-rustls",
|
||||
] }
|
||||
lz4_flex = { version = "0.11.5", default-features = false, features = [
|
||||
"checked-decode",
|
||||
"safe-decode",
|
||||
"safe-encode",
|
||||
"std",
|
||||
] }
|
||||
maxminddb = "0.26.0"
|
||||
meilisearch-sdk = { version = "0.30.0", default-features = false }
|
||||
modrinth-content-management = { path = "packages/modrinth-content-management" }
|
||||
@@ -135,6 +141,7 @@ paste = "1.0.15"
|
||||
path-util = { path = "packages/path-util" }
|
||||
phf = { version = "0.13.1", features = ["macros"] }
|
||||
png = "0.18.0"
|
||||
postcard = { version = "1.1.3", default-features = false, features = ["alloc"] }
|
||||
proc-macro2 = { version = "1.0" }
|
||||
prometheus = "0.14.0"
|
||||
quartz_nbt = "0.2.9"
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
HomeIcon,
|
||||
LeftArrowIcon,
|
||||
LibraryIcon,
|
||||
LinkIcon,
|
||||
LogInIcon,
|
||||
LogOutIcon,
|
||||
NewspaperIcon,
|
||||
@@ -86,7 +85,6 @@ import NavButton from '@/components/ui/NavButton.vue'
|
||||
import PrideFundraiserBanner from '@/components/ui/PrideFundraiserBanner.vue'
|
||||
import PromotionWrapper from '@/components/ui/PromotionWrapper.vue'
|
||||
import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
|
||||
import SharedInstanceInviteHandler from '@/components/ui/shared-instances/shared-instance-invite-handler/index.vue'
|
||||
import SplashScreen from '@/components/ui/SplashScreen.vue'
|
||||
import WindowControls from '@/components/ui/WindowControls.vue'
|
||||
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||
@@ -149,7 +147,6 @@ const APP_SIDEBAR_WIDTH = 300
|
||||
const INTERCOM_BUBBLE_DEFAULT_PADDING = 20
|
||||
const PRIDE_FUNDRAISER_END_DATE = new Date('2026-07-01T00:00:00Z').getTime()
|
||||
const credentials = ref()
|
||||
let credentialsRefreshId = 0
|
||||
const sidebarToggled = ref(true)
|
||||
const unsubscribeSidebarToggle = themeStore.$subscribe(() => {
|
||||
sidebarToggled.value = !themeStore.toggleSidebar
|
||||
@@ -640,7 +637,6 @@ const contentInstallModpackAlreadyInstalledModal = ref()
|
||||
const addServerToInstanceModal = ref()
|
||||
const incompatibilityWarningModal = ref()
|
||||
const installToPlayModal = ref()
|
||||
const sharedInstanceInviteHandler = ref()
|
||||
const updateToPlayModal = ref()
|
||||
|
||||
const modrinthLoginFlowWaitModal = ref()
|
||||
@@ -651,8 +647,8 @@ watch(incompatibilityWarningModal, (modal) => {
|
||||
}
|
||||
})
|
||||
|
||||
setupAuthProvider(credentials, async (_redirectPath, flow) => {
|
||||
await signIn(flow)
|
||||
setupAuthProvider(credentials, async (_redirectPath) => {
|
||||
await signIn()
|
||||
})
|
||||
|
||||
async function validateSession(sessionToken) {
|
||||
@@ -669,33 +665,23 @@ async function validateSession(sessionToken) {
|
||||
}
|
||||
|
||||
async function fetchCredentials() {
|
||||
const refreshId = ++credentialsRefreshId
|
||||
credentials.value = undefined
|
||||
|
||||
const creds = await getCreds().catch(handleError)
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
|
||||
if (creds && creds.user_id) {
|
||||
if (creds.session && !(await validateSession(creds.session))) {
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
|
||||
await logout().catch(handleError)
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
|
||||
credentials.value = null
|
||||
return
|
||||
}
|
||||
creds.user = await get_user(creds.user_id, 'bypass').catch(handleError)
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
}
|
||||
credentials.value = creds ?? null
|
||||
}
|
||||
|
||||
async function signIn(flow = 'sign-in') {
|
||||
async function signIn() {
|
||||
modrinthLoginFlowWaitModal.value.show()
|
||||
|
||||
try {
|
||||
await login(flow)
|
||||
await login()
|
||||
await fetchCredentials()
|
||||
} catch (error) {
|
||||
if (
|
||||
@@ -713,13 +699,6 @@ async function signIn(flow = 'sign-in') {
|
||||
}
|
||||
|
||||
async function logOut() {
|
||||
await performLogOut()
|
||||
}
|
||||
|
||||
async function performLogOut() {
|
||||
credentialsRefreshId++
|
||||
credentials.value = undefined
|
||||
|
||||
await logout().catch(handleError)
|
||||
await fetchCredentials()
|
||||
}
|
||||
@@ -842,34 +821,30 @@ function openServerInviteInviterProfile(inviterName) {
|
||||
}
|
||||
|
||||
async function handleLiveNotification(notification) {
|
||||
if (!notification?.body || notification.read) return
|
||||
if (await sharedInstanceInviteHandler.value?.handleNotification(notification)) return
|
||||
if (notification?.body?.type !== 'server_invite' || notification.read) return
|
||||
if (displayedServerInviteNotifications.has(notification.id)) return
|
||||
|
||||
if (notification.body.type === 'server_invite') {
|
||||
if (displayedServerInviteNotifications.has(notification.id)) return
|
||||
displayedServerInviteNotifications.add(notification.id)
|
||||
|
||||
displayedServerInviteNotifications.add(notification.id)
|
||||
const serverName =
|
||||
typeof notification.body.server_name === 'string' ? notification.body.server_name : 'a server'
|
||||
const inviterId = notification.body.invited_by
|
||||
const invitedBy =
|
||||
typeof inviterId === 'string' ? await get_user(inviterId, 'bypass').catch(() => null) : null
|
||||
|
||||
const serverName =
|
||||
typeof notification.body.server_name === 'string' ? notification.body.server_name : 'a server'
|
||||
const inviterId = notification.body.invited_by
|
||||
const invitedBy =
|
||||
typeof inviterId === 'string' ? await get_user(inviterId, 'bypass').catch(() => null) : null
|
||||
|
||||
addPopupNotification({
|
||||
title: serverName,
|
||||
autoCloseMs: null,
|
||||
toast: {
|
||||
type: 'server-invite',
|
||||
actorName: invitedBy?.username ?? null,
|
||||
actorAvatarUrl: invitedBy?.avatar_url ?? null,
|
||||
entityName: serverName,
|
||||
onAccept: () => acceptServerInviteNotification(notification),
|
||||
onDecline: () => declineServerInviteNotification(notification),
|
||||
onOpenActor: () => openServerInviteInviterProfile(invitedBy?.username ?? null),
|
||||
},
|
||||
})
|
||||
}
|
||||
addPopupNotification({
|
||||
title: serverName,
|
||||
autoCloseMs: null,
|
||||
toast: {
|
||||
type: 'server-invite',
|
||||
actorName: invitedBy?.username ?? null,
|
||||
actorAvatarUrl: invitedBy?.avatar_url ?? null,
|
||||
entityName: serverName,
|
||||
onAccept: () => acceptServerInviteNotification(notification),
|
||||
onDecline: () => declineServerInviteNotification(notification),
|
||||
onOpenActor: () => openServerInviteInviterProfile(invitedBy?.username ?? null),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async function handleCommand(e) {
|
||||
@@ -880,12 +855,13 @@ async function handleCommand(e) {
|
||||
if (e.path.endsWith('.mrpack')) {
|
||||
const location = { type: 'fromFile', path: e.path }
|
||||
const preview = await install_get_modpack_preview(location).catch(handleError)
|
||||
if (preview?.unknownFile) {
|
||||
if (preview?.unknownFile || preview?.externalFilesInModpack.length > 0) {
|
||||
const splitPath = e.path.split(/[\\/]/)
|
||||
const fileName = splitPath ? splitPath[splitPath.length - 1] : e.path
|
||||
unknownPackWarningModal.value?.show(
|
||||
() => install_create_modpack_instance(location).then(() => undefined),
|
||||
fileName,
|
||||
preview.externalFilesInModpack,
|
||||
)
|
||||
} else {
|
||||
await install_create_modpack_instance(location).catch(handleError)
|
||||
@@ -902,8 +878,6 @@ async function handleCommand(e) {
|
||||
} else {
|
||||
await run(e.id).catch(handleError)
|
||||
}
|
||||
} else if (e.event === 'InstallSharedInstanceInvite') {
|
||||
await sharedInstanceInviteHandler.value?.installFromInviteId(e.invite_id)
|
||||
} else if (e.event === 'InstallServer') {
|
||||
await router.push(`/project/${e.id}`)
|
||||
await playServerProject(e.id).catch(handleError)
|
||||
@@ -1494,12 +1468,6 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
>
|
||||
<PlusIcon />
|
||||
</NavButton>
|
||||
<NavButton
|
||||
v-tooltip.right="'Install from invite link'"
|
||||
:to="(event) => sharedInstanceInviteHandler?.showManualInviteLinkModal(event)"
|
||||
>
|
||||
<LinkIcon />
|
||||
</NavButton>
|
||||
<div class="flex flex-grow"></div>
|
||||
<NavButton
|
||||
v-tooltip.right="formatMessage(commonMessages.settingsLabel)"
|
||||
@@ -1769,9 +1737,8 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
@create-anyway="handleContentInstallModpackDuplicateCreateAnyway"
|
||||
@go-to-instance="handleContentInstallModpackDuplicateGoToInstance"
|
||||
/>
|
||||
<SharedInstanceInviteHandler ref="sharedInstanceInviteHandler" />
|
||||
<InstallToPlayModal ref="installToPlayModal" />
|
||||
<UpdateToPlayModal ref="updateToPlayModal" />
|
||||
<InstallToPlayModal ref="installToPlayModal" :show-external-warnings="false" />
|
||||
<UpdateToPlayModal ref="updateToPlayModal" :show-external-warnings="false" />
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -142,9 +142,7 @@ const unlisten = await process_listener((e) => {
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
checkProcess()
|
||||
})
|
||||
onMounted(() => checkProcess())
|
||||
onUnmounted(() => unlisten())
|
||||
</script>
|
||||
|
||||
|
||||
@@ -10,12 +10,18 @@ import {
|
||||
useRelativeTime,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import FriendsSection from '@/components/ui/friends/FriendsSection.vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { useFriends } from '@/composables/use-friends'
|
||||
import type { FriendWithUserData } from '@/helpers/friends.ts'
|
||||
import { friend_listener } from '@/helpers/events'
|
||||
import {
|
||||
add_friend,
|
||||
friends,
|
||||
type FriendWithUserData,
|
||||
remove_friend,
|
||||
transformFriends,
|
||||
} from '@/helpers/friends.ts'
|
||||
import type { ModrinthCredentials } from '@/helpers/mr_auth'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
@@ -29,23 +35,36 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const userCredentials = computed(() => props.credentials)
|
||||
const {
|
||||
friends: userFriends,
|
||||
loading,
|
||||
requestFriend,
|
||||
acceptFriend,
|
||||
removeFriend: removeFriendRecord,
|
||||
} = useFriends({
|
||||
currentUserId: () => userCredentials.value?.user_id,
|
||||
getCredentials: () => userCredentials.value,
|
||||
onError: handleError,
|
||||
})
|
||||
|
||||
const search = ref('')
|
||||
const friendInvitesModal = ref()
|
||||
|
||||
const username = ref('')
|
||||
const addFriendModal = ref()
|
||||
async function addFriendFromModal() {
|
||||
addFriendModal.value.hide()
|
||||
await add_friend(username.value).catch(handleError)
|
||||
username.value = ''
|
||||
await loadFriends()
|
||||
}
|
||||
|
||||
async function addFriend(friend: FriendWithUserData) {
|
||||
const id = friend.id === userCredentials.value?.user_id ? friend.friend_id : friend.id
|
||||
if (id) {
|
||||
await add_friend(id).catch(handleError)
|
||||
await loadFriends()
|
||||
}
|
||||
}
|
||||
|
||||
async function removeFriend(friend: FriendWithUserData) {
|
||||
const id = friend.id === userCredentials.value?.user_id ? friend.friend_id : friend.id
|
||||
if (id) {
|
||||
await remove_friend(id).catch(handleError)
|
||||
await loadFriends()
|
||||
}
|
||||
}
|
||||
|
||||
const userFriends = ref<FriendWithUserData[]>([])
|
||||
const sortedFriends = computed<FriendWithUserData[]>(() =>
|
||||
userFriends.value.slice().sort((a, b) => {
|
||||
if (a.last_updated === null && b.last_updated === null) {
|
||||
@@ -89,22 +108,42 @@ const incomingRequests = computed(() =>
|
||||
.sort((a, b) => b.created.diff(a.created)),
|
||||
)
|
||||
|
||||
function addFriendFromModal() {
|
||||
const target = username.value.trim()
|
||||
if (!target) return
|
||||
const loading = ref(true)
|
||||
async function loadFriends(timeout = false) {
|
||||
loading.value = timeout
|
||||
|
||||
addFriendModal.value.hide()
|
||||
requestFriend({ id: target, username: target })
|
||||
username.value = ''
|
||||
try {
|
||||
const friendsList = await friends()
|
||||
userFriends.value = await transformFriends(friendsList, userCredentials.value)
|
||||
loading.value = false
|
||||
} catch (e) {
|
||||
console.error('Error loading friends', e)
|
||||
if (timeout) {
|
||||
setTimeout(() => loadFriends(), 15 * 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addFriend(friend: FriendWithUserData) {
|
||||
acceptFriend(friend)
|
||||
}
|
||||
watch(
|
||||
userCredentials,
|
||||
() => {
|
||||
if (userCredentials.value === undefined) {
|
||||
userFriends.value = []
|
||||
loading.value = false
|
||||
} else if (userCredentials.value === null) {
|
||||
userFriends.value = []
|
||||
loading.value = false
|
||||
} else {
|
||||
loadFriends(true)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
function removeFriend(friend: FriendWithUserData) {
|
||||
removeFriendRecord(friend)
|
||||
}
|
||||
const unlisten = await friend_listener(() => loadFriends())
|
||||
onUnmounted(() => {
|
||||
unlisten()
|
||||
})
|
||||
|
||||
const messages = defineMessages({
|
||||
addFriend: {
|
||||
|
||||
@@ -1,108 +1,41 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.header)" :on-hide="reset">
|
||||
<div class="max-w-[31rem] flex flex-col gap-6">
|
||||
<Admonition
|
||||
type="warning"
|
||||
:header="formatMessage(messages.warningTitle)"
|
||||
:body="formatMessage(messages.warningBody)"
|
||||
/>
|
||||
<div v-if="fileName" class="overflow-x-auto whitespace-nowrap text-sm text-secondary">
|
||||
{{ fileName }}
|
||||
</div>
|
||||
<div>
|
||||
<p class="mt-0 leading-tight">
|
||||
{{ formatMessage(messages.body) }}
|
||||
</p>
|
||||
<p class="text-orange font-semibold mb-0 leading-tight">
|
||||
{{ formatMessage(messages.malwareStatement) }}
|
||||
</p>
|
||||
</div>
|
||||
<Checkbox v-model="dontShowAgain" :label="formatMessage(messages.dontShowAgain)" />
|
||||
<div class="flex gap-2 justify-end">
|
||||
<ButtonStyled type="outlined">
|
||||
<button @click="cancel">
|
||||
<XIcon />
|
||||
{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="orange">
|
||||
<button :disabled="isProceeding" @click="proceed">
|
||||
<SpinnerIcon v-if="isProceeding" class="animate-spin" />
|
||||
<CircleArrowRightIcon v-else />
|
||||
{{ formatMessage(messages.installAnyway) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<UnknownFileWarningModal
|
||||
ref="modal"
|
||||
:mode="externalFilesInModpack.length > 0 ? 'modpack' : 'mod'"
|
||||
:file-name="fileName"
|
||||
:external-files-in-modpack="externalFilesInModpack"
|
||||
@cancel="reset"
|
||||
@continue="proceed"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { CircleArrowRightIcon, SpinnerIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
NewModal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { UnknownFileWarningModal } from '@modrinth/ui'
|
||||
import { ref, useTemplateRef } from 'vue'
|
||||
|
||||
import { get as getSettings, set as setSettings } from '@/helpers/settings'
|
||||
import { useTheming } from '@/store/state'
|
||||
import type { FeatureFlag } from '@/store/theme.ts'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const themeStore = useTheming()
|
||||
const skipUnknownPackWarningFeatureFlag = 'skip_unknown_pack_warning' as FeatureFlag
|
||||
|
||||
const dontShowAgain = ref(false)
|
||||
const modal = useTemplateRef('modal')
|
||||
const onProceed = ref<() => Promise<void>>()
|
||||
const isProceeding = ref(false)
|
||||
const fileName = ref('')
|
||||
const externalFilesInModpack = ref<string[]>([])
|
||||
|
||||
const messages = defineMessages({
|
||||
header: {
|
||||
id: 'unknown-pack-warning-modal.header',
|
||||
defaultMessage: 'Confirm installation',
|
||||
},
|
||||
warningTitle: {
|
||||
id: 'unknown-pack-warning-modal.warning.title',
|
||||
defaultMessage: 'Unknown file warning',
|
||||
},
|
||||
warningBody: {
|
||||
id: 'unknown-pack-warning-modal.warning.body',
|
||||
defaultMessage: `We couldn't find this file on Modrinth. We strongly recommend only installing files from sources you trust.`,
|
||||
},
|
||||
body: {
|
||||
id: 'unknown-pack-warning-modal.body',
|
||||
defaultMessage: `A file is only reviewed if it’s uploaded to Modrinth, regardless of its file format (including .mrpack).`,
|
||||
},
|
||||
malwareStatement: {
|
||||
id: 'unknown-pack-warning-modal.malware-statement',
|
||||
defaultMessage: `Malware is often distributed through modpack files by sharing them on platforms like Discord.`,
|
||||
},
|
||||
dontShowAgain: {
|
||||
id: 'unknown-pack-warning-modal.dont-show-again',
|
||||
defaultMessage: `Don't show this warning again`,
|
||||
},
|
||||
installAnyway: {
|
||||
id: 'unknown-pack-warning-modal.install-anyway',
|
||||
defaultMessage: `Install anyway`,
|
||||
},
|
||||
})
|
||||
|
||||
function show(createInstance: () => Promise<void>, selectedFileName = '') {
|
||||
function show(
|
||||
createInstance: () => Promise<void>,
|
||||
selectedFileName = '',
|
||||
selectedExternalFiles: string[] = [],
|
||||
) {
|
||||
onProceed.value = createInstance
|
||||
fileName.value = selectedFileName
|
||||
dontShowAgain.value = false
|
||||
externalFilesInModpack.value = selectedExternalFiles
|
||||
|
||||
if (themeStore.getFeatureFlag(skipUnknownPackWarningFeatureFlag)) {
|
||||
// noinspection ES6MissingAwait
|
||||
createInstance()
|
||||
void createInstance()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -112,18 +45,11 @@ function show(createInstance: () => Promise<void>, selectedFileName = '') {
|
||||
function reset() {
|
||||
onProceed.value = undefined
|
||||
fileName.value = ''
|
||||
externalFilesInModpack.value = []
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
modal.value?.hide()
|
||||
}
|
||||
|
||||
async function proceed() {
|
||||
if (!onProceed.value) {
|
||||
return
|
||||
}
|
||||
|
||||
if (dontShowAgain.value) {
|
||||
async function proceed(dontShowAgain: boolean) {
|
||||
if (dontShowAgain) {
|
||||
themeStore.featureFlags[skipUnknownPackWarningFeatureFlag] = true
|
||||
const settings = await getSettings()
|
||||
settings.feature_flags[skipUnknownPackWarningFeatureFlag] = true
|
||||
@@ -131,9 +57,8 @@ async function proceed() {
|
||||
}
|
||||
|
||||
const createInstance = onProceed.value
|
||||
modal.value?.hide()
|
||||
// noinspection ES6MissingAwait
|
||||
createInstance()
|
||||
reset()
|
||||
if (createInstance) void createInstance()
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
<template>
|
||||
<StackedAdmonitions v-bind="$attrs" :items="stackItems" class="w-full">
|
||||
<template #item="{ item, dismissible }">
|
||||
<InstanceAdmonitionsSharedInstanceStale
|
||||
v-if="item.kind === 'shared-instance-stale'"
|
||||
:instance="instance"
|
||||
@published="emit('published')"
|
||||
/>
|
||||
<InstanceAdmonitionsSharedInstanceWrongAccount
|
||||
v-else-if="item.kind === 'shared-instance-wrong-account'"
|
||||
:expected-user-id="sharedInstanceExpectedUserId"
|
||||
:role="sharedInstanceRole"
|
||||
:signed-out="sharedInstanceSignedOut"
|
||||
/>
|
||||
<InstanceAdmonitionsSharedInstanceUnavailable
|
||||
v-else-if="item.kind === 'shared-instance-unavailable'"
|
||||
:reason="sharedInstanceUnavailableReason"
|
||||
:manager="sharedInstanceUnavailableManager"
|
||||
:dismissible="dismissible"
|
||||
@dismiss="sharedInstanceUnavailableDismissed = true"
|
||||
/>
|
||||
</template>
|
||||
</StackedAdmonitions>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { StackedAdmonitions } from '@modrinth/ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import type { SharedInstanceUnavailableReason } from '@/helpers/install'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
import InstanceAdmonitionsSharedInstanceStale from './instance-admonitions-shared-instance-stale.vue'
|
||||
import InstanceAdmonitionsSharedInstanceUnavailable from './instance-admonitions-shared-instance-unavailable.vue'
|
||||
import InstanceAdmonitionsSharedInstanceWrongAccount from './instance-admonitions-shared-instance-wrong-account.vue'
|
||||
import type { InstanceAdmonitionItem, SharedInstanceRole } from './types'
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = defineProps<{
|
||||
instance: GameInstance
|
||||
sharedInstanceUnavailableReason?: SharedInstanceUnavailableReason | null
|
||||
sharedInstanceUnavailableManager?: string | null
|
||||
sharedInstanceWrongAccount?: boolean
|
||||
sharedInstanceExpectedUserId?: string | null
|
||||
sharedInstanceRole?: SharedInstanceRole | null
|
||||
sharedInstanceSignedOut?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
published: []
|
||||
}>()
|
||||
|
||||
const sharedInstanceWrongAccount = computed(() => props.sharedInstanceWrongAccount ?? false)
|
||||
const sharedInstanceUnavailableDismissed = ref(false)
|
||||
const showSharedInstancePublishAdmonition = computed(
|
||||
() =>
|
||||
!sharedInstanceWrongAccount.value &&
|
||||
props.instance.install_stage === 'installed' &&
|
||||
props.instance.shared_instance?.role === 'owner' &&
|
||||
props.instance.shared_instance.status === 'stale',
|
||||
)
|
||||
|
||||
const stackItems = computed<InstanceAdmonitionItem[]>(() => {
|
||||
const items: InstanceAdmonitionItem[] = []
|
||||
|
||||
if (sharedInstanceWrongAccount.value) {
|
||||
items.push({
|
||||
id: 'shared-instance-wrong-account',
|
||||
type: 'warning',
|
||||
dismissible: false,
|
||||
kind: 'shared-instance-wrong-account',
|
||||
})
|
||||
}
|
||||
|
||||
if (props.sharedInstanceUnavailableReason && !sharedInstanceUnavailableDismissed.value) {
|
||||
items.push({
|
||||
id: 'shared-instance-unavailable',
|
||||
type: 'warning',
|
||||
dismissible: true,
|
||||
kind: 'shared-instance-unavailable',
|
||||
})
|
||||
}
|
||||
|
||||
if (showSharedInstancePublishAdmonition.value) {
|
||||
items.push({
|
||||
id: 'shared-instance-stale',
|
||||
type: 'warning',
|
||||
dismissible: false,
|
||||
kind: 'shared-instance-stale',
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
watch(
|
||||
() => [props.instance.id, props.sharedInstanceUnavailableReason],
|
||||
() => {
|
||||
sharedInstanceUnavailableDismissed.value = false
|
||||
},
|
||||
)
|
||||
</script>
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
import { defineMessages } from '@modrinth/ui'
|
||||
|
||||
export const instanceAdmonitionsMessages = defineMessages({
|
||||
sharedInstanceChangesHeader: {
|
||||
id: 'app.instance.admonitions.shared-instance.changes-header',
|
||||
defaultMessage: "Your changes haven't been shared yet",
|
||||
},
|
||||
sharedInstanceChangesBody: {
|
||||
id: 'app.instance.admonitions.shared-instance.changes-body',
|
||||
defaultMessage: "Your local instance is ahead of the users you've shared it with.",
|
||||
},
|
||||
sharedInstancePublishButton: {
|
||||
id: 'app.instance.admonitions.shared-instance.publish-button',
|
||||
defaultMessage: 'Push update',
|
||||
},
|
||||
sharedInstancePublishingButton: {
|
||||
id: 'app.instance.admonitions.shared-instance.publishing-button',
|
||||
defaultMessage: 'Pushing...',
|
||||
},
|
||||
sharedInstanceReviewingButton: {
|
||||
id: 'app.instance.admonitions.shared-instance.reviewing-button',
|
||||
defaultMessage: 'Reviewing...',
|
||||
},
|
||||
sharedInstanceReviewHeader: {
|
||||
id: 'app.instance.admonitions.shared-instance.review-header',
|
||||
defaultMessage: 'Review changes',
|
||||
},
|
||||
sharedInstanceReviewAdmonitionHeader: {
|
||||
id: 'app.instance.admonitions.shared-instance.review-admonition-header',
|
||||
defaultMessage: 'Push update',
|
||||
},
|
||||
sharedInstanceReviewDescription: {
|
||||
id: 'app.instance.admonitions.shared-instance.review-description',
|
||||
defaultMessage:
|
||||
'Review the content changes that will be shared with everyone using this instance.',
|
||||
},
|
||||
sharedInstanceAddedLabel: {
|
||||
id: 'app.instance.admonitions.shared-instance.added-label',
|
||||
defaultMessage: 'Added',
|
||||
},
|
||||
sharedInstanceRemovedLabel: {
|
||||
id: 'app.instance.admonitions.shared-instance.removed-label',
|
||||
defaultMessage: 'Removed',
|
||||
},
|
||||
sharedInstanceWrongAccountHeader: {
|
||||
id: 'app.instance.shared-instance-wrong-account.warning-header',
|
||||
defaultMessage: 'You are using the wrong Modrinth account',
|
||||
},
|
||||
sharedInstanceSignedOutHeader: {
|
||||
id: 'app.instance.shared-instance-wrong-account.signed-out-header',
|
||||
defaultMessage: 'You need to sign in to Modrinth',
|
||||
},
|
||||
sharedInstanceWrongAccountSignInAs: {
|
||||
id: 'app.instance.shared-instance-wrong-account.sign-in-as-label',
|
||||
defaultMessage: 'Sign in as',
|
||||
},
|
||||
sharedInstanceWrongAccountUserBody: {
|
||||
id: 'app.instance.shared-instance-wrong-account.user-admonition-body-v2',
|
||||
defaultMessage: 'to receive updates for this shared instance.',
|
||||
},
|
||||
sharedInstanceWrongAccountOwnerBody: {
|
||||
id: 'app.instance.shared-instance-wrong-account.owner-admonition-body-v2',
|
||||
defaultMessage: "to manage this shared instance. You won't be able to push updates to users.",
|
||||
},
|
||||
sharedInstanceWrongAccountFallbackUsername: {
|
||||
id: 'app.instance.shared-instance-wrong-account.fallback-username',
|
||||
defaultMessage: 'the linked account',
|
||||
},
|
||||
})
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
<template>
|
||||
<Admonition
|
||||
type="warning"
|
||||
inline-actions
|
||||
:header="formatMessage(messages.sharedInstanceChangesHeader)"
|
||||
>
|
||||
{{ formatMessage(messages.sharedInstanceChangesBody) }}
|
||||
<template #actions>
|
||||
<ButtonStyled color="orange">
|
||||
<button class="!h-10" :disabled="isPublishButtonDisabled" @click="reviewChanges">
|
||||
<UploadIcon aria-hidden="true" />
|
||||
{{
|
||||
isPublishing
|
||||
? formatMessage(messages.sharedInstancePublishingButton)
|
||||
: isReviewingPublish
|
||||
? formatMessage(messages.sharedInstanceReviewingButton)
|
||||
: formatMessage(messages.sharedInstancePublishButton)
|
||||
}}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</Admonition>
|
||||
|
||||
<ContentDiffModal
|
||||
ref="publishReviewModal"
|
||||
:header="formatMessage(messages.sharedInstanceReviewHeader)"
|
||||
:admonition-header="formatMessage(messages.sharedInstanceReviewAdmonitionHeader)"
|
||||
:description="formatMessage(messages.sharedInstanceReviewDescription)"
|
||||
:diffs="publishDiffs"
|
||||
:confirm-label="formatMessage(messages.sharedInstancePublishButton)"
|
||||
:confirm-icon="UploadIcon"
|
||||
:added-label="formatMessage(messages.sharedInstanceAddedLabel)"
|
||||
:removed-label="formatMessage(messages.sharedInstanceRemovedLabel)"
|
||||
@confirm="publishChanges"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UploadIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
ButtonStyled,
|
||||
type ContentDiffItem,
|
||||
ContentDiffModal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import {
|
||||
getSharedInstanceUnavailableReason,
|
||||
isSharedInstanceUnavailableError,
|
||||
} from '@/helpers/install'
|
||||
import { get_shared_instance_publish_preview, publish_shared_instance } from '@/helpers/instance'
|
||||
import { useSharedInstanceErrors } from '@/helpers/shared-instance-errors'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
import { instanceAdmonitionsMessages as messages } from './instance-admonitions-messages'
|
||||
|
||||
const props = defineProps<{
|
||||
instance: GameInstance
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
published: []
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const { notifySharedInstanceError, notifySharedInstanceUnavailable } = useSharedInstanceErrors()
|
||||
const isPublishing = ref(false)
|
||||
const isReviewingPublish = ref(false)
|
||||
const publishReviewModal = ref<InstanceType<typeof ContentDiffModal>>()
|
||||
const publishDiffs = ref<ContentDiffItem[]>([])
|
||||
|
||||
const isPublishButtonDisabled = computed(() => isPublishing.value || isReviewingPublish.value)
|
||||
|
||||
async function reviewChanges(e?: MouseEvent) {
|
||||
if (isPublishButtonDisabled.value) return
|
||||
|
||||
isReviewingPublish.value = true
|
||||
try {
|
||||
const preview = await get_shared_instance_publish_preview(props.instance.id)
|
||||
if (!preview) {
|
||||
notifySharedInstanceUnavailable()
|
||||
emit('published')
|
||||
return
|
||||
}
|
||||
if (preview.diffs.length === 0) {
|
||||
emit('published')
|
||||
return
|
||||
}
|
||||
|
||||
publishDiffs.value = preview.diffs.map((diff) => ({
|
||||
type: diff.type,
|
||||
projectName: diff.projectName ?? undefined,
|
||||
fileName: diff.fileName ?? undefined,
|
||||
currentVersionName: diff.currentVersionName ?? undefined,
|
||||
newVersionName: diff.newVersionName ?? undefined,
|
||||
disabled: diff.disabled,
|
||||
}))
|
||||
publishReviewModal.value?.show(e)
|
||||
} catch (err) {
|
||||
if (isSharedInstanceUnavailableError(err)) {
|
||||
notifySharedInstanceUnavailable(getSharedInstanceUnavailableReason(err))
|
||||
emit('published')
|
||||
return
|
||||
}
|
||||
|
||||
notifySharedInstanceError(err)
|
||||
} finally {
|
||||
isReviewingPublish.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function publishChanges() {
|
||||
if (isPublishing.value) return
|
||||
|
||||
isPublishing.value = true
|
||||
try {
|
||||
await publish_shared_instance(props.instance.id)
|
||||
emit('published')
|
||||
} catch (err) {
|
||||
if (isSharedInstanceUnavailableError(err)) {
|
||||
notifySharedInstanceUnavailable(getSharedInstanceUnavailableReason(err))
|
||||
emit('published')
|
||||
return
|
||||
}
|
||||
|
||||
notifySharedInstanceError(err)
|
||||
} finally {
|
||||
isPublishing.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
<template>
|
||||
<Admonition
|
||||
type="warning"
|
||||
:header="formatMessage(sharedInstanceErrorMessages.unavailableTitle)"
|
||||
:dismissible="dismissible"
|
||||
@dismiss="emit('dismiss')"
|
||||
>
|
||||
{{ formatSharedInstanceUnavailable(reason ?? null, manager) }}
|
||||
</Admonition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Admonition, useVIntl } from '@modrinth/ui'
|
||||
|
||||
import type { SharedInstanceUnavailableReason } from '@/helpers/install'
|
||||
import {
|
||||
sharedInstanceErrorMessages,
|
||||
useSharedInstanceErrors,
|
||||
} from '@/helpers/shared-instance-errors'
|
||||
|
||||
defineProps<{
|
||||
reason?: SharedInstanceUnavailableReason | null
|
||||
manager?: string | null
|
||||
dismissible?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
dismiss: []
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const { formatSharedInstanceUnavailable } = useSharedInstanceErrors()
|
||||
</script>
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
<template>
|
||||
<Admonition type="warning" :header="formatMessage(headerMessage)">
|
||||
<span class="flex flex-wrap items-center gap-x-1.5 gap-y-1">
|
||||
<span>{{ formatMessage(messages.sharedInstanceWrongAccountSignInAs) }}</span>
|
||||
<span
|
||||
v-if="sharedInstanceExpectedUser"
|
||||
class="inline-flex max-w-full min-w-0 items-center gap-1.5 align-middle font-semibold text-contrast"
|
||||
>
|
||||
<Avatar
|
||||
:src="sharedInstanceExpectedUser.avatarUrl"
|
||||
:alt="sharedInstanceExpectedUsername"
|
||||
:tint-by="sharedInstanceExpectedUser.tintBy"
|
||||
size="20px"
|
||||
circle
|
||||
no-shadow
|
||||
/>
|
||||
<span class="min-w-0 truncate">{{ sharedInstanceExpectedUsername }}</span>
|
||||
</span>
|
||||
<span v-else class="font-semibold">{{ sharedInstanceExpectedUsername }}</span>
|
||||
<span>{{ formatMessage(bodyMessage) }}</span>
|
||||
</span>
|
||||
</Admonition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Admonition, Avatar, useVIntl } from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { get_user } from '@/helpers/cache'
|
||||
|
||||
import { instanceAdmonitionsMessages as messages } from './instance-admonitions-messages'
|
||||
import type { SharedInstanceRole } from './types'
|
||||
|
||||
const props = defineProps<{
|
||||
expectedUserId?: string | null
|
||||
role?: SharedInstanceRole | null
|
||||
signedOut?: boolean
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const expectedUserId = computed(() => props.expectedUserId ?? null)
|
||||
const expectedUserQuery = useQuery({
|
||||
queryKey: computed(() => ['user', expectedUserId.value]),
|
||||
queryFn: async () => {
|
||||
if (!expectedUserId.value) return null
|
||||
|
||||
return await get_user(expectedUserId.value, 'bypass').catch(() => null)
|
||||
},
|
||||
enabled: () => !!expectedUserId.value,
|
||||
staleTime: 30_000,
|
||||
})
|
||||
const sharedInstanceExpectedUser = computed(() => {
|
||||
const user = expectedUserQuery.data.value
|
||||
if (!user) return null
|
||||
|
||||
return {
|
||||
username: user.username,
|
||||
avatarUrl: user.avatar_url ?? undefined,
|
||||
tintBy: user.id,
|
||||
}
|
||||
})
|
||||
const sharedInstanceExpectedUsername = computed(
|
||||
() =>
|
||||
sharedInstanceExpectedUser.value?.username ||
|
||||
formatMessage(messages.sharedInstanceWrongAccountFallbackUsername),
|
||||
)
|
||||
const headerMessage = computed(() =>
|
||||
props.signedOut
|
||||
? messages.sharedInstanceSignedOutHeader
|
||||
: messages.sharedInstanceWrongAccountHeader,
|
||||
)
|
||||
const bodyMessage = computed(() =>
|
||||
props.role === 'owner'
|
||||
? messages.sharedInstanceWrongAccountOwnerBody
|
||||
: messages.sharedInstanceWrongAccountUserBody,
|
||||
)
|
||||
</script>
|
||||
@@ -1,12 +0,0 @@
|
||||
import type { StackedAdmonitionItem } from '@modrinth/ui'
|
||||
|
||||
export type InstanceAdmonitionKind =
|
||||
| 'shared-instance-stale'
|
||||
| 'shared-instance-unavailable'
|
||||
| 'shared-instance-wrong-account'
|
||||
|
||||
export type InstanceAdmonitionItem = StackedAdmonitionItem & {
|
||||
kind: InstanceAdmonitionKind
|
||||
}
|
||||
|
||||
export type SharedInstanceRole = 'owner' | 'member'
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
injectFilePicker,
|
||||
injectNotificationManager,
|
||||
InstallationSettingsLayout,
|
||||
provideAppBackup,
|
||||
provideInstallationSettings,
|
||||
useDebugLogger,
|
||||
useVIntl,
|
||||
@@ -15,26 +16,24 @@ import type { GameVersionTag, PlatformTag } from '@modrinth/utils'
|
||||
import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import SharedInstanceInstallationSettingsControls from '@/components/ui/shared-instances/SharedInstanceInstallationSettingsControls.vue'
|
||||
import { useManagedContentPolicy } from '@/composables/instances/use-managed-content-policy'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project_versions, get_version } from '@/helpers/cache'
|
||||
import {
|
||||
install_duplicate_instance,
|
||||
install_existing_instance,
|
||||
install_pack_to_existing_instance,
|
||||
installJobInstanceId,
|
||||
wait_for_install_job,
|
||||
} from '@/helpers/install'
|
||||
import {
|
||||
edit,
|
||||
get_linked_modpack_info,
|
||||
unlink_shared_instance,
|
||||
unpublish_shared_instance,
|
||||
list,
|
||||
update_managed_modrinth_version,
|
||||
update_repair_modrinth,
|
||||
} from '@/helpers/instance'
|
||||
import { get_loader_versions } from '@/helpers/metadata'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import { provideInstanceBackup } from '@/providers/instance-backup'
|
||||
import { injectInstanceSettings } from '@/providers/instance-settings'
|
||||
import { useTheming } from '@/store/state'
|
||||
|
||||
@@ -48,7 +47,6 @@ const debug = useDebugLogger('AppInstallationSettings')
|
||||
const themeStore = useTheming()
|
||||
|
||||
const { instance, offline, isMinecraftServer, onUnlinked, closeModal } = injectInstanceSettings()
|
||||
const managedContentPolicy = useManagedContentPolicy(instance)
|
||||
const skipNonEssentialWarnings = computed(() =>
|
||||
themeStore.getFeatureFlag('skip_non_essential_warnings'),
|
||||
)
|
||||
@@ -113,15 +111,9 @@ debug('metadata queries configured', {
|
||||
const isModrinthLinkedModpack = computed(
|
||||
() =>
|
||||
instance.value.link?.type === 'modrinth_modpack' ||
|
||||
instance.value.link?.type === 'server_project_modpack' ||
|
||||
(instance.value.link?.type === 'shared_instance' &&
|
||||
!!instance.value.link.modpack_project_id &&
|
||||
!!instance.value.link.modpack_version_id),
|
||||
instance.value.link?.type === 'server_project_modpack',
|
||||
)
|
||||
const isImportedModpack = computed(() => instance.value.link?.type === 'imported_modpack')
|
||||
const isSharedInstanceManagedModpack = managedContentPolicy.isManagedModpack
|
||||
const canUnpublishSharedInstance = managedContentPolicy.canUnpublish
|
||||
const canUnlinkSharedInstance = managedContentPolicy.canUnlink
|
||||
|
||||
const modpackInfoQuery = useQuery({
|
||||
queryKey: computed(() => ['linkedModpackInfo', instance.value.id]),
|
||||
@@ -132,36 +124,6 @@ const modpackInfo = modpackInfoQuery.data
|
||||
|
||||
const repairing = ref(false)
|
||||
const reinstalling = ref(false)
|
||||
const unpublishingSharedInstance = ref(false)
|
||||
const unlinkingSharedInstance = ref(false)
|
||||
|
||||
async function unpublishSharedInstance() {
|
||||
unpublishingSharedInstance.value = true
|
||||
try {
|
||||
await unpublish_shared_instance(instance.value.id)
|
||||
await queryClient.invalidateQueries({ queryKey: ['sharedInstanceUsers', instance.value.id] })
|
||||
await queryClient.invalidateQueries({ queryKey: ['linkedModpackInfo', instance.value.id] })
|
||||
onUnlinked()
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
} finally {
|
||||
unpublishingSharedInstance.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function unlinkSharedInstance() {
|
||||
unlinkingSharedInstance.value = true
|
||||
try {
|
||||
await unlink_shared_instance(instance.value.id)
|
||||
await queryClient.invalidateQueries({ queryKey: ['sharedInstanceUsers', instance.value.id] })
|
||||
await queryClient.invalidateQueries({ queryKey: ['linkedModpackInfo', instance.value.id] })
|
||||
onUnlinked()
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
} finally {
|
||||
unlinkingSharedInstance.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
loaderVersion: {
|
||||
@@ -200,7 +162,27 @@ async function installLocalModpackFromPicker() {
|
||||
return !!completed
|
||||
}
|
||||
|
||||
provideInstanceBackup(instance)
|
||||
provideAppBackup({
|
||||
async createBackup() {
|
||||
debug('createBackup: start', {
|
||||
instanceId: instance.value.id,
|
||||
instanceName: instance.value.name,
|
||||
})
|
||||
const allInstances = await list()
|
||||
const prefix = `${instance.value.name} - Backup #`
|
||||
const existingNums = allInstances
|
||||
.filter((p) => p.name.startsWith(prefix))
|
||||
.map((p) => parseInt(p.name.slice(prefix.length), 10))
|
||||
.filter((n) => !isNaN(n))
|
||||
const nextNum = existingNums.length > 0 ? Math.max(...existingNums) + 1 : 1
|
||||
const job = await install_duplicate_instance(instance.value.id)
|
||||
const newInstanceId = installJobInstanceId(job)
|
||||
if (newInstanceId) {
|
||||
await edit(newInstanceId, { name: `${prefix}${nextNum}` })
|
||||
}
|
||||
debug('createBackup: done', { newInstanceId, backupName: `${prefix}${nextNum}` })
|
||||
},
|
||||
})
|
||||
|
||||
provideInstallationSettings({
|
||||
closeSettings: closeModal,
|
||||
@@ -226,19 +208,12 @@ provideInstallationSettings({
|
||||
}
|
||||
return rows
|
||||
}),
|
||||
isLinked: computed(
|
||||
() =>
|
||||
isModrinthLinkedModpack.value ||
|
||||
isImportedModpack.value ||
|
||||
isSharedInstanceManagedModpack.value,
|
||||
),
|
||||
isLinked: computed(() => isModrinthLinkedModpack.value || isImportedModpack.value),
|
||||
isBusy: computed(
|
||||
() =>
|
||||
instance.value.install_stage !== 'installed' ||
|
||||
repairing.value ||
|
||||
reinstalling.value ||
|
||||
unlinkingSharedInstance.value ||
|
||||
unpublishingSharedInstance.value ||
|
||||
!!offline,
|
||||
),
|
||||
skipNonEssentialWarnings,
|
||||
@@ -477,38 +452,14 @@ provideInstallationSettings({
|
||||
isServer: false,
|
||||
isApp: true,
|
||||
showModpackVersionActions: computed(
|
||||
() =>
|
||||
isModrinthLinkedModpack.value &&
|
||||
!isMinecraftServer.value &&
|
||||
!isSharedInstanceManagedModpack.value,
|
||||
() => isModrinthLinkedModpack.value && !isMinecraftServer.value,
|
||||
),
|
||||
isLocalFile: isImportedModpack,
|
||||
isManagedModpack: isSharedInstanceManagedModpack,
|
||||
managedModpackWarning: managedContentPolicy.managedModpackWarning,
|
||||
repairing,
|
||||
reinstalling,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<InstallationSettingsLayout>
|
||||
<template #extra>
|
||||
<SharedInstanceInstallationSettingsControls
|
||||
:can-unpublish="canUnpublishSharedInstance"
|
||||
:can-unlink="canUnlinkSharedInstance"
|
||||
:busy="
|
||||
instance.install_stage !== 'installed' ||
|
||||
repairing ||
|
||||
reinstalling ||
|
||||
unpublishingSharedInstance ||
|
||||
unlinkingSharedInstance ||
|
||||
!!offline
|
||||
"
|
||||
:unpublishing="unpublishingSharedInstance"
|
||||
:unlinking="unlinkingSharedInstance"
|
||||
:unpublish="unpublishSharedInstance"
|
||||
:unlink="unlinkSharedInstance"
|
||||
/>
|
||||
</template>
|
||||
</InstallationSettingsLayout>
|
||||
<InstallationSettingsLayout />
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.installToPlay)" :closable="true">
|
||||
<div v-if="requiredContentProject" class="flex flex-col gap-6 max-w-[500px]">
|
||||
<Admonition type="info" :header="formatMessage(messages.contentRequired)">
|
||||
{{ formatMessage(messages.serverRequiresMods) }}
|
||||
</Admonition>
|
||||
<NewModal
|
||||
ref="modal"
|
||||
:header="formatMessage(messages.installToPlay)"
|
||||
:closable="true"
|
||||
:on-hide="show_ads_window"
|
||||
max-width="640px"
|
||||
width="640px"
|
||||
>
|
||||
<div v-if="requiredContentProject" class="flex w-full flex-col gap-6">
|
||||
<p class="m-0 text-primary">
|
||||
{{ formatMessage(messages.inviteWarning) }}
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="font-semibold text-contrast">{{
|
||||
formatMessage(messages.requiredModpack)
|
||||
}}</span>
|
||||
<div class="flex flex-col gap-2.5">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-semibold text-contrast">
|
||||
{{ formatMessage(messages.sharedInstance) }}
|
||||
</span>
|
||||
|
||||
<ButtonStyled type="transparent">
|
||||
<button @click="openViewContents">
|
||||
@@ -19,14 +26,16 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-3 rounded-xl bg-surface-2 p-3">
|
||||
<div class="flex items-center gap-3 rounded-2xl bg-surface-2 p-3">
|
||||
<Avatar
|
||||
:src="requiredContentProject.icon_url"
|
||||
:alt="requiredContentProject.title"
|
||||
size="48px"
|
||||
size="56px"
|
||||
no-shadow
|
||||
class="!rounded-2xl"
|
||||
/>
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="font-semibold text-contrast">
|
||||
<div class="flex min-w-0 flex-col gap-0.5">
|
||||
<span class="truncate font-semibold text-contrast">
|
||||
<template v-if="usingCustomModpack && modpackVersion">
|
||||
{{ modpackVersion.name }}
|
||||
</template>
|
||||
@@ -34,7 +43,7 @@
|
||||
{{ requiredContentProject.title }}
|
||||
</template>
|
||||
</span>
|
||||
<span class="text-sm text-secondary">
|
||||
<span class="truncate text-sm font-medium text-secondary">
|
||||
{{ loaderDisplay }} {{ requiredContentProject.game_versions?.[0] }}
|
||||
<template v-if="modCount">
|
||||
· {{ formatMessage(messages.modCount, { count: modCount }) }}
|
||||
@@ -43,24 +52,105 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #actions>
|
||||
<div class="flex justify-end gap-2">
|
||||
<ButtonStyled>
|
||||
<button @click="handleDecline">
|
||||
<XIcon />
|
||||
{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button @click="handleAccept">
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(messages.installButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<Admonition
|
||||
v-if="hasExternalFiles"
|
||||
type="warning"
|
||||
:header="formatMessage(messages.unknownFilesWarning)"
|
||||
>
|
||||
{{ formatMessage(messages.unknownFilesDescription) }}
|
||||
</Admonition>
|
||||
|
||||
<div v-if="hasExternalFiles" class="relative w-full">
|
||||
<div
|
||||
ref="externalFileTable"
|
||||
class="max-h-[242px] overflow-y-auto rounded-2xl"
|
||||
@scroll="checkTableScrollState"
|
||||
>
|
||||
<Table
|
||||
:columns="externalFileColumns"
|
||||
:data="externalFileRows"
|
||||
row-key="id"
|
||||
virtualized
|
||||
:virtual-row-height="48"
|
||||
class="shadow-sm"
|
||||
>
|
||||
<template #cell-name="{ value }">
|
||||
<span class="block truncate" :title="String(value)">{{ value }}</span>
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-2"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-2"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showTableTopFade"
|
||||
class="pointer-events-none absolute left-0 right-0 top-0 z-10 h-2 bg-gradient-to-b from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-2"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-2"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showTableBottomFade"
|
||||
class="pointer-events-none absolute bottom-0 left-0 right-0 z-10 h-2 bg-gradient-to-t from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<p v-if="hasExternalFiles" class="m-0 text-primary">
|
||||
{{ formatMessage(messages.reviewedFiles) }}
|
||||
</p>
|
||||
|
||||
<div class="flex w-full items-center justify-between gap-2">
|
||||
<ButtonStyled type="transparent" color="red">
|
||||
<button @click="handleReport">
|
||||
<ReportIcon />
|
||||
{{ formatMessage(commonMessages.reportButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<template v-if="hasExternalFiles">
|
||||
<ButtonStyled type="transparent" color="orange">
|
||||
<button @click="handleAccept">
|
||||
{{ formatMessage(messages.installAnyway) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button @click="handleDecline">
|
||||
<BanIcon />
|
||||
{{ formatMessage(messages.dontInstall) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
<template v-else>
|
||||
<ButtonStyled>
|
||||
<button @click="handleDecline">
|
||||
<XIcon />
|
||||
{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button @click="handleAccept">
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(messages.installButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
|
||||
<ModpackContentModal
|
||||
@@ -72,33 +162,56 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { DownloadIcon, EyeIcon, XIcon } from '@modrinth/assets'
|
||||
import type { ContentItem } from '@modrinth/ui'
|
||||
import { BanIcon, DownloadIcon, EyeIcon, ReportIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
type ContentItem,
|
||||
defineMessages,
|
||||
formatLoader,
|
||||
ModpackContentModal,
|
||||
NewModal,
|
||||
Table,
|
||||
type TableColumn,
|
||||
useScrollIndicator,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
|
||||
import { hide_ads_window, show_ads_window } from '@/helpers/ads'
|
||||
import { get_project, get_project_many, get_version, get_version_many } from '@/helpers/cache.js'
|
||||
import { injectServerInstall } from '@/providers/server-install'
|
||||
|
||||
type ExternalFileColumn = 'name'
|
||||
type ExternalFileRow = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modpackVersionId = ref<string | null>(null)
|
||||
const modpackVersion = ref<Labrinth.Versions.v2.Version | null>(null)
|
||||
const project = ref<Labrinth.Projects.v3.Project | null>(null)
|
||||
const requiredContentProject = ref<Labrinth.Projects.v2.Project | null>(null)
|
||||
const externalFiles = ref<string[]>([])
|
||||
const externalFileTable = ref<HTMLElement | null>(null)
|
||||
const onInstallComplete = ref<() => void>(() => {})
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<{
|
||||
showExternalWarnings?: boolean
|
||||
}>()
|
||||
|
||||
const { installServerProject, startInstallingServer, stopInstallingServer } = injectServerInstall()
|
||||
const {
|
||||
showTopFade: showTableTopFade,
|
||||
showBottomFade: showTableBottomFade,
|
||||
checkScrollState: checkTableScrollState,
|
||||
forceCheck: forceCheckTableScroll,
|
||||
} = useScrollIndicator(externalFileTable)
|
||||
|
||||
const usingCustomModpack = computed(() => {
|
||||
return requiredContentProject.value?.id === project.value?.id
|
||||
@@ -111,13 +224,36 @@ const loaderDisplay = computed(() => {
|
||||
})
|
||||
|
||||
const modCount = computed(() => modpackVersion.value?.dependencies?.length)
|
||||
const hasExternalFiles = computed(
|
||||
() => Boolean(props.showExternalWarnings) && externalFiles.value.length > 0,
|
||||
)
|
||||
const externalFileRows = computed<ExternalFileRow[]>(() =>
|
||||
externalFiles.value.map((name, index) => ({
|
||||
id: `${index}-${name}`,
|
||||
name,
|
||||
})),
|
||||
)
|
||||
|
||||
async function fetchData(versionId: string) {
|
||||
// cache is making version null for some reason so bypassing for now
|
||||
modpackVersion.value = await get_version(versionId, 'bypass')
|
||||
const version = await get_version(versionId, 'bypass')
|
||||
modpackVersion.value = version
|
||||
|
||||
if (modpackVersion.value?.project_id) {
|
||||
requiredContentProject.value = await get_project(modpackVersion.value.project_id, 'bypass')
|
||||
if (version?.project_id) {
|
||||
requiredContentProject.value = await get_project(version.project_id, 'bypass')
|
||||
externalFiles.value = [
|
||||
...new Set(
|
||||
(version.dependencies ?? [])
|
||||
.filter(
|
||||
(dependency) =>
|
||||
dependency.dependency_type === 'embedded' &&
|
||||
!dependency.project_id &&
|
||||
!dependency.version_id &&
|
||||
dependency.file_name,
|
||||
)
|
||||
.flatMap((dependency) => (dependency.file_name ? [dependency.file_name] : [])),
|
||||
),
|
||||
].sort((left, right) => left.localeCompare(right))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +275,12 @@ function handleDecline() {
|
||||
hide()
|
||||
}
|
||||
|
||||
function handleReport() {
|
||||
if (project.value?.id) {
|
||||
openUrl(`https://modrinth.com/report?item=project&itemID=${project.value.id}`)
|
||||
}
|
||||
}
|
||||
|
||||
const modpackContentModal = ref<InstanceType<typeof ModpackContentModal>>()
|
||||
|
||||
async function openViewContents() {
|
||||
@@ -217,17 +359,19 @@ async function show(
|
||||
modpackVersionId.value = modpackVersionIdVal
|
||||
modpackVersion.value = null
|
||||
requiredContentProject.value = null
|
||||
externalFiles.value = []
|
||||
onInstallComplete.value = callback
|
||||
|
||||
if (modpackVersionIdVal) await fetchData(modpackVersionIdVal)
|
||||
|
||||
hide_ads_window()
|
||||
modal.value?.show(e)
|
||||
await nextTick()
|
||||
forceCheckTableScroll()
|
||||
}
|
||||
|
||||
function hide() {
|
||||
modal.value?.hide()
|
||||
show_ads_window()
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -235,22 +379,10 @@ const messages = defineMessages({
|
||||
id: 'app.modal.install-to-play.header',
|
||||
defaultMessage: 'Install to play',
|
||||
},
|
||||
sharedServerInstance: {
|
||||
id: 'app.modal.install-to-play.shared-server-instance',
|
||||
defaultMessage: 'Shared server instance',
|
||||
},
|
||||
contentRequired: {
|
||||
id: 'app.modal.install-to-play.content-required',
|
||||
defaultMessage: 'Content required',
|
||||
},
|
||||
serverRequiresMods: {
|
||||
id: 'app.modal.install-to-play.server-requires-mods',
|
||||
inviteWarning: {
|
||||
id: 'app.modal.install-to-play.invite-warning',
|
||||
defaultMessage:
|
||||
'This server requires mods to play. Click Install to set up the required files from Modrinth, then launch directly into the server.',
|
||||
},
|
||||
requiredModpack: {
|
||||
id: 'app.modal.install-to-play.required-modpack',
|
||||
defaultMessage: 'Required modpack',
|
||||
'This invite was created by another Modrinth user, not Modrinth. Only accept invites from people you trust.',
|
||||
},
|
||||
sharedInstance: {
|
||||
id: 'app.modal.install-to-play.shared-instance',
|
||||
@@ -268,7 +400,41 @@ const messages = defineMessages({
|
||||
id: 'app.modal.install-to-play.view-contents',
|
||||
defaultMessage: 'View contents',
|
||||
},
|
||||
unknownFilesWarning: {
|
||||
id: 'app.modal.install-to-play.unknown-files-warning',
|
||||
defaultMessage: 'Unknown files warning',
|
||||
},
|
||||
unknownFilesDescription: {
|
||||
id: 'app.modal.install-to-play.unknown-files-description',
|
||||
defaultMessage:
|
||||
'This server modpack contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust.',
|
||||
},
|
||||
unrecognizedFiles: {
|
||||
id: 'app.modal.install-to-play.unrecognized-files',
|
||||
defaultMessage: 'Unrecognized files',
|
||||
},
|
||||
reviewedFiles: {
|
||||
id: 'app.modal.install-to-play.reviewed-files',
|
||||
defaultMessage:
|
||||
'A file is only reviewed if it’s published to Modrinth, regardless of its file format (including .mrpack).',
|
||||
},
|
||||
installAnyway: {
|
||||
id: 'app.modal.install-to-play.install-anyway',
|
||||
defaultMessage: 'Install anyway',
|
||||
},
|
||||
dontInstall: {
|
||||
id: 'app.modal.install-to-play.dont-install',
|
||||
defaultMessage: 'Dont install',
|
||||
},
|
||||
})
|
||||
|
||||
const externalFileColumns = computed<TableColumn<ExternalFileColumn>[]>(() => [
|
||||
{
|
||||
key: 'name',
|
||||
label: formatMessage(messages.unrecognizedFiles),
|
||||
cellClass: '!h-12',
|
||||
},
|
||||
])
|
||||
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
<template>
|
||||
<NewModal
|
||||
ref="modal"
|
||||
:header="formatMessage(messages.header)"
|
||||
:on-hide="() => finish(false)"
|
||||
no-padding
|
||||
max-width="548px"
|
||||
width="100%"
|
||||
>
|
||||
<div class="flex w-full flex-col gap-6 p-6">
|
||||
<div class="flex flex-col gap-2 px-3">
|
||||
<h2 class="m-0 text-xl font-semibold leading-7 text-contrast">
|
||||
{{ formatMessage(messages.signInHeading) }}
|
||||
</h2>
|
||||
<p class="m-0 text-base leading-6 text-primary">
|
||||
{{ formatMessage(messages.description) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
<ButtonStyled>
|
||||
<button
|
||||
class="w-full !shadow-none"
|
||||
type="button"
|
||||
:disabled="authenticating !== null"
|
||||
@click="authenticate('sign-up')"
|
||||
>
|
||||
<SpinnerIcon
|
||||
v-if="authenticating === 'sign-up'"
|
||||
aria-hidden="true"
|
||||
class="animate-spin"
|
||||
/>
|
||||
<UserPlusIcon v-else aria-hidden="true" />
|
||||
{{ formatMessage(messages.createAccountButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button
|
||||
class="w-full"
|
||||
type="button"
|
||||
:disabled="authenticating !== null"
|
||||
@click="authenticate('sign-in')"
|
||||
>
|
||||
<SpinnerIcon
|
||||
v-if="authenticating === 'sign-in'"
|
||||
aria-hidden="true"
|
||||
class="animate-spin"
|
||||
/>
|
||||
<LogInIcon v-else aria-hidden="true" />
|
||||
{{ formatMessage(messages.signInButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
|
||||
<p class="m-0 text-center text-base font-medium leading-6 text-primary">
|
||||
<IntlFormatted :message-id="messages.supportPrompt">
|
||||
<template #support="{ children }">
|
||||
<button
|
||||
type="button"
|
||||
class="inline cursor-pointer border-0 bg-transparent p-0 text-base font-medium leading-6 text-blue hover:underline"
|
||||
@click="openSupport"
|
||||
>
|
||||
<component :is="() => children" />
|
||||
</button>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LogInIcon, SpinnerIcon, UserPlusIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, defineMessages, IntlFormatted, NewModal, useVIntl } from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import type { ModrinthAuthFlow } from '@/helpers/mr_auth'
|
||||
|
||||
const props = defineProps<{
|
||||
requestAuth: (flow: ModrinthAuthFlow) => Promise<boolean>
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const authenticating = ref<ModrinthAuthFlow | null>(null)
|
||||
let resolveShow: ((signedIn: boolean) => void) | undefined
|
||||
|
||||
function show(event?: MouseEvent) {
|
||||
resolveShow?.(false)
|
||||
const modalInstance = modal.value
|
||||
if (!modalInstance) return Promise.resolve(false)
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
resolveShow = resolve
|
||||
modalInstance.show(event)
|
||||
})
|
||||
}
|
||||
|
||||
function finish(signedIn: boolean) {
|
||||
resolveShow?.(signedIn)
|
||||
resolveShow = undefined
|
||||
}
|
||||
|
||||
async function authenticate(flow: ModrinthAuthFlow) {
|
||||
authenticating.value = flow
|
||||
try {
|
||||
if (await props.requestAuth(flow)) {
|
||||
finish(true)
|
||||
modal.value?.hide()
|
||||
}
|
||||
} finally {
|
||||
authenticating.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function openSupport() {
|
||||
openUrl('https://support.modrinth.com')
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
header: {
|
||||
id: 'modal.modrinth-account-required.header',
|
||||
defaultMessage: 'Account required',
|
||||
},
|
||||
signInHeading: {
|
||||
id: 'modal.modrinth-account-required.sign-in-heading',
|
||||
defaultMessage: 'Sign in to a Modrinth account',
|
||||
},
|
||||
description: {
|
||||
id: 'modal.modrinth-account-required.description',
|
||||
defaultMessage:
|
||||
"You'll need to sign into your Modrinth account before you can use this feature.",
|
||||
},
|
||||
createAccountButton: {
|
||||
id: 'modal.modrinth-account-required.create-account-button',
|
||||
defaultMessage: 'Create an account',
|
||||
},
|
||||
signInButton: {
|
||||
id: 'modal.modrinth-account-required.sign-in-button',
|
||||
defaultMessage: 'Sign in to Modrinth',
|
||||
},
|
||||
supportPrompt: {
|
||||
id: 'modal.modrinth-account-required.support-prompt',
|
||||
defaultMessage: 'Having trouble signing in? <support>Get support</support>',
|
||||
},
|
||||
})
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
@@ -2,17 +2,17 @@
|
||||
<ContentDiffModal
|
||||
ref="diffModal"
|
||||
:header="formatMessage(messages.updateToPlay)"
|
||||
:admonition-header="formatMessage(messages.updateRequired)"
|
||||
:description="
|
||||
instance ? formatMessage(messages.updateRequiredDescription, { name: instance.name }) : ''
|
||||
"
|
||||
:diffs="normalizedDiffs"
|
||||
:version-date="versionDate"
|
||||
:show-external-warnings="showExternalWarnings"
|
||||
:confirm-label="formatMessage(commonMessages.updateButton)"
|
||||
:confirm-icon="DownloadIcon"
|
||||
:show-report-button="true"
|
||||
:removed-label="formatMessage(messages.removed)"
|
||||
@confirm="handleUpdate"
|
||||
@cancel="handleDecline"
|
||||
@report="handleReport"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -26,9 +26,8 @@ import {
|
||||
defineMessages,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import dayjs from 'dayjs'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { get_project_many, get_version, get_version_many } from '@/helpers/cache.js'
|
||||
import { wait_for_install_job } from '@/helpers/install'
|
||||
@@ -77,9 +76,8 @@ const { formatMessage } = useVIntl()
|
||||
const { startInstallingServer, stopInstallingServer } = injectServerInstall()
|
||||
type UpdateCompleteCallback = () => void | Promise<void>
|
||||
|
||||
const emit = defineEmits<{
|
||||
cancel: []
|
||||
complete: []
|
||||
defineProps<{
|
||||
showExternalWarnings?: boolean
|
||||
}>()
|
||||
|
||||
const diffModal = ref<InstanceType<typeof ContentDiffModal>>()
|
||||
@@ -89,15 +87,22 @@ const diffs = ref<DependencyDiff[]>([])
|
||||
const modpackVersionId = ref<string | null>(null)
|
||||
const modpackVersion = ref<Version | null>(null)
|
||||
|
||||
const normalizedDiffs = computed<ContentDiffItem[]>(() => {
|
||||
return diffs.value.map((diff) => ({
|
||||
const normalizedDiffs = computed<ContentDiffItem[]>(() =>
|
||||
diffs.value.map((diff) => ({
|
||||
type: diff.type,
|
||||
external: Boolean(diff.fileName && !diff.project),
|
||||
projectName: diff.project?.title,
|
||||
fileName: diff.fileName,
|
||||
currentVersionName: diff.currentVersion?.version_number,
|
||||
newVersionName: diff.newVersion?.version_number,
|
||||
}))
|
||||
})
|
||||
})),
|
||||
)
|
||||
|
||||
const versionDate = computed(() =>
|
||||
modpackVersion.value?.date_published
|
||||
? dayjs(modpackVersion.value.date_published).format('MMMM D, YYYY')
|
||||
: undefined,
|
||||
)
|
||||
|
||||
async function computeDependencyDiffs(
|
||||
currentDeps: Dependency[],
|
||||
@@ -195,6 +200,10 @@ async function computeDependencyDiffs(
|
||||
}
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const aExternal = Boolean(a.fileName && !a.project)
|
||||
const bExternal = Boolean(b.fileName && !b.project)
|
||||
if (aExternal !== bExternal) return aExternal ? -1 : 1
|
||||
|
||||
const typeOrder = { added: 0, updated: 1, removed: 2 }
|
||||
const typeCompare = typeOrder[a.type] - typeOrder[b.type]
|
||||
if (typeCompare !== 0) return typeCompare
|
||||
@@ -232,17 +241,8 @@ async function checkUpdateAvailable(inst: GameInstance): Promise<DependencyDiff[
|
||||
return null
|
||||
}
|
||||
|
||||
watch(
|
||||
() => instance.value,
|
||||
async (newInstance) => {
|
||||
if (!newInstance) return
|
||||
const result = await checkUpdateAvailable(newInstance)
|
||||
diffs.value = result || []
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
)
|
||||
|
||||
async function handleUpdate() {
|
||||
hide()
|
||||
const serverProjectId = instance.value?.link?.project_id
|
||||
if (serverProjectId) startInstallingServer(serverProjectId)
|
||||
try {
|
||||
@@ -255,18 +255,11 @@ async function handleUpdate() {
|
||||
console.error('Error updating instance:', error)
|
||||
} finally {
|
||||
if (serverProjectId) stopInstallingServer(serverProjectId)
|
||||
emit('complete')
|
||||
}
|
||||
}
|
||||
|
||||
function handleReport() {
|
||||
if (instance.value?.link?.project_id) {
|
||||
openUrl(`https://modrinth.com/report?item=project&itemID=${instance.value.link.project_id}`)
|
||||
}
|
||||
}
|
||||
|
||||
function handleDecline() {
|
||||
emit('cancel')
|
||||
hide()
|
||||
}
|
||||
|
||||
function show(
|
||||
@@ -277,8 +270,15 @@ function show(
|
||||
) {
|
||||
instance.value = instanceVal
|
||||
modpackVersionId.value = modpackVersionIdVal
|
||||
modpackVersion.value = null
|
||||
diffs.value = []
|
||||
onUpdateComplete.value = callback
|
||||
diffModal.value?.show(e)
|
||||
void checkUpdateAvailable(instanceVal).then((result) => {
|
||||
if (instance.value?.id === instanceVal.id && modpackVersionId.value === modpackVersionIdVal) {
|
||||
diffs.value = result || []
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function hide() {
|
||||
@@ -290,14 +290,14 @@ const messages = defineMessages({
|
||||
id: 'app.modal.update-to-play.header',
|
||||
defaultMessage: 'Update to play',
|
||||
},
|
||||
updateRequired: {
|
||||
id: 'app.modal.update-to-play.update-required',
|
||||
defaultMessage: 'Update required',
|
||||
},
|
||||
updateRequiredDescription: {
|
||||
id: 'app.modal.update-to-play.update-required-description',
|
||||
defaultMessage:
|
||||
'An update is required to play {name}. Please update to latest version to launch the game.',
|
||||
'An update is required to play {name}. Please update to the latest version to launch the game.',
|
||||
},
|
||||
removed: {
|
||||
id: 'app.modal.update-to-play.removed',
|
||||
defaultMessage: 'Removed',
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
-181
@@ -1,181 +0,0 @@
|
||||
<template>
|
||||
<div v-if="canUnpublish" class="flex flex-col gap-2.5">
|
||||
<span class="text-lg font-semibold text-contrast">{{ formatMessage(messages.title) }}</span>
|
||||
<div>
|
||||
<ButtonStyled color="orange">
|
||||
<button :disabled="busy" @click="unpublishModal?.show()">
|
||||
<SpinnerIcon v-if="unpublishing" class="animate-spin" />
|
||||
<UnlinkIcon v-else class="size-5" />
|
||||
{{ formatMessage(unpublishing ? messages.unpublishingButton : messages.unpublishButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<span class="text-primary">{{ formatMessage(messages.unpublishDescription) }}</span>
|
||||
</div>
|
||||
<div v-if="canUnlink" class="flex flex-col gap-2.5">
|
||||
<span class="text-lg font-semibold text-contrast">{{
|
||||
formatMessage(messages.linkedTitle)
|
||||
}}</span>
|
||||
<div>
|
||||
<ButtonStyled color="orange">
|
||||
<button :disabled="busy" @click="unlinkModal?.show()">
|
||||
<SpinnerIcon v-if="unlinking" class="animate-spin" />
|
||||
<UnlinkIcon v-else class="size-5" />
|
||||
{{ formatMessage(unlinking ? messages.unlinkingButton : messages.unlinkButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<span class="text-primary">{{ formatMessage(messages.unlinkDescription) }}</span>
|
||||
</div>
|
||||
|
||||
<NewModal
|
||||
ref="unpublishModal"
|
||||
:header="formatMessage(messages.unpublishModalHeader)"
|
||||
fade="warning"
|
||||
max-width="500px"
|
||||
>
|
||||
<Admonition type="warning" :header="formatMessage(messages.unpublishModalAdmonitionHeader)">{{
|
||||
formatMessage(messages.unpublishModalBody)
|
||||
}}</Admonition>
|
||||
<template #actions
|
||||
><div class="flex justify-end gap-2">
|
||||
<ButtonStyled
|
||||
><button @click="unpublishModal?.hide()">
|
||||
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button></ButtonStyled
|
||||
><ButtonStyled color="orange"
|
||||
><button :disabled="busy" @click="confirmUnpublish">
|
||||
<UnlinkIcon />{{ formatMessage(messages.unpublishButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</div></template
|
||||
>
|
||||
</NewModal>
|
||||
<NewModal
|
||||
ref="unlinkModal"
|
||||
:header="formatMessage(messages.unlinkModalHeader)"
|
||||
fade="warning"
|
||||
max-width="500px"
|
||||
:on-hide="() => backupCreator?.cancelBackup()"
|
||||
>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Admonition type="warning" :header="formatMessage(messages.unlinkModalAdmonitionHeader)">{{
|
||||
formatMessage(messages.unlinkModalBody)
|
||||
}}</Admonition>
|
||||
<InlineBackupCreator
|
||||
ref="backupCreator"
|
||||
backup-name="Before unlinking shared instance"
|
||||
@update:buttons-disabled="backupBusy = $event"
|
||||
/>
|
||||
</div>
|
||||
<template #actions
|
||||
><div class="flex justify-end gap-2">
|
||||
<ButtonStyled
|
||||
><button @click="unlinkModal?.hide()">
|
||||
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button></ButtonStyled
|
||||
><ButtonStyled color="orange"
|
||||
><button :disabled="busy || backupBusy" @click="confirmUnlink">
|
||||
<UnlinkIcon />{{ formatMessage(messages.unlinkButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</div></template
|
||||
>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SpinnerIcon, UnlinkIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
InlineBackupCreator,
|
||||
NewModal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
canUnpublish: boolean
|
||||
canUnlink: boolean
|
||||
busy: boolean
|
||||
unpublishing: boolean
|
||||
unlinking: boolean
|
||||
unpublish: () => Promise<void>
|
||||
unlink: () => Promise<void>
|
||||
}>()
|
||||
const { formatMessage } = useVIntl()
|
||||
const unpublishModal = ref<InstanceType<typeof NewModal>>()
|
||||
const unlinkModal = ref<InstanceType<typeof NewModal>>()
|
||||
const backupCreator = ref<InstanceType<typeof InlineBackupCreator>>()
|
||||
const backupBusy = ref(false)
|
||||
|
||||
async function confirmUnpublish() {
|
||||
unpublishModal.value?.hide()
|
||||
await props.unpublish()
|
||||
}
|
||||
async function confirmUnlink() {
|
||||
unlinkModal.value?.hide()
|
||||
await props.unlink()
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'installation-settings.shared-instance.title', defaultMessage: 'Shared instance' },
|
||||
linkedTitle: {
|
||||
id: 'installation-settings.shared-instance.linked-title',
|
||||
defaultMessage: 'Linked shared instance',
|
||||
},
|
||||
unpublishButton: {
|
||||
id: 'installation-settings.shared-instance.unpublish-button',
|
||||
defaultMessage: 'Unpublish shared instance',
|
||||
},
|
||||
unpublishingButton: {
|
||||
id: 'installation-settings.shared-instance.unpublishing-button',
|
||||
defaultMessage: 'Unpublishing...',
|
||||
},
|
||||
unpublishDescription: {
|
||||
id: 'installation-settings.shared-instance.unpublish-description',
|
||||
defaultMessage: 'Stop sharing this instance and remove it from Modrinth.',
|
||||
},
|
||||
unlinkButton: {
|
||||
id: 'installation-settings.shared-instance.unlink-button',
|
||||
defaultMessage: 'Unlink shared instance',
|
||||
},
|
||||
unlinkingButton: {
|
||||
id: 'installation-settings.shared-instance.unlinking-button',
|
||||
defaultMessage: 'Unlinking...',
|
||||
},
|
||||
unlinkDescription: {
|
||||
id: 'installation-settings.shared-instance.unlink-description',
|
||||
defaultMessage: 'Disconnect this local instance from future shared updates.',
|
||||
},
|
||||
unpublishModalHeader: {
|
||||
id: 'installation-settings.unpublish-shared-instance.modal.header',
|
||||
defaultMessage: 'Unpublish shared instance',
|
||||
},
|
||||
unpublishModalAdmonitionHeader: {
|
||||
id: 'installation-settings.unpublish-shared-instance.modal.admonition-header',
|
||||
defaultMessage: 'Unpublishing shared instance',
|
||||
},
|
||||
unpublishModalBody: {
|
||||
id: 'installation-settings.unpublish-shared-instance.modal.admonition-body',
|
||||
defaultMessage:
|
||||
"This deletes the shared instance from Modrinth's servers. People using it in the Modrinth App will stop receiving updates, but your local instance and its content will stay on this device.",
|
||||
},
|
||||
unlinkModalHeader: {
|
||||
id: 'installation-settings.unlink-shared-instance.modal.header',
|
||||
defaultMessage: 'Unlink shared instance',
|
||||
},
|
||||
unlinkModalAdmonitionHeader: {
|
||||
id: 'installation-settings.unlink-shared-instance.modal.admonition-header',
|
||||
defaultMessage: 'Unlinking shared instance',
|
||||
},
|
||||
unlinkModalBody: {
|
||||
id: 'installation-settings.unlink-shared-instance.modal.admonition-body',
|
||||
defaultMessage:
|
||||
'This only affects your local instance. Your installed content will stay on this device, and the shared instance and other people using it will not be affected.',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -1,120 +0,0 @@
|
||||
<template>
|
||||
<ContentDiffModal
|
||||
ref="modal"
|
||||
:header="formatMessage(messages.updateToPlay)"
|
||||
:admonition-header="formatMessage(messages.updateRequired)"
|
||||
:description="instance ? formatMessage(messages.description, { name: instance.name }) : ''"
|
||||
:diffs="diffs"
|
||||
:confirm-label="formatMessage(commonMessages.updateButton)"
|
||||
:confirm-icon="DownloadIcon"
|
||||
:added-label="formatMessage(messages.addedLabel)"
|
||||
:removed-label="formatMessage(messages.removedLabel)"
|
||||
:show-report-button="false"
|
||||
@confirm="update"
|
||||
@cancel="emit('cancel')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DownloadIcon } from '@modrinth/assets'
|
||||
import {
|
||||
commonMessages,
|
||||
type ContentDiffItem,
|
||||
ContentDiffModal,
|
||||
defineMessages,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import {
|
||||
getSharedInstanceUnavailableReason,
|
||||
install_update_shared_instance,
|
||||
isSharedInstanceUnavailableError,
|
||||
type SharedInstanceUnavailableReason,
|
||||
type SharedInstanceUpdatePreview,
|
||||
wait_for_install_job,
|
||||
} from '@/helpers/install'
|
||||
import { useSharedInstanceErrors } from '@/helpers/shared-instance-errors'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
type UpdateCompleteCallback = () => void | Promise<void>
|
||||
|
||||
const emit = defineEmits<{
|
||||
cancel: []
|
||||
complete: []
|
||||
sharedInstanceUnavailable: [reason: SharedInstanceUnavailableReason | null]
|
||||
}>()
|
||||
const modal = ref<InstanceType<typeof ContentDiffModal>>()
|
||||
const instance = ref<GameInstance | null>(null)
|
||||
const preview = ref<SharedInstanceUpdatePreview | null>(null)
|
||||
const onComplete = ref<UpdateCompleteCallback>(() => {})
|
||||
const { formatMessage } = useVIntl()
|
||||
const { notifySharedInstanceError } = useSharedInstanceErrors()
|
||||
const diffs = computed<ContentDiffItem[]>(
|
||||
() =>
|
||||
preview.value?.diffs.map((diff) => ({
|
||||
type: diff.type,
|
||||
projectName: diff.projectName ?? undefined,
|
||||
fileName: diff.fileName ?? undefined,
|
||||
currentVersionName: diff.currentVersionName ?? undefined,
|
||||
newVersionName: diff.newVersionName ?? undefined,
|
||||
disabled: diff.disabled,
|
||||
})) ?? [],
|
||||
)
|
||||
|
||||
async function update() {
|
||||
try {
|
||||
if (instance.value) {
|
||||
const job = await install_update_shared_instance(instance.value.id)
|
||||
await wait_for_install_job(job.job_id)
|
||||
await onComplete.value()
|
||||
}
|
||||
} catch (error) {
|
||||
if (isSharedInstanceUnavailableError(error)) {
|
||||
emit('sharedInstanceUnavailable', getSharedInstanceUnavailableReason(error))
|
||||
return
|
||||
}
|
||||
notifySharedInstanceError(error)
|
||||
} finally {
|
||||
emit('complete')
|
||||
}
|
||||
}
|
||||
|
||||
function show(
|
||||
instanceValue: GameInstance,
|
||||
previewValue: SharedInstanceUpdatePreview,
|
||||
callback: UpdateCompleteCallback = () => {},
|
||||
event?: MouseEvent,
|
||||
) {
|
||||
instance.value = instanceValue
|
||||
preview.value = previewValue
|
||||
onComplete.value = callback
|
||||
modal.value?.show(event)
|
||||
}
|
||||
function hide() {
|
||||
modal.value?.hide()
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
updateToPlay: { id: 'app.modal.update-to-play.header', defaultMessage: 'Update to play' },
|
||||
updateRequired: {
|
||||
id: 'app.modal.update-to-play.update-required',
|
||||
defaultMessage: 'Update required',
|
||||
},
|
||||
description: {
|
||||
id: 'app.modal.update-to-play.update-required-description',
|
||||
defaultMessage:
|
||||
'An update is required to play {name}. Please update to latest version to launch the game.',
|
||||
},
|
||||
addedLabel: {
|
||||
id: 'app.modal.update-to-play.shared-instance-added-label',
|
||||
defaultMessage: 'Added',
|
||||
},
|
||||
removedLabel: {
|
||||
id: 'app.modal.update-to-play.shared-instance-removed-label',
|
||||
defaultMessage: 'Removed',
|
||||
},
|
||||
})
|
||||
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.installToPlay)" :closable="true" no-padding>
|
||||
<div v-if="preview" class="flex flex-col gap-6 max-w-[500px] p-6 pb-2">
|
||||
<Admonition type="warning" :header="formatMessage(messages.trustWarningHeader)">
|
||||
{{ formatMessage(messages.trustWarningDescription) }}
|
||||
</Admonition>
|
||||
<SharedInstanceInstallSummary :preview="preview" @view-contents="openViewContents" />
|
||||
<div v-if="preview.externalFileCount" class="flex items-center gap-2 text-orange">
|
||||
<IssuesIcon class="h-5 w-5 flex-none" />
|
||||
<span>{{
|
||||
formatMessage(messages.externalFileWarning, { count: preview.externalFileCount })
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<template #actions>
|
||||
<div class="flex justify-end gap-2">
|
||||
<ButtonStyled
|
||||
><button @click="hide">
|
||||
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
<ButtonStyled color="brand"
|
||||
><button @click="accept">
|
||||
<DownloadIcon />{{ formatMessage(messages.installButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
<ModpackContentModal
|
||||
ref="contentModal"
|
||||
:header="formatMessage(messages.sharedInstanceContent)"
|
||||
:modpack-name="preview?.name ?? ''"
|
||||
:modpack-icon-url="preview?.iconUrl ?? undefined"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DownloadIcon, IssuesIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
ModpackContentModal,
|
||||
NewModal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { hide_ads_window, show_ads_window } from '@/helpers/ads'
|
||||
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
||||
|
||||
import SharedInstanceInstallSummary from './shared-instance-install-summary.vue'
|
||||
import { useSharedInstancePreviewContent } from './use-shared-instance-preview-content'
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const contentModal = ref<InstanceType<typeof ModpackContentModal>>()
|
||||
const preview = ref<SharedInstanceInstallPreview | null>(null)
|
||||
const install = ref<() => void | Promise<void>>(() => {})
|
||||
const { formatMessage } = useVIntl()
|
||||
const { load } = useSharedInstancePreviewContent()
|
||||
|
||||
async function accept() {
|
||||
hide()
|
||||
try {
|
||||
await install.value()
|
||||
} catch (error) {
|
||||
console.error('Failed to install shared instance:', error)
|
||||
}
|
||||
}
|
||||
async function openViewContents() {
|
||||
if (!preview.value) return
|
||||
contentModal.value?.showLoading()
|
||||
try {
|
||||
contentModal.value?.show(await load(preview.value))
|
||||
} catch (error) {
|
||||
console.error('Failed to load shared instance contents:', error)
|
||||
contentModal.value?.show([])
|
||||
}
|
||||
}
|
||||
function show(
|
||||
previewValue: SharedInstanceInstallPreview,
|
||||
installValue: () => void | Promise<void>,
|
||||
event?: MouseEvent,
|
||||
) {
|
||||
preview.value = previewValue
|
||||
install.value = installValue
|
||||
hide_ads_window()
|
||||
modal.value?.show(event)
|
||||
}
|
||||
function hide() {
|
||||
modal.value?.hide()
|
||||
show_ads_window()
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
installToPlay: { id: 'app.modal.install-to-play.header', defaultMessage: 'Install to play' },
|
||||
sharedInstanceContent: {
|
||||
id: 'app.modal.install-to-play.shared-instance-content',
|
||||
defaultMessage: 'Shared instance content',
|
||||
},
|
||||
trustWarningHeader: {
|
||||
id: 'app.modal.install-to-play.trust-warning-header',
|
||||
defaultMessage: 'Do you trust this user?',
|
||||
},
|
||||
trustWarningDescription: {
|
||||
id: 'app.modal.install-to-play.trust-warning-description',
|
||||
defaultMessage:
|
||||
'A shared instance will install files on your computer and may include content not from Modrinth.',
|
||||
},
|
||||
externalFileWarning: {
|
||||
id: 'app.modal.install-to-play.external-file-warning',
|
||||
defaultMessage:
|
||||
'{count, plural, one {This instance includes # file that is not from Modrinth.} other {This instance includes # files that are not from Modrinth.}}',
|
||||
},
|
||||
installButton: { id: 'app.modal.install-to-play.install-button', defaultMessage: 'Install' },
|
||||
})
|
||||
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-1">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="font-semibold text-contrast">{{ formatMessage(messages.sharedInstance) }}</span>
|
||||
<ButtonStyled type="transparent">
|
||||
<button @click="emit('viewContents')">
|
||||
<EyeIcon />
|
||||
{{ formatMessage(messages.viewContents) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 rounded-xl bg-surface-2 p-3">
|
||||
<Avatar :src="preview.iconUrl" :alt="preview.name" size="48px" />
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="font-semibold text-contrast">{{ preview.name }}</span>
|
||||
<span class="text-sm text-secondary">
|
||||
{{ loaderDisplay }} {{ preview.gameVersion }}
|
||||
<template v-if="preview.modCount">
|
||||
<BulletDivider />
|
||||
{{ formatMessage(messages.modCount, { count: preview.modCount }) }}
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { EyeIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
BulletDivider,
|
||||
ButtonStyled,
|
||||
defineMessages,
|
||||
formatLoader,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
||||
|
||||
const props = defineProps<{ preview: SharedInstanceInstallPreview }>()
|
||||
const emit = defineEmits<{ viewContents: [] }>()
|
||||
const { formatMessage } = useVIntl()
|
||||
const loaderDisplay = computed(() =>
|
||||
props.preview.loader ? formatLoader(formatMessage, props.preview.loader) : '',
|
||||
)
|
||||
const messages = defineMessages({
|
||||
sharedInstance: {
|
||||
id: 'app.modal.install-to-play.shared-instance',
|
||||
defaultMessage: 'Shared instance',
|
||||
},
|
||||
viewContents: { id: 'app.modal.install-to-play.view-contents', defaultMessage: 'View contents' },
|
||||
modCount: {
|
||||
id: 'app.modal.install-to-play.mod-count',
|
||||
defaultMessage: '{count, plural, one {# mod} other {# mods}}',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import type { ContentItem } from '@modrinth/ui'
|
||||
|
||||
import { get_project_many, get_version, get_version_many } from '@/helpers/cache.js'
|
||||
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
||||
|
||||
type VersionDependency = Labrinth.Versions.v2.Dependency & { version_id?: string }
|
||||
|
||||
export function useSharedInstancePreviewContent() {
|
||||
async function load(preview: SharedInstanceInstallPreview): Promise<ContentItem[]> {
|
||||
return [
|
||||
...preview.externalFiles.map(externalFileContentItem),
|
||||
...(await modpackContentItems(preview)),
|
||||
...(await contentItemsFromVersionIds(
|
||||
preview.contentVersionIds.filter((id) => id !== preview.modpackVersionId),
|
||||
)),
|
||||
]
|
||||
}
|
||||
|
||||
async function modpackContentItems(preview: SharedInstanceInstallPreview) {
|
||||
if (!preview.modpackVersionId) return []
|
||||
const version = await get_version(preview.modpackVersionId, 'must_revalidate')
|
||||
return await contentItemsFromDependencies(version?.dependencies ?? [])
|
||||
}
|
||||
|
||||
async function contentItemsFromDependencies(dependencies: Labrinth.Versions.v2.Dependency[]) {
|
||||
const deps = dependencies as VersionDependency[]
|
||||
const projectIds = unique(deps.map((dep) => dep.project_id).filter((id): id is string => !!id))
|
||||
const versionIds = unique(deps.map((dep) => dep.version_id).filter((id): id is string => !!id))
|
||||
const [projects, versions]: [Labrinth.Projects.v2.Project[], Labrinth.Versions.v2.Version[]] =
|
||||
await Promise.all([
|
||||
projectIds.length ? get_project_many(projectIds, 'must_revalidate') : [],
|
||||
versionIds.length ? get_version_many(versionIds, 'must_revalidate') : [],
|
||||
])
|
||||
const projectMap = new Map(projects.map((project) => [project.id, project]))
|
||||
const versionMap = new Map(versions.map((version) => [version.id, version]))
|
||||
|
||||
return deps.map((dependency): ContentItem => {
|
||||
const project = dependency.project_id ? projectMap.get(dependency.project_id) : null
|
||||
const version = dependency.version_id ? versionMap.get(dependency.version_id) : null
|
||||
const fileName =
|
||||
version?.files?.[0]?.filename ?? dependency.file_name ?? project?.title ?? 'Unknown'
|
||||
return contentItem(
|
||||
version?.id ?? project?.id ?? fileName,
|
||||
fileName,
|
||||
project,
|
||||
version,
|
||||
!project && !version,
|
||||
dependency.project_id ?? fileName,
|
||||
dependency.file_name ?? fileName,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async function contentItemsFromVersionIds(versionIds: string[]) {
|
||||
const versions: Labrinth.Versions.v2.Version[] = versionIds.length
|
||||
? await get_version_many(unique(versionIds), 'must_revalidate')
|
||||
: []
|
||||
const projectIds = unique(versions.map((version) => version.project_id).filter(Boolean))
|
||||
const projects: Labrinth.Projects.v2.Project[] = projectIds.length
|
||||
? await get_project_many(projectIds, 'must_revalidate')
|
||||
: []
|
||||
const projectMap = new Map(projects.map((project) => [project.id, project]))
|
||||
return versions.map((version): ContentItem => {
|
||||
const project = projectMap.get(version.project_id)
|
||||
const fileName = version.files?.[0]?.filename ?? project?.title ?? version.name ?? 'Unknown'
|
||||
return contentItem(
|
||||
version.id,
|
||||
fileName,
|
||||
project,
|
||||
version,
|
||||
false,
|
||||
version.project_id,
|
||||
version.name,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
return { load }
|
||||
}
|
||||
|
||||
function contentItem(
|
||||
id: string,
|
||||
fileName: string,
|
||||
project?: Labrinth.Projects.v2.Project | null,
|
||||
version?: Labrinth.Versions.v2.Version | null,
|
||||
external = false,
|
||||
fallbackProjectId = id,
|
||||
fallbackTitle = fileName,
|
||||
projectType = project?.project_type ?? 'mod',
|
||||
): ContentItem {
|
||||
return {
|
||||
id,
|
||||
file_name: fileName,
|
||||
project_type: projectType,
|
||||
has_update: false,
|
||||
update_version_id: null,
|
||||
external,
|
||||
project: {
|
||||
id: project?.id ?? fallbackProjectId,
|
||||
slug: project?.slug ?? fallbackProjectId,
|
||||
title: project?.title ?? fallbackTitle,
|
||||
icon_url: project?.icon_url ?? undefined,
|
||||
},
|
||||
...(version
|
||||
? {
|
||||
version: {
|
||||
id: version.id,
|
||||
file_name: fileName,
|
||||
version_number: version.version_number ?? undefined,
|
||||
date_published: version.date_published ?? undefined,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
}
|
||||
}
|
||||
|
||||
function externalFileContentItem(
|
||||
file: SharedInstanceInstallPreview['externalFiles'][number],
|
||||
): ContentItem {
|
||||
return contentItem(
|
||||
`external:${file.fileType}:${file.fileName}`,
|
||||
file.fileName,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
file.fileName,
|
||||
file.fileName,
|
||||
file.fileType,
|
||||
)
|
||||
}
|
||||
|
||||
function unique<T>(values: T[]) {
|
||||
return Array.from(new Set(values))
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<SharedInstanceInviteLinkModal ref="inviteLinkModal" :process-invite="installFromInviteId" />
|
||||
<ModrinthAccountRequiredModal ref="accountRequiredModal" :request-auth="requestAuth" />
|
||||
<SharedInstanceInstallModal ref="installModal" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { injectAuth } from '@modrinth/ui'
|
||||
import { nextTick, ref } from 'vue'
|
||||
|
||||
import ModrinthAccountRequiredModal from '@/components/ui/modal/ModrinthAccountRequiredModal.vue'
|
||||
import SharedInstanceInstallModal from '@/components/ui/shared-instances/shared-instance-install-modal/index.vue'
|
||||
import type { ModrinthAuthFlow } from '@/helpers/mr_auth'
|
||||
|
||||
import SharedInstanceInviteLinkModal from './shared-instance-invite-link-modal.vue'
|
||||
import type { SharedInstanceInviteHandler } from './shared-instance-invite-types'
|
||||
import { useSharedInstanceInviteHandler } from './use-shared-instance-invite-handler'
|
||||
|
||||
const auth = injectAuth()
|
||||
const inviteLinkModal = ref<InstanceType<typeof SharedInstanceInviteLinkModal>>()
|
||||
const installModal = ref<InstanceType<typeof SharedInstanceInstallModal>>()
|
||||
const accountRequiredModal = ref<InstanceType<typeof ModrinthAccountRequiredModal>>()
|
||||
const { handleNotification, installFromInviteId } = useSharedInstanceInviteHandler(
|
||||
installModal,
|
||||
accountRequiredModal,
|
||||
)
|
||||
|
||||
async function requestAuth(flow: ModrinthAuthFlow) {
|
||||
await auth.requestSignIn('', flow)
|
||||
await nextTick()
|
||||
return !!auth.session_token.value
|
||||
}
|
||||
|
||||
function showManualInviteLinkModal(event?: MouseEvent) {
|
||||
inviteLinkModal.value?.show(event)
|
||||
}
|
||||
|
||||
defineExpose<SharedInstanceInviteHandler>({
|
||||
handleNotification,
|
||||
installFromInviteId,
|
||||
showManualInviteLinkModal,
|
||||
})
|
||||
</script>
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
<template>
|
||||
<NewModal ref="modal" header="Install from invite link" max-width="32rem">
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="font-semibold text-contrast">Invite link</span>
|
||||
<StyledInput
|
||||
v-model="inviteLink"
|
||||
placeholder="https://modrinth.com/share/..."
|
||||
:disabled="processing"
|
||||
@keydown.enter="process"
|
||||
/>
|
||||
<span v-if="inviteLink && !inviteId" class="text-sm text-red">
|
||||
Enter a valid Modrinth shared-instance invite link.
|
||||
</span>
|
||||
</div>
|
||||
<template #actions>
|
||||
<div class="flex justify-end gap-2">
|
||||
<ButtonStyled>
|
||||
<button :disabled="processing" @click="modal?.hide()"><XIcon /> Cancel</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button :disabled="!inviteId || processing" @click="process">
|
||||
<LinkIcon />
|
||||
Process
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LinkIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, NewModal, StyledInput } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { parseSharedInstanceInviteLink } from './shared-instance-invite-parser'
|
||||
|
||||
const props = defineProps<{ processInvite: (inviteId: string) => Promise<void> }>()
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const inviteLink = ref('')
|
||||
const processing = ref(false)
|
||||
const inviteId = computed(() => parseSharedInstanceInviteLink(inviteLink.value))
|
||||
|
||||
function show(event?: MouseEvent) {
|
||||
inviteLink.value = ''
|
||||
modal.value?.show(event)
|
||||
}
|
||||
|
||||
async function process() {
|
||||
if (!inviteId.value) return
|
||||
|
||||
processing.value = true
|
||||
modal.value?.hide()
|
||||
try {
|
||||
await props.processInvite(inviteId.value)
|
||||
} finally {
|
||||
processing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
import type {
|
||||
AppNotification,
|
||||
SharedInstanceInvite,
|
||||
SharedInstanceInviteNotificationBody,
|
||||
} from './shared-instance-invite-types'
|
||||
|
||||
function optionalString(value: unknown) {
|
||||
return typeof value === 'string' ? value : null
|
||||
}
|
||||
|
||||
export function parseSharedInstanceInviteNotification(
|
||||
notification: AppNotification,
|
||||
): SharedInstanceInvite | null {
|
||||
if (notification.body?.type !== 'shared_instance_invite') return null
|
||||
|
||||
const body = notification.body as SharedInstanceInviteNotificationBody
|
||||
const sharedInstanceId = optionalString(body.shared_instance_id)
|
||||
const sharedInstanceName = optionalString(body.shared_instance_name)
|
||||
if (!sharedInstanceId || !sharedInstanceName) return null
|
||||
|
||||
return {
|
||||
sharedInstanceId,
|
||||
sharedInstanceName,
|
||||
invitedById: optionalString(body.invited_by),
|
||||
invitedByUsername: optionalString(body.invited_by_username),
|
||||
invitedByAvatarUrl: optionalString(body.invited_by_avatar_url),
|
||||
instanceIconUrl: optionalString(body.instance_icon_url),
|
||||
}
|
||||
}
|
||||
|
||||
export function parseSharedInstanceInviteLink(value: string) {
|
||||
const trimmedValue = value.trim()
|
||||
if (!trimmedValue) return null
|
||||
|
||||
try {
|
||||
const url = new URL(trimmedValue)
|
||||
const match = /^\/share\/([^/]+)\/?$/.exec(url.pathname)
|
||||
return match ? decodeURIComponent(match[1]) : null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
export type SharedInstanceInviteNotificationBody = {
|
||||
type: 'shared_instance_invite'
|
||||
shared_instance_id?: unknown
|
||||
shared_instance_name?: unknown
|
||||
invited_by?: unknown
|
||||
invited_by_username?: unknown
|
||||
invited_by_avatar_url?: unknown
|
||||
instance_icon_url?: unknown
|
||||
}
|
||||
|
||||
export type AppNotification = {
|
||||
id: string | number
|
||||
read?: boolean
|
||||
body?: { type?: unknown } & Record<string, unknown>
|
||||
}
|
||||
|
||||
export type SharedInstanceInvite = {
|
||||
sharedInstanceId: string
|
||||
sharedInstanceName: string
|
||||
invitedById: string | null
|
||||
invitedByUsername: string | null
|
||||
invitedByAvatarUrl: string | null
|
||||
instanceIconUrl: string | null
|
||||
}
|
||||
|
||||
export type SharedInstanceInviteHandler = {
|
||||
handleNotification(notification: AppNotification): Promise<boolean>
|
||||
installFromInviteId(inviteId: string): Promise<void>
|
||||
showManualInviteLinkModal(event?: MouseEvent): void
|
||||
}
|
||||
-160
@@ -1,160 +0,0 @@
|
||||
import {
|
||||
injectAuth,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
injectPopupNotificationManager,
|
||||
} from '@modrinth/ui'
|
||||
import { useQueryClient } from '@tanstack/vue-query'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { type Ref, watch } from 'vue'
|
||||
|
||||
import { config } from '@/config'
|
||||
import { get_user } from '@/helpers/cache'
|
||||
import { toError } from '@/helpers/errors'
|
||||
import {
|
||||
install_accept_shared_instance_invite,
|
||||
install_get_shared_instance_preview,
|
||||
install_shared_instance,
|
||||
} from '@/helpers/install'
|
||||
|
||||
import { parseSharedInstanceInviteNotification } from './shared-instance-invite-parser'
|
||||
import type { AppNotification, SharedInstanceInvite } from './shared-instance-invite-types'
|
||||
|
||||
type InstallModal = {
|
||||
show(
|
||||
preview: Awaited<ReturnType<typeof install_get_shared_instance_preview>>,
|
||||
install: () => Promise<void>,
|
||||
): void
|
||||
}
|
||||
|
||||
type AccountRequiredModal = {
|
||||
show(event?: MouseEvent): Promise<boolean>
|
||||
}
|
||||
|
||||
export function useSharedInstanceInviteHandler(
|
||||
installModal: Ref<InstallModal | undefined>,
|
||||
accountRequiredModal: Ref<AccountRequiredModal | undefined>,
|
||||
) {
|
||||
const auth = injectAuth()
|
||||
const client = injectModrinthClient()
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { addPopupNotification } = injectPopupNotificationManager()
|
||||
const queryClient = useQueryClient()
|
||||
const displayedNotifications = new Set<string | number>()
|
||||
|
||||
async function markNotificationRead(notification: AppNotification) {
|
||||
await client.labrinth.notifications_v2.markAsRead(String(notification.id))
|
||||
}
|
||||
|
||||
async function resolveInvite(invite: SharedInstanceInvite) {
|
||||
const invitedBy =
|
||||
!invite.invitedByUsername && invite.invitedById
|
||||
? await get_user(invite.invitedById, 'bypass').catch(() => null)
|
||||
: null
|
||||
|
||||
return {
|
||||
...invite,
|
||||
invitedByUsername: invite.invitedByUsername ?? invitedBy?.username ?? null,
|
||||
invitedByAvatarUrl: invite.invitedByAvatarUrl ?? invitedBy?.avatar_url ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
function showInstall(
|
||||
preview: Awaited<ReturnType<typeof install_get_shared_instance_preview>>,
|
||||
install: () => Promise<void>,
|
||||
) {
|
||||
if (!installModal.value) throw new Error('Shared instance install modal is not available.')
|
||||
installModal.value.show(preview, install)
|
||||
}
|
||||
|
||||
async function acceptNotification(notification: AppNotification, invite: SharedInstanceInvite) {
|
||||
try {
|
||||
const preview = await install_get_shared_instance_preview(
|
||||
invite.sharedInstanceId,
|
||||
invite.sharedInstanceName,
|
||||
)
|
||||
if (invite.instanceIconUrl) preview.iconUrl = invite.instanceIconUrl
|
||||
|
||||
showInstall(preview, async () => {
|
||||
await install_shared_instance(
|
||||
invite.sharedInstanceId,
|
||||
invite.sharedInstanceName,
|
||||
invite.invitedById,
|
||||
null,
|
||||
null,
|
||||
invite.instanceIconUrl,
|
||||
)
|
||||
await markNotificationRead(notification)
|
||||
await queryClient.invalidateQueries({ queryKey: ['instances'] })
|
||||
})
|
||||
} catch (error) {
|
||||
handleError(toError(error))
|
||||
}
|
||||
}
|
||||
|
||||
async function handleNotification(notification: AppNotification) {
|
||||
const parsedInvite = parseSharedInstanceInviteNotification(notification)
|
||||
if (!parsedInvite) return false
|
||||
if (displayedNotifications.has(notification.id)) return true
|
||||
|
||||
displayedNotifications.add(notification.id)
|
||||
const invite = await resolveInvite(parsedInvite)
|
||||
addPopupNotification({
|
||||
title: invite.sharedInstanceName,
|
||||
autoCloseMs: null,
|
||||
toast: {
|
||||
type: 'instance-invite',
|
||||
actorName: invite.invitedByUsername,
|
||||
actorAvatarUrl: invite.invitedByAvatarUrl ?? undefined,
|
||||
entityName: invite.sharedInstanceName,
|
||||
entityIconUrl: invite.instanceIconUrl ?? undefined,
|
||||
onAccept: () => acceptNotification(notification, invite),
|
||||
onDecline: () =>
|
||||
markNotificationRead(notification).catch((error) => handleError(toError(error))),
|
||||
onOpenActor: () => {
|
||||
if (invite.invitedByUsername) {
|
||||
openUrl(`${config.siteUrl}/user/${encodeURIComponent(invite.invitedByUsername)}`)
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
async function requireAccount() {
|
||||
if (!auth.isReady?.value) {
|
||||
await new Promise<void>((resolve) => {
|
||||
const stop = watch(auth.isReady!, (ready) => {
|
||||
if (ready) {
|
||||
stop()
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
if (auth.session_token.value) return true
|
||||
return (await accountRequiredModal.value?.show()) ?? false
|
||||
}
|
||||
|
||||
async function installFromInviteId(inviteId: string) {
|
||||
try {
|
||||
if (!(await requireAccount())) return
|
||||
const invite = await install_accept_shared_instance_invite(inviteId)
|
||||
showInstall(invite.preview, async () => {
|
||||
await install_shared_instance(
|
||||
invite.sharedInstanceId,
|
||||
invite.preview.name,
|
||||
invite.managerId,
|
||||
invite.serverManagerName,
|
||||
invite.serverManagerIconUrl,
|
||||
invite.instanceIconUrl,
|
||||
)
|
||||
await queryClient.invalidateQueries({ queryKey: ['instances'] })
|
||||
})
|
||||
} catch (error) {
|
||||
handleError(toError(error))
|
||||
}
|
||||
}
|
||||
|
||||
return { handleNotification, installFromInviteId }
|
||||
}
|
||||
@@ -53,10 +53,6 @@ const messages = defineMessages({
|
||||
id: 'app.action-bar.install.unknown-instance',
|
||||
defaultMessage: 'Unknown instance',
|
||||
},
|
||||
updatingSharedContent: {
|
||||
id: 'app.action-bar.install.updating-shared-content',
|
||||
defaultMessage: 'Updating shared content',
|
||||
},
|
||||
})
|
||||
|
||||
const phaseMessages = defineMessages({
|
||||
@@ -272,9 +268,6 @@ export async function useInstallJobNotifications(opts: {
|
||||
version: job.details.major_version,
|
||||
})
|
||||
}
|
||||
if (job.kind === 'update_shared_instance' && job.phase === 'downloading_content') {
|
||||
return formatMessage(messages.updatingSharedContent)
|
||||
}
|
||||
return formatMessage(phaseMessages[job.phase])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import { type ContentActionWarning, type ContentItem, defineMessages, useVIntl } from '@modrinth/ui'
|
||||
import { computed, type Ref } from 'vue'
|
||||
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
const managedSourceKinds = new Set(['shared_instance', 'modrinth_modpack', 'imported_modpack'])
|
||||
|
||||
export function useManagedContentPolicy(instance: Ref<GameInstance>) {
|
||||
const { formatMessage } = useVIntl()
|
||||
const isManagedModpack = computed(() => instance.value.shared_instance?.role === 'member')
|
||||
const canUnpublish = computed(() => instance.value.shared_instance?.role === 'owner')
|
||||
const canUnlink = computed(() => instance.value.shared_instance?.role === 'member')
|
||||
const managedModpackWarning = computed(() => ({
|
||||
admonitionHeader: formatMessage(messages.warningHeader),
|
||||
changeVersionBody: formatMessage(messages.changeVersionBody),
|
||||
unlinkBody: formatMessage(messages.unlinkBody),
|
||||
}))
|
||||
|
||||
function isManagedContent(item: ContentItem) {
|
||||
return isManagedModpack.value && !!item.source_kind && managedSourceKinds.has(item.source_kind)
|
||||
}
|
||||
|
||||
function canMutateContent(item: ContentItem) {
|
||||
return !isManagedContent(item)
|
||||
}
|
||||
|
||||
function canUpdateContent(item: ContentItem) {
|
||||
return (
|
||||
canMutateContent(item) && !!item.file_path && !!item.has_update && !!item.update_version_id
|
||||
)
|
||||
}
|
||||
|
||||
function deleteWarning(items: ContentItem[]): ContentActionWarning | null {
|
||||
if (!items.some(isManagedContent)) return null
|
||||
return {
|
||||
admonitionHeader: formatMessage(messages.warningHeader),
|
||||
admonitionBody: formatMessage(
|
||||
items.length === 1 ? messages.deleteSingleBody : messages.deleteBulkBody,
|
||||
),
|
||||
actionLabel: formatMessage(
|
||||
items.length === 1 ? messages.deleteButton : messages.deleteManyButton,
|
||||
{ count: items.length },
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
function disableWarning(items: ContentItem[]): ContentActionWarning | null {
|
||||
if (!items.some(isManagedContent)) return null
|
||||
return {
|
||||
admonitionHeader: formatMessage(messages.warningHeader),
|
||||
admonitionBody: formatMessage(
|
||||
items.length === 1 ? messages.disableSingleBody : messages.disableBulkBody,
|
||||
),
|
||||
actionLabel: formatMessage(
|
||||
items.length === 1 ? messages.disableButton : messages.disableManyButton,
|
||||
{ count: items.length },
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isManagedModpack,
|
||||
canUnpublish,
|
||||
canUnlink,
|
||||
managedModpackWarning,
|
||||
isManagedContent,
|
||||
canMutateContent,
|
||||
canUpdateContent,
|
||||
deleteWarning,
|
||||
disableWarning,
|
||||
}
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
warningHeader: {
|
||||
id: 'content.shared-instance.warning-header',
|
||||
defaultMessage: 'This is part of the shared instance',
|
||||
},
|
||||
changeVersionBody: {
|
||||
id: 'content.shared-instance.change-version-body',
|
||||
defaultMessage:
|
||||
'Changing the version only changes your local copy. Future shared instance updates may restore or change it again.',
|
||||
},
|
||||
unlinkBody: {
|
||||
id: 'content.shared-instance.unlink-body',
|
||||
defaultMessage:
|
||||
'Unlinking only changes your local copy. Future shared instance updates may restore or change it again.',
|
||||
},
|
||||
deleteSingleBody: {
|
||||
id: 'content.shared-instance.delete-single-body',
|
||||
defaultMessage:
|
||||
'Deleting it only changes your local copy. Future shared instance updates may restore or change it again.',
|
||||
},
|
||||
deleteBulkBody: {
|
||||
id: 'content.shared-instance.delete-bulk-body',
|
||||
defaultMessage:
|
||||
'Some selected projects are part of the shared instance. Deleting them only changes your local copy, and future shared instance updates may restore or change them again.',
|
||||
},
|
||||
deleteButton: { id: 'content.shared-instance.delete-button', defaultMessage: 'Delete anyway' },
|
||||
deleteManyButton: {
|
||||
id: 'content.shared-instance.delete-many-button',
|
||||
defaultMessage: 'Delete {count, number} projects anyway',
|
||||
},
|
||||
disableSingleBody: {
|
||||
id: 'content.shared-instance.disable-single-body',
|
||||
defaultMessage:
|
||||
'Disabling it only changes your local copy. Future shared instance updates may re-enable, restore, or change it again.',
|
||||
},
|
||||
disableBulkBody: {
|
||||
id: 'content.shared-instance.disable-bulk-body',
|
||||
defaultMessage:
|
||||
'Some selected projects are part of the shared instance. Disabling them only changes your local copy, and future shared instance updates may re-enable, restore, or change them again.',
|
||||
},
|
||||
disableButton: { id: 'content.shared-instance.disable-button', defaultMessage: 'Disable anyway' },
|
||||
disableManyButton: {
|
||||
id: 'content.shared-instance.disable-many-button',
|
||||
defaultMessage: 'Disable {count, number} projects anyway',
|
||||
},
|
||||
})
|
||||
@@ -1,148 +0,0 @@
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, type MaybeRefOrGetter, onUnmounted, toValue } from 'vue'
|
||||
|
||||
import { toError } from '@/helpers/errors'
|
||||
import { friend_listener } from '@/helpers/events.js'
|
||||
import {
|
||||
acceptCachedFriend,
|
||||
add_friend,
|
||||
createPendingFriend,
|
||||
type FriendCacheUser,
|
||||
friendsQueryKey,
|
||||
type FriendWithUserData,
|
||||
getFriendsWithUserData,
|
||||
getFriendUserId,
|
||||
matchesFriend,
|
||||
remove_friend,
|
||||
removeCachedFriend,
|
||||
upsertCachedFriend,
|
||||
} from '@/helpers/friends'
|
||||
import type { ModrinthCredentials } from '@/helpers/mr_auth'
|
||||
|
||||
type FriendsMutationContext = {
|
||||
queryKey: ReturnType<typeof friendsQueryKey>
|
||||
previousFriends?: FriendWithUserData[]
|
||||
}
|
||||
|
||||
type AddFriendMutationVariables = {
|
||||
userId: string
|
||||
user: FriendCacheUser
|
||||
acceptExisting: boolean
|
||||
}
|
||||
|
||||
type RemoveFriendMutationVariables = {
|
||||
userId: string
|
||||
user: FriendWithUserData
|
||||
}
|
||||
|
||||
export function useFriends(options: {
|
||||
currentUserId: MaybeRefOrGetter<string | null | undefined>
|
||||
getCredentials: () => ModrinthCredentials | null | Promise<ModrinthCredentials | null>
|
||||
enabled?: MaybeRefOrGetter<boolean>
|
||||
onError?: (error: Error) => void
|
||||
}) {
|
||||
const queryClient = useQueryClient()
|
||||
const queryKey = computed(() => friendsQueryKey(toValue(options.currentUserId)))
|
||||
const query = useQuery({
|
||||
queryKey,
|
||||
queryFn: async () => getFriendsWithUserData(await options.getCredentials()),
|
||||
enabled: () => !!toValue(options.currentUserId) && toValue(options.enabled ?? true),
|
||||
staleTime: 30_000,
|
||||
})
|
||||
const friends = computed(() => query.data.value ?? [])
|
||||
|
||||
function restore(context?: FriendsMutationContext) {
|
||||
if (!context) return
|
||||
if (context.previousFriends === undefined) {
|
||||
queryClient.removeQueries({ queryKey: context.queryKey, exact: true })
|
||||
return
|
||||
}
|
||||
queryClient.setQueryData(context.queryKey, context.previousFriends)
|
||||
}
|
||||
|
||||
const addMutation = useMutation({
|
||||
mutationFn: ({ userId }: AddFriendMutationVariables) => add_friend(userId),
|
||||
onMutate: async ({ user, acceptExisting }): Promise<FriendsMutationContext> => {
|
||||
const activeQueryKey = queryKey.value
|
||||
await queryClient.cancelQueries({ queryKey: activeQueryKey })
|
||||
const previousFriends = queryClient.getQueryData<FriendWithUserData[]>(activeQueryKey)
|
||||
const currentUserId = toValue(options.currentUserId)
|
||||
queryClient.setQueryData<FriendWithUserData[]>(activeQueryKey, (cachedFriends = []) =>
|
||||
acceptExisting
|
||||
? acceptCachedFriend(cachedFriends, user.id, user.username, currentUserId)
|
||||
: upsertCachedFriend(
|
||||
cachedFriends,
|
||||
createPendingFriend(user, currentUserId),
|
||||
currentUserId,
|
||||
),
|
||||
)
|
||||
return { queryKey: activeQueryKey, previousFriends }
|
||||
},
|
||||
onError: (error, _variables, context) => {
|
||||
restore(context)
|
||||
options.onError?.(toError(error))
|
||||
},
|
||||
onSettled: (_data, _error, _variables, context) => {
|
||||
void queryClient.invalidateQueries({ queryKey: context?.queryKey ?? queryKey.value })
|
||||
},
|
||||
})
|
||||
|
||||
const removeMutation = useMutation({
|
||||
mutationFn: ({ userId }: RemoveFriendMutationVariables) => remove_friend(userId),
|
||||
onMutate: async ({ user, userId }): Promise<FriendsMutationContext> => {
|
||||
const activeQueryKey = queryKey.value
|
||||
await queryClient.cancelQueries({ queryKey: activeQueryKey })
|
||||
const previousFriends = queryClient.getQueryData<FriendWithUserData[]>(activeQueryKey)
|
||||
queryClient.setQueryData<FriendWithUserData[]>(activeQueryKey, (cachedFriends = []) =>
|
||||
removeCachedFriend(cachedFriends, userId, user.username, toValue(options.currentUserId)),
|
||||
)
|
||||
return { queryKey: activeQueryKey, previousFriends }
|
||||
},
|
||||
onError: (error, _variables, context) => {
|
||||
restore(context)
|
||||
options.onError?.(toError(error))
|
||||
},
|
||||
onSettled: (_data, _error, _variables, context) => {
|
||||
void queryClient.invalidateQueries({ queryKey: context?.queryKey ?? queryKey.value })
|
||||
},
|
||||
})
|
||||
|
||||
function requestFriend(user: FriendCacheUser, acceptExisting = false) {
|
||||
addMutation.mutate({ userId: user.id, user, acceptExisting })
|
||||
}
|
||||
|
||||
function acceptFriend(friend: FriendWithUserData) {
|
||||
const userId = getFriendUserId(friend, toValue(options.currentUserId))
|
||||
requestFriend({ id: userId, username: friend.username, avatarUrl: friend.avatar }, true)
|
||||
}
|
||||
|
||||
function removeFriend(friend: FriendWithUserData) {
|
||||
const userId = getFriendUserId(friend, toValue(options.currentUserId))
|
||||
removeMutation.mutate({ userId, user: friend })
|
||||
}
|
||||
|
||||
function findFriend(id: string, username: string) {
|
||||
return friends.value.find((friend) =>
|
||||
matchesFriend(friend, id, username, toValue(options.currentUserId)),
|
||||
)
|
||||
}
|
||||
|
||||
let unlisten: (() => void) | undefined
|
||||
void friend_listener(() => {
|
||||
void queryClient.invalidateQueries({ queryKey: queryKey.value })
|
||||
}).then((listener) => {
|
||||
unlisten = listener
|
||||
})
|
||||
onUnmounted(() => unlisten?.())
|
||||
|
||||
return {
|
||||
query,
|
||||
queryKey,
|
||||
friends,
|
||||
loading: computed(() => !!toValue(options.currentUserId) && query.isLoading.value),
|
||||
requestFriend,
|
||||
acceptFriend,
|
||||
removeFriend,
|
||||
findFriend,
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed, type Ref } from 'vue'
|
||||
|
||||
import { get_user } from '@/helpers/cache.js'
|
||||
|
||||
export function useUserQuery(userId: Ref<string | null | undefined>) {
|
||||
return useQuery({
|
||||
queryKey: computed(() => ['user', userId.value]),
|
||||
queryFn: async ({ queryKey }) => {
|
||||
const id = queryKey[1]
|
||||
if (typeof id !== 'string') return null
|
||||
return await get_user(id, 'bypass').catch(() => null)
|
||||
},
|
||||
enabled: () => !!userId.value,
|
||||
staleTime: 30_000,
|
||||
})
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
export function toError(error: unknown) {
|
||||
if (error instanceof Error) return error
|
||||
if (typeof error === 'string') return new Error(error)
|
||||
if (error && typeof error === 'object') {
|
||||
const record = error as Record<string, unknown>
|
||||
const message = record.message ?? record.error
|
||||
if (typeof message === 'string') return new Error(message)
|
||||
return new Error(JSON.stringify(error))
|
||||
}
|
||||
return new Error(String(error))
|
||||
}
|
||||
@@ -6,8 +6,6 @@ import dayjs from 'dayjs'
|
||||
import { get_user_many } from '@/helpers/cache'
|
||||
import type { ModrinthCredentials } from '@/helpers/mr_auth'
|
||||
|
||||
export const friendsQueryKey = (userId?: string | null) => ['friends', userId ?? null] as const
|
||||
|
||||
export type UserStatus = {
|
||||
user_id: string
|
||||
instance_name: string | null
|
||||
@@ -48,111 +46,6 @@ export type FriendWithUserData = {
|
||||
online: boolean
|
||||
avatar: string
|
||||
}
|
||||
|
||||
export type FriendCacheUser = {
|
||||
id: string
|
||||
username: string
|
||||
avatarUrl?: string | null
|
||||
}
|
||||
|
||||
export async function getFriendsWithUserData(
|
||||
credentials: ModrinthCredentials | null,
|
||||
): Promise<FriendWithUserData[]> {
|
||||
if (!credentials) return []
|
||||
|
||||
const friendsList = await friends()
|
||||
return await transformFriends(friendsList, credentials)
|
||||
}
|
||||
|
||||
export function createPendingFriend(
|
||||
user: FriendCacheUser,
|
||||
currentUserId?: string | null,
|
||||
): FriendWithUserData {
|
||||
return {
|
||||
id: user.id,
|
||||
friend_id: currentUserId ?? null,
|
||||
status: null,
|
||||
last_updated: null,
|
||||
created: dayjs(),
|
||||
username: user.username,
|
||||
accepted: false,
|
||||
online: false,
|
||||
avatar: user.avatarUrl ?? '',
|
||||
}
|
||||
}
|
||||
|
||||
export function getFriendUserId(
|
||||
friend: Pick<FriendWithUserData, 'id' | 'friend_id'>,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
return friend.id === currentUserId && friend.friend_id ? friend.friend_id : friend.id
|
||||
}
|
||||
|
||||
export function matchesFriend(
|
||||
friend: FriendWithUserData,
|
||||
id: string,
|
||||
username: string,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
const friendId = getFriendUserId(friend, currentUserId)
|
||||
return (
|
||||
normalizeFriendKey(friendId) === normalizeFriendKey(id) ||
|
||||
normalizeFriendKey(friend.username) === normalizeFriendKey(username)
|
||||
)
|
||||
}
|
||||
|
||||
export function upsertCachedFriend(
|
||||
friends: FriendWithUserData[],
|
||||
friend: FriendWithUserData,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
const existingFriend = friends.find((cachedFriend) =>
|
||||
matchesFriend(cachedFriend, friend.id, friend.username, currentUserId),
|
||||
)
|
||||
|
||||
if (!existingFriend) return [friend, ...friends]
|
||||
|
||||
return friends.map((cachedFriend) =>
|
||||
matchesFriend(cachedFriend, friend.id, friend.username, currentUserId)
|
||||
? {
|
||||
...cachedFriend,
|
||||
...friend,
|
||||
id: cachedFriend.id,
|
||||
friend_id: cachedFriend.friend_id,
|
||||
}
|
||||
: cachedFriend,
|
||||
)
|
||||
}
|
||||
|
||||
export function acceptCachedFriend(
|
||||
friends: FriendWithUserData[],
|
||||
id: string,
|
||||
username: string,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
return friends.map((friend) =>
|
||||
matchesFriend(friend, id, username, currentUserId)
|
||||
? {
|
||||
...friend,
|
||||
accepted: true,
|
||||
}
|
||||
: friend,
|
||||
)
|
||||
}
|
||||
|
||||
export function removeCachedFriend(
|
||||
friends: FriendWithUserData[],
|
||||
id: string,
|
||||
username: string,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
return friends.filter((friend) => !matchesFriend(friend, id, username, currentUserId))
|
||||
}
|
||||
|
||||
export function normalizeFriendKey(value: string) {
|
||||
return value.trim().toLowerCase()
|
||||
}
|
||||
|
||||
export async function transformFriends(
|
||||
friends: UserFriend[],
|
||||
credentials: ModrinthCredentials | null,
|
||||
|
||||
@@ -27,6 +27,7 @@ export interface InstallModpackPreview {
|
||||
iconUrl?: string | null
|
||||
link?: InstanceLink | null
|
||||
unknownFile: boolean
|
||||
externalFilesInModpack: string[]
|
||||
}
|
||||
|
||||
export interface InstallCreateInstanceRequest {
|
||||
@@ -44,84 +45,6 @@ export interface InstallPostInstallEdit {
|
||||
link?: InstanceLink | null
|
||||
}
|
||||
|
||||
export interface SharedInstanceInstallPreview {
|
||||
name: string
|
||||
iconUrl?: string | null
|
||||
gameVersion: string
|
||||
loader: InstanceLoader
|
||||
modCount: number
|
||||
externalFileCount: number
|
||||
modpackVersionId?: string | null
|
||||
contentVersionIds: string[]
|
||||
externalFiles: SharedInstanceExternalFilePreview[]
|
||||
}
|
||||
|
||||
export interface SharedInstanceInviteInstallPreview {
|
||||
sharedInstanceId: string
|
||||
managerId?: string | null
|
||||
serverManagerName?: string | null
|
||||
serverManagerIconUrl?: string | null
|
||||
instanceIconUrl?: string | null
|
||||
preview: SharedInstanceInstallPreview
|
||||
}
|
||||
|
||||
export interface SharedInstanceExternalFilePreview {
|
||||
fileName: string
|
||||
fileType: string
|
||||
}
|
||||
|
||||
export interface SharedInstanceUpdatePreview {
|
||||
sharedInstanceId: string
|
||||
currentVersion?: number | null
|
||||
latestVersion: number
|
||||
updateAvailable: boolean
|
||||
diffs: SharedInstanceUpdateDiff[]
|
||||
}
|
||||
|
||||
export interface SharedInstanceUpdateDiff {
|
||||
type:
|
||||
| 'added'
|
||||
| 'removed'
|
||||
| 'updated'
|
||||
| 'modpack_linked'
|
||||
| 'modpack_updated'
|
||||
| 'modpack_unlinked'
|
||||
| 'game_version_updated'
|
||||
| 'loader_updated'
|
||||
projectId?: string | null
|
||||
projectName?: string | null
|
||||
fileName?: string | null
|
||||
currentVersionName?: string | null
|
||||
newVersionName?: string | null
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export const SHARED_INSTANCE_UNAVAILABLE_ERROR_CODE = 'shared_instance_unavailable'
|
||||
|
||||
export type SharedInstanceUnavailableReason = 'deleted' | 'access_revoked'
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null
|
||||
}
|
||||
|
||||
export function isSharedInstanceUnavailableError(error: unknown) {
|
||||
return getSharedInstanceUnavailableReason(error) !== null
|
||||
}
|
||||
|
||||
export function getSharedInstanceUnavailableReason(
|
||||
error: unknown,
|
||||
): SharedInstanceUnavailableReason | null {
|
||||
if (!isRecord(error) || error.code !== SHARED_INSTANCE_UNAVAILABLE_ERROR_CODE) return null
|
||||
return error.reason === 'deleted' || error.reason === 'access_revoked' ? error.reason : null
|
||||
}
|
||||
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
if (typeof error === 'string') return error
|
||||
if (error instanceof Error) return error.message || 'Unknown error'
|
||||
if (isRecord(error) && typeof error.message === 'string') return error.message
|
||||
return 'Unknown error'
|
||||
}
|
||||
|
||||
export type InstallJobStatus =
|
||||
| 'queued'
|
||||
| 'running'
|
||||
@@ -167,7 +90,6 @@ export interface InstallErrorView {
|
||||
code: string
|
||||
phase?: InstallPhaseId | null
|
||||
message: string
|
||||
reason?: SharedInstanceUnavailableReason | null
|
||||
api?: {
|
||||
error: string
|
||||
status?: number | null
|
||||
@@ -200,8 +122,6 @@ export interface InstallJobSnapshot {
|
||||
kind:
|
||||
| 'create_instance'
|
||||
| 'create_modpack_instance'
|
||||
| 'create_shared_instance'
|
||||
| 'update_shared_instance'
|
||||
| 'import_instance'
|
||||
| 'duplicate_instance'
|
||||
| 'install_existing_instance'
|
||||
@@ -252,58 +172,6 @@ export async function install_create_modpack_instance(
|
||||
})
|
||||
}
|
||||
|
||||
export async function install_get_shared_instance_preview(sharedInstanceId: string, name: string) {
|
||||
return await invoke<SharedInstanceInstallPreview>(
|
||||
'plugin:install|install_get_shared_instance_preview',
|
||||
{
|
||||
sharedInstanceId,
|
||||
name,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function install_accept_shared_instance_invite(inviteId: string) {
|
||||
return await invoke<SharedInstanceInviteInstallPreview>(
|
||||
'plugin:install|install_accept_shared_instance_invite',
|
||||
{
|
||||
inviteId,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function install_get_shared_instance_update_preview(instanceId: string) {
|
||||
return await invoke<SharedInstanceUpdatePreview | null>(
|
||||
'plugin:install|install_get_shared_instance_update_preview',
|
||||
{
|
||||
instanceId,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function install_shared_instance(
|
||||
sharedInstanceId: string,
|
||||
name: string,
|
||||
managerId?: string | null,
|
||||
serverManagerName?: string | null,
|
||||
serverManagerIconUrl?: string | null,
|
||||
instanceIconUrl?: string | null,
|
||||
) {
|
||||
return await invoke<InstallJobSnapshot>('plugin:install|install_shared_instance', {
|
||||
sharedInstanceId,
|
||||
name,
|
||||
managerId,
|
||||
serverManagerName,
|
||||
serverManagerIconUrl,
|
||||
instanceIconUrl,
|
||||
})
|
||||
}
|
||||
|
||||
export async function install_update_shared_instance(instanceId: string) {
|
||||
return await invoke<InstallJobSnapshot>('plugin:install|install_update_shared_instance', {
|
||||
instanceId,
|
||||
})
|
||||
}
|
||||
|
||||
export async function install_import_instance(
|
||||
launcherType: string,
|
||||
basePath: string,
|
||||
@@ -381,8 +249,7 @@ export function isInstallJobFinished(status: InstallJobStatus) {
|
||||
function settleInstallJob(job: InstallJobSnapshot) {
|
||||
if (job.status === 'succeeded') return job
|
||||
|
||||
if (job.error) throw job.error
|
||||
throw new Error(`Install job ${job.job_id} ${job.status}`)
|
||||
throw new Error(job.error?.message ?? `Install job ${job.job_id} ${job.status}`)
|
||||
}
|
||||
|
||||
export async function wait_for_install_job(jobId: string) {
|
||||
|
||||
@@ -7,14 +7,13 @@ import type { Labrinth } from '@modrinth/api-client'
|
||||
import type { ContentItem, ContentOwner } from '@modrinth/ui'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
import type { InstallJobSnapshot, SharedInstanceUpdateDiff } from './install'
|
||||
import type { InstallJobSnapshot } from './install'
|
||||
import type {
|
||||
CacheBehaviour,
|
||||
ContentFile,
|
||||
ContentFileProjectType,
|
||||
GameInstance,
|
||||
InstanceLoader,
|
||||
SharedInstanceAttachment,
|
||||
} from './types'
|
||||
|
||||
export async function remove(instanceId: string): Promise<void> {
|
||||
@@ -243,6 +242,10 @@ export async function add_project_from_path(
|
||||
})
|
||||
}
|
||||
|
||||
export async function is_file_on_modrinth(projectPath: string): Promise<boolean> {
|
||||
return await invoke('plugin:instance|instance_is_file_on_modrinth', { projectPath })
|
||||
}
|
||||
|
||||
// Toggle disabling a project
|
||||
export async function toggle_disable_project(
|
||||
instanceId: string,
|
||||
@@ -332,82 +335,3 @@ export async function edit(instanceId: string, editInstance: Partial<GameInstanc
|
||||
export async function edit_icon(instanceId: string, iconPath: string | null): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_edit_icon', { instanceId, iconPath })
|
||||
}
|
||||
|
||||
export type SharedInstanceUsers = {
|
||||
user_ids: string[]
|
||||
users: SharedInstanceUser[]
|
||||
tokens: number
|
||||
}
|
||||
|
||||
export type SharedInstanceJoinType = 'owner' | 'invite' | 'link'
|
||||
|
||||
export type SharedInstanceUser = {
|
||||
id: string
|
||||
joined_at?: string | null
|
||||
join_type: SharedInstanceJoinType
|
||||
last_played?: string | null
|
||||
}
|
||||
|
||||
export interface SharedInstancePublishPreview {
|
||||
sharedInstanceId: string
|
||||
latestVersion: number
|
||||
diffs: SharedInstanceUpdateDiff[]
|
||||
}
|
||||
|
||||
export interface SharedInstanceInviteLink {
|
||||
inviteId: string
|
||||
expiresAt: string
|
||||
maxUses: number
|
||||
}
|
||||
|
||||
export async function get_shared_instance_users(instanceId: string): Promise<SharedInstanceUsers> {
|
||||
return await invoke('plugin:instance|instance_share_get_users', { instanceId })
|
||||
}
|
||||
|
||||
export async function invite_shared_instance_users(
|
||||
instanceId: string,
|
||||
userIds: string[],
|
||||
): Promise<SharedInstanceUsers> {
|
||||
return await invoke('plugin:instance|instance_share_invite_users', { instanceId, userIds })
|
||||
}
|
||||
|
||||
export async function create_shared_instance_invite_link(
|
||||
instanceId: string,
|
||||
options: {
|
||||
maxAgeSeconds?: number
|
||||
maxUses?: number
|
||||
replaceInviteId?: string
|
||||
} = {},
|
||||
): Promise<SharedInstanceInviteLink> {
|
||||
return await invoke('plugin:instance|instance_share_create_invite_link', {
|
||||
instanceId,
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
export async function remove_shared_instance_users(
|
||||
instanceId: string,
|
||||
userIds: string[],
|
||||
): Promise<SharedInstanceUsers> {
|
||||
return await invoke('plugin:instance|instance_share_remove_users', { instanceId, userIds })
|
||||
}
|
||||
|
||||
export async function get_shared_instance_publish_preview(
|
||||
instanceId: string,
|
||||
): Promise<SharedInstancePublishPreview | null> {
|
||||
return await invoke('plugin:instance|instance_share_get_publish_preview', { instanceId })
|
||||
}
|
||||
|
||||
export async function publish_shared_instance(
|
||||
instanceId: string,
|
||||
): Promise<SharedInstanceAttachment> {
|
||||
return await invoke('plugin:instance|instance_share_publish', { instanceId })
|
||||
}
|
||||
|
||||
export async function unlink_shared_instance(instanceId: string): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_share_unlink', { instanceId })
|
||||
}
|
||||
|
||||
export async function unpublish_shared_instance(instanceId: string): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_share_unpublish', { instanceId })
|
||||
}
|
||||
|
||||
@@ -12,10 +12,8 @@ export type ModrinthCredentials = {
|
||||
active: boolean
|
||||
}
|
||||
|
||||
export type ModrinthAuthFlow = 'sign-in' | 'sign-up'
|
||||
|
||||
export async function login(flow: ModrinthAuthFlow = 'sign-in'): Promise<ModrinthCredentials> {
|
||||
return await invoke('plugin:mr-auth|modrinth_login', { flow })
|
||||
export async function login(): Promise<ModrinthCredentials> {
|
||||
return await invoke('plugin:mr-auth|modrinth_login')
|
||||
}
|
||||
|
||||
export async function logout(): Promise<void> {
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
import { defineMessages, injectNotificationManager, useVIntl } from '@modrinth/ui'
|
||||
|
||||
import { getErrorMessage, type SharedInstanceUnavailableReason } from '@/helpers/install'
|
||||
|
||||
export const sharedInstanceErrorMessages = defineMessages({
|
||||
unavailableTitle: {
|
||||
id: 'instance.shared-instance.unavailable.title',
|
||||
defaultMessage: 'Shared instance no longer available',
|
||||
},
|
||||
unavailableText: {
|
||||
id: 'instance.shared-instance.unavailable.text-v2',
|
||||
defaultMessage:
|
||||
"Your local instance is still available, but it is no longer linked and won't receive updates.",
|
||||
},
|
||||
deletedText: {
|
||||
id: 'instance.shared-instance.unavailable.deleted-text-v2',
|
||||
defaultMessage:
|
||||
"The shared instance was deleted. Your local instance is still available, but it is no longer linked and won't receive updates.",
|
||||
},
|
||||
accessRevokedText: {
|
||||
id: 'instance.shared-instance.unavailable.access-revoked-text-v2',
|
||||
defaultMessage:
|
||||
"Your access to the shared instance was revoked. Your local instance is still available, but it is no longer linked and won't receive updates.",
|
||||
},
|
||||
unavailableFallbackManager: {
|
||||
id: 'instance.shared-instance.unavailable.manager-fallback',
|
||||
defaultMessage: 'the instance manager',
|
||||
},
|
||||
errorTitle: {
|
||||
id: 'instance.shared-instance.error.title',
|
||||
defaultMessage: 'Something has gone wrong',
|
||||
},
|
||||
})
|
||||
|
||||
export function sharedInstanceUnavailableTextMessage(
|
||||
reason: SharedInstanceUnavailableReason | null,
|
||||
) {
|
||||
if (reason === 'deleted') return sharedInstanceErrorMessages.deletedText
|
||||
if (reason === 'access_revoked') return sharedInstanceErrorMessages.accessRevokedText
|
||||
return sharedInstanceErrorMessages.unavailableText
|
||||
}
|
||||
|
||||
export function useSharedInstanceErrors() {
|
||||
const { formatMessage } = useVIntl()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
function formatSharedInstanceUnavailable(
|
||||
reason: SharedInstanceUnavailableReason | null = null,
|
||||
manager?: string | null,
|
||||
) {
|
||||
return formatMessage(sharedInstanceUnavailableTextMessage(reason), {
|
||||
manager: manager || formatMessage(sharedInstanceErrorMessages.unavailableFallbackManager),
|
||||
})
|
||||
}
|
||||
|
||||
function notifySharedInstanceUnavailable(
|
||||
reason: SharedInstanceUnavailableReason | null = null,
|
||||
manager?: string | null,
|
||||
) {
|
||||
addNotification({
|
||||
type: 'warning',
|
||||
title: formatMessage(sharedInstanceErrorMessages.unavailableTitle),
|
||||
text: formatSharedInstanceUnavailable(reason, manager),
|
||||
})
|
||||
}
|
||||
|
||||
function notifySharedInstanceError(error: unknown) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
title: formatMessage(sharedInstanceErrorMessages.errorTitle),
|
||||
text: getErrorMessage(error),
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
formatSharedInstanceUnavailable,
|
||||
notifySharedInstanceError,
|
||||
notifySharedInstanceUnavailable,
|
||||
}
|
||||
}
|
||||
+1
-31
@@ -17,7 +17,6 @@ export type GameInstance = {
|
||||
groups: string[]
|
||||
|
||||
link?: InstanceLink | null
|
||||
shared_instance?: SharedInstanceAttachment | null
|
||||
update_channel: ReleaseChannel
|
||||
|
||||
created: Date
|
||||
@@ -87,47 +86,18 @@ export type InstanceLink = InstanceLinkIdentity &
|
||||
}
|
||||
| {
|
||||
type: 'shared_instance'
|
||||
modpack_project_id?: ModrinthId | null
|
||||
modpack_version_id?: ModrinthId | null
|
||||
shared_instance_id: string
|
||||
}
|
||||
)
|
||||
|
||||
export type SharedInstanceAttachment = {
|
||||
id: string
|
||||
role: 'owner' | 'member'
|
||||
manager_id?: string | null
|
||||
server_manager_name?: string | null
|
||||
server_manager_icon_url?: string | null
|
||||
linked_user_id?: string | null
|
||||
status:
|
||||
| 'unknown'
|
||||
| 'up_to_date'
|
||||
| 'update_available'
|
||||
| 'applying'
|
||||
| 'stale'
|
||||
| 'not_ready'
|
||||
| 'error'
|
||||
applied_version?: number | null
|
||||
latest_version?: number | null
|
||||
}
|
||||
|
||||
export type Instance = GameInstance
|
||||
|
||||
type ReleaseChannel = 'release' | 'beta' | 'alpha'
|
||||
|
||||
export type InstanceLoader = 'vanilla' | 'forge' | 'fabric' | 'quilt' | 'neoforge'
|
||||
|
||||
export type ContentSourceKind =
|
||||
| 'local'
|
||||
| 'modrinth_modpack'
|
||||
| 'server_project'
|
||||
| 'modrinth_hosting'
|
||||
| 'imported_modpack'
|
||||
| 'shared_instance'
|
||||
|
||||
type ContentFile = {
|
||||
enabled: boolean
|
||||
source_kind?: ContentSourceKind | null
|
||||
metadata?: {
|
||||
project_id: string
|
||||
version_id: string
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
export type SearchUser = {
|
||||
id: string
|
||||
username: string
|
||||
avatar_url: string | null
|
||||
}
|
||||
|
||||
export async function search_user(query: string): Promise<SearchUser[]> {
|
||||
return await invoke<SearchUser[]>('plugin:users|search_user', { query })
|
||||
}
|
||||
@@ -11,6 +11,87 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "إخفاء المزيد من الحالات قيد التشغيل"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "تم النسخ"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "نسخ التفاصيل"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "التجاهل"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "فتح المثيل"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "إعادة المحاولة"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "تم الإلغاء بسبب إغلاق التطبيق"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "تعذّر قراءة حزمة التعديلات"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "تم الإلغاء"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "لم تكتمل عملية التنظيف"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "تعذّر تنزيل الملفات"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "الملف الذي تم تنزيله تالف"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "تعذّر حفظ الملفات"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "لم يكتمل التنزيل"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "تعذّر العثور على المثيل"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "مسار الملف غير صالح"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "بيانات حزمة التعديلات غير صالحة"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "تحتوي ملفات حزمة التعديلات على بيانات وصفية غير صالحة"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "لم يكتمل إعداد Java"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "فشل إعداد أداة التحميل"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "تعذر تحديث البيانات المحلية"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "فشل إعداد Minecraft"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "لم أتمكن من الوصول إلى Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "لا يوجد إذن للكتابة"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "تعذر تنزيل الحزمة"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "حدث خطأ ما"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "مثيل غير معروف"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "عمليات التثبيت"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "إنشاء نسخة أساسية"
|
||||
},
|
||||
@@ -74,12 +155,63 @@
|
||||
"app.appearance-settings.hide-nametag.title": {
|
||||
"message": "إخفاء عرض الاسم"
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.description": {
|
||||
"message": "يتضمن العوالم الحديثة في قسم \"العودة إلى اللعب\" على الصفحة الرئيسية."
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.title": {
|
||||
"message": "العودة إلى العوالم"
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.description": {
|
||||
"message": "قم بتصغير نافذة المشغل عند بدء تشغيل عملية Minecraft."
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.title": {
|
||||
"message": "تصغير نافذة المشغل"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.description": {
|
||||
"message": "استخدام إطار نافذة النظام (يتطلب إعادة تشغيل التطبيق)."
|
||||
},
|
||||
"app.appearance-settings.native-decorations.title": {
|
||||
"message": "الزخارف التقليدية"
|
||||
},
|
||||
"app.appearance-settings.select-option": {
|
||||
"message": "حدد خياراً"
|
||||
},
|
||||
"app.appearance-settings.show-play-time.description": {
|
||||
"message": "يعرض مقدار الوقت الذي قضيته في لعب إحدى المهام."
|
||||
},
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "إظهار مدة التشغيل"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "يتخطى تلقائيًا عمليات التأكيد ذات المخاطر المنخفضة، مثل تثبيت حزم التعديلات المكررة، وحذف المحتوى العادي، والتحديثات الجماعية، وإلغاء ربط حزم التعديلات، ومطالبات الإصلاح. وسيستمر عرض التحذيرات الخطيرة."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "تخطي التحذيرات غير الضرورية"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "يتيح إمكانية إظهار الشريط الجانبي أو إخفائه."
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.title": {
|
||||
"message": "تبديل الشريط الجانبي"
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.description": {
|
||||
"message": "إذا حاولت تثبيت ملف Modrinth Pack (.mrpack) غير مستضاف على Modrinth، فسنتأكد من أنك على دراية بالمخاطر قبل تثبيته."
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.title": {
|
||||
"message": "أخبرني قبل تثبيت حزم التعديلات غير المعروفة"
|
||||
},
|
||||
"app.auth-servers.unreachable.body": {
|
||||
"message": "قد تكون خوادم مصادقة ماينكرافت معطلة حاليًا. تحقق من اتصالك بالإنترنت وحاول مرة أخرى لاحقًا."
|
||||
},
|
||||
"app.auth-servers.unreachable.header": {
|
||||
"message": "تعذر الوصول إلى خوادم المصادقة"
|
||||
},
|
||||
"app.browse.add-servers-to-instance": {
|
||||
"message": "إضافة خادم إلى المثيل"
|
||||
},
|
||||
"app.browse.add-to-an-instance": {
|
||||
"message": "إضافة إلى مثيل"
|
||||
},
|
||||
"app.browse.add-to-instance": {
|
||||
"message": "أضف للنموذج"
|
||||
},
|
||||
@@ -102,11 +234,20 @@
|
||||
"message": "استكشف خوادم"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "إخفاء الخوادم المضافة مسبقًا"
|
||||
"message": "إخفاء الخوادم التي تمت إضافتها بالفعل"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "حزم التعديل"
|
||||
},
|
||||
"app.browse.server-instance-content-warning": {
|
||||
"message": "قد تؤدي إضافة المحتوى إلى حدوث مشاكل في التوافق عند الاتصال بالخادم. كما سيُفقد أي محتوى تمت إضافته عند تحديث محتوى مثيل الخادم."
|
||||
},
|
||||
"app.browse.server.installing": {
|
||||
"message": "جاري التثبيت"
|
||||
},
|
||||
"app.content-install.no-compatible-versions": {
|
||||
"message": "لا توجد إصدارات متاحة تتوافق مع {compatibilityLabel}. اختر إصدارًا لتثبيته على أي حال. لن يتم تثبيت التبعيات تلقائيًا."
|
||||
},
|
||||
"app.export-modal.description-placeholder": {
|
||||
"message": "أدخل وصف التعديل..."
|
||||
},
|
||||
@@ -128,6 +269,60 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "تنزيل المحتوى"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "تنزيل لعبة Minecraft"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "تنزيل ملف الحزمة"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "استخراج التجاوزات"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "وضع اللمسات الأخيرة"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "في قائمة الانتظار للتثبيت"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "التحضير لـ Java"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "تنزيل Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "استخراج Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "جلب Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "التحضير لـ Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "التحقق من صحة إصدار Java {version}"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "قراءة قائمة المحتويات"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "معالج التحميل"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "حل مشكلة Minecraft"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "معالجة المحتوى"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "التراجع"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "تشغيل معالجات التحميل"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "سيتم حذف جميع البيانات الخاصة لنموذجك نهائيًا، بما في ذلك عوالمك والتكوينات وكل المحتوى المثبت."
|
||||
},
|
||||
@@ -152,6 +347,15 @@
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "النموذج"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "جاري تنزيل {current, number}/{total, number} مشروعًا..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "آخر المستجدات حول عملية التشطيب..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "تحديد الإصدارات..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "مشروع"
|
||||
},
|
||||
@@ -176,6 +380,18 @@
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "تصفح الخوادم"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "حذف العالم"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "حذف العالم"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "سيتم حذف هذا العالم نهائيًا من هذه النسخة. لا يمكن التراجع عن هذا الإجراء."
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "حذف {name}"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "معدّل"
|
||||
},
|
||||
@@ -194,12 +410,21 @@
|
||||
"app.instance.worlds.no-worlds-heading": {
|
||||
"message": "لم تتم إضافة أي من الخوادم أو العوالم"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.remove-button": {
|
||||
"message": "إزالة الخادم"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.title": {
|
||||
"message": "إزالة الخادم"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-body": {
|
||||
"message": "سيتم حذف هذا الخادم من قائمة الخوادم الخاصة بك ومن قائمة الخوادم داخل اللعبة. يمكنك إضافته مرة أخرى لاحقًا إذا كنت تعرف عنوانه."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "إزالة {name}"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "ابحث بين ال{count} عوالم..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "المحتوى مطلوب"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "نزل للعب"
|
||||
},
|
||||
@@ -209,36 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# تعديل} other {# تعديلات}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "حُزْمَة التعديل مطلوبة"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "يتطلب هذا الخادم تعديلات للعب. انقر فوق \"تثبيت\" لإعداد الملفات المطلوبة من Modrinth، ثم قم بتشغيله مباشرة إلى الخادم."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "النماذج المشتركة"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "نماذج الخادم مشتركة"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "عرض المحتويات"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "حدث للعب"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "يلزم التحديث"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "هناك تحديث مطلوب للعب بـ {name}. الرجاء التحديث إلى أحدث اصدار لتشغيل اللعبة."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "هذا المشروع مُثبَّت بالفعل"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "تغيير الإصدار"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "العودة إلى الاستكشاف"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "تثبيت المحتويات الى النموذج"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "جميع الإصدارات"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "التنزيل من المتصفح"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "التثبيت"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "مثبت بالفعل"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "تم تفعيل وضع المطوّر."
|
||||
},
|
||||
@@ -281,6 +512,12 @@
|
||||
"app.skins.delete-modal.title": {
|
||||
"message": "هل أنت متأكد من حذف المظهر هذا؟"
|
||||
},
|
||||
"app.skins.dropped-file-error.text": {
|
||||
"message": "فشل قراءة الملف الذي تم إسقاطه."
|
||||
},
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "حدث خطأ أثناء معالجة الملف"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "تعديل المظهر"
|
||||
},
|
||||
@@ -290,6 +527,15 @@
|
||||
"app.skins.modal.add-title": {
|
||||
"message": "إضافة المظهر"
|
||||
},
|
||||
"app.skins.modal.arm-style-section": {
|
||||
"message": "طراز الأذرع"
|
||||
},
|
||||
"app.skins.modal.arm-style-slim": {
|
||||
"message": "نحيف"
|
||||
},
|
||||
"app.skins.modal.arm-style-wide": {
|
||||
"message": "عريض"
|
||||
},
|
||||
"app.skins.modal.cape-fallback-name": {
|
||||
"message": "رداء"
|
||||
},
|
||||
@@ -308,12 +554,18 @@
|
||||
"app.skins.modal.none-cape-option": {
|
||||
"message": "لا شيء"
|
||||
},
|
||||
"app.skins.modal.replace-texture-button": {
|
||||
"message": "استبدال النسيج"
|
||||
},
|
||||
"app.skins.modal.save-skin-button": {
|
||||
"message": "حفظ المظهر"
|
||||
},
|
||||
"app.skins.modal.saving-tooltip": {
|
||||
"message": "حفظ..."
|
||||
},
|
||||
"app.skins.modal.texture-section": {
|
||||
"message": "النسيج"
|
||||
},
|
||||
"app.skins.modal.upload-skin-first-tooltip": {
|
||||
"message": "أرفع المظهر أولا !"
|
||||
},
|
||||
@@ -323,9 +575,69 @@
|
||||
"app.skins.previewing-badge": {
|
||||
"message": "أستعراض"
|
||||
},
|
||||
"app.skins.rate-limit.text": {
|
||||
"message": "أنت تقوم بتغيير مظهرك بشكل متكرر جدًّا. وقد قامت خوادم Mojang بحظر الطلبات الإضافية مؤقتًا. يرجى الانتظار قليلاً قبل إعادة المحاولة."
|
||||
},
|
||||
"app.skins.rate-limit.title": {
|
||||
"message": "تمهل !"
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "تعذر حفظ طلبك المتعلق بشكل الشخصية."
|
||||
},
|
||||
"app.skins.reorder-error.title": {
|
||||
"message": "فشل إعادة ترتيب أشكال الشخصيات"
|
||||
},
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "البناة والبيئات الحيوية"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "الفوضى المربعة"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "انطلق نحو السماء"
|
||||
},
|
||||
"app.skins.section.default-skins": {
|
||||
"message": "شكل الشخصية الافتراضية"
|
||||
},
|
||||
"app.skins.section.minecon-earth-2017": {
|
||||
"message": "MINECON Earth 2017"
|
||||
},
|
||||
"app.skins.section.modrinth": {
|
||||
"message": "Modrinth"
|
||||
},
|
||||
"app.skins.section.modrinth-pride": {
|
||||
"message": "فخر Modrinth"
|
||||
},
|
||||
"app.skins.section.modrinth-pride.tooltip": {
|
||||
"message": "لقد حصلت على هذه أشكال الشخصيات مقابل تبرعك لحملة جمع التبرعات التي نظمتها Modrinth Pride خلال شهر الفخر."
|
||||
},
|
||||
"app.skins.section.mounts-of-mayhem": {
|
||||
"message": "جبال الفوضى"
|
||||
},
|
||||
"app.skins.section.saved-skins": {
|
||||
"message": "المظاهر المحفوظة"
|
||||
},
|
||||
"app.skins.section.striding-hero": {
|
||||
"message": "البطل السائر بخطوات واسعة"
|
||||
},
|
||||
"app.skins.section.the-copper-age": {
|
||||
"message": "العصر النحاسي"
|
||||
},
|
||||
"app.skins.section.the-garden-awakens": {
|
||||
"message": "الحديقة تستيقظ"
|
||||
},
|
||||
"app.skins.section.tiny-takeover": {
|
||||
"message": "الاستحواذ الصغير"
|
||||
},
|
||||
"app.skins.sign-in.button": {
|
||||
"message": "تسجيل الدخول"
|
||||
},
|
||||
"app.skins.sign-in.description": {
|
||||
"message": "يرجى تسجيل الدخول إلى حسابك في Minecraft لاستخدام ميزات إدارة أشكال الشخصيات في تطبيق Modrinth."
|
||||
},
|
||||
"app.skins.sign-in.rinthbot-alt": {
|
||||
"message": "روبوت Modrinth المتحمس"
|
||||
},
|
||||
"app.skins.sign-in.title": {
|
||||
"message": "الرجاء تسجيل الدخول"
|
||||
},
|
||||
@@ -350,6 +662,9 @@
|
||||
"app.update-popup.download-complete": {
|
||||
"message": "اكتمل التنزيل"
|
||||
},
|
||||
"app.update-popup.reload": {
|
||||
"message": "أعد التحميل للتحديث"
|
||||
},
|
||||
"app.update-popup.title": {
|
||||
"message": "تحديث متاح"
|
||||
},
|
||||
@@ -548,6 +863,30 @@
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "الاسم"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel": {
|
||||
"message": "تحديث القناة"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha": {
|
||||
"message": "نسخة أولية"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha.description": {
|
||||
"message": "ستظهر الإصدارات النهائية والإصدارات التجريبية والإصدارات الأولية كـ«تحديثات متاحة»."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "بيتا"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta.description": {
|
||||
"message": "ستظهر الإصدارات النهائية والإصدارات التجريبية كـ«تحديثات متاحة»."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release": {
|
||||
"message": "إصدار ثابت"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release.description": {
|
||||
"message": "لن تظهر سوى الإصدارات النهائية ضمن التحديثات المتاحة."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.select": {
|
||||
"message": "اختر قناة التحديث"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "إجراءات تشغيل إضافية"
|
||||
},
|
||||
@@ -596,6 +935,24 @@
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "جافا والذاكرة"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-environment-variables": {
|
||||
"message": "متغيرات البيئة المخصصة"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-java-arguments": {
|
||||
"message": "معلمات Java المخصصة"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-java-installation": {
|
||||
"message": "تثبيت Java المخصص"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-memory-allocation": {
|
||||
"message": "تخصيص الذاكرة حسب الطلب"
|
||||
},
|
||||
"instance.settings.tabs.java.enter-environment-variables": {
|
||||
"message": "أدخل المتغيرات البيئية..."
|
||||
},
|
||||
"instance.settings.tabs.java.enter-java-arguments": {
|
||||
"message": "أدخل معلمات Java..."
|
||||
},
|
||||
"instance.settings.tabs.java.environment-variables": {
|
||||
"message": "المتغيرات البيئية"
|
||||
},
|
||||
@@ -653,6 +1010,9 @@
|
||||
"instance.worlds.copy_address": {
|
||||
"message": "نسخ العنوان"
|
||||
},
|
||||
"instance.worlds.create_shortcut": {
|
||||
"message": "إنشاء اختصار"
|
||||
},
|
||||
"instance.worlds.dont_show_on_home": {
|
||||
"message": "عدم العرض في الصفحة الرئيسية"
|
||||
},
|
||||
@@ -692,6 +1052,12 @@
|
||||
"minecraft-account.label": {
|
||||
"message": "حساب ماينكرافت"
|
||||
},
|
||||
"minecraft-account.not-signed-in": {
|
||||
"message": "لم يتم تسجيل الدخول"
|
||||
},
|
||||
"minecraft-account.remove-account": {
|
||||
"message": "حذف الحساب"
|
||||
},
|
||||
"minecraft-account.select-account": {
|
||||
"message": "اختيار الحساب"
|
||||
},
|
||||
@@ -721,8 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "يتم توفير المحمّل من قبل الخادم"
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "لا تعرض هذا التحذير مجددا"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Skrýt více spuštěných instancí"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Zkopírováno"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Zavřít"
|
||||
},
|
||||
@@ -20,6 +23,9 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Zkusit znovu"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Zrušeno"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Neznámá instance"
|
||||
},
|
||||
@@ -167,9 +173,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Objevit servery"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Skrýt již přidané servery"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacky"
|
||||
},
|
||||
@@ -219,7 +222,7 @@
|
||||
"message": "Dokončení instalace"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Příprava instance"
|
||||
"message": "Ve frontě na instalaci"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Příprava Javy"
|
||||
@@ -359,9 +362,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Hledat v {count} světech..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Požadovaný obsah"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Nainstaluj pro hraní"
|
||||
},
|
||||
@@ -371,39 +371,39 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mód} few {# módy} other {# módů}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Požadovaný modpack"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Tento server k hraní vyžaduje módy. Klikni na instalovat pro získání potřebných módů z Modrinth a poté se rovnou připoj na server."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Sdílená instance"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Sdílená serverová instance"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Zobrazit obsah"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Aktualizuj pro hraní"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Je vyžadována aktualizace"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Pro hraní {name} je vyžadována aktualizace. Prosím aktualizuj na nejnovější verzi, abys mohl hru spustit."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Tento projekt je již nainstalován"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Změnit verzi"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Zpět k Objevování"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Nainstalovat obsah do instance"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Všechny verze"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Stáhnout v prohlížeči"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Již staženo"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Vývojářský režim povolen."
|
||||
},
|
||||
@@ -524,6 +524,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -1018,26 +1021,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader zprostředkovává server"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Soubor je zkontrolován pouze v případě, že je nahrán na Modrinth, bez ohledu na jeho formát (včetně formátu .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Toto varování znovu nezobrazovat"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Potvrdit instalaci"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Přesto nainstalovat"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Malware se často šíří prostřednictvím souborů s modpacky, které se sdílejí na platformách jako Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Tento soubor jsme na Modrinthu nenašli. Důrazně doporučujeme instalovat pouze soubory z důvěryhodných zdrojů."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Upozornění na neznámý soubor"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,18 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Gem flere kørende instances"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Tilsidesæt"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Åben instance"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Prøv igen"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Ukendt instance"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Gør til primære instance"
|
||||
},
|
||||
@@ -141,7 +153,7 @@
|
||||
"message": "Opdag servere"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Gem allerede tilføjet til servere"
|
||||
"message": "Gem servere som allerede er tilføjet"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacks"
|
||||
@@ -165,7 +177,7 @@
|
||||
"message": "Eksporter modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Modpack Navn"
|
||||
"message": "Modpack navn"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Modpack navn"
|
||||
@@ -176,6 +188,15 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Downloader indhold"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Downloader Minecraft"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Downloader Java {version}"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Al' data for din instance vil blive permanent slettet, dette inkludere dine verdener, konfigurationer, og alt installeret indhold."
|
||||
},
|
||||
@@ -200,6 +221,9 @@
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "Instance"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "Downloader {current, number}/{total, number} projekter..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "projekt"
|
||||
},
|
||||
@@ -245,9 +269,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Søg {count} verdener..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Indhold krævet"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installer for at spille"
|
||||
},
|
||||
@@ -257,27 +278,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Modpack krævet"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Denne server kræver mods for at spille. Tryk på installer for at sætte de krævet filler fra modrinth op, så lancer direkte til serveren."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Delt instance"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Delt server instance"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Vis indhold"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Opdater for at spille"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Opdatering krævet"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "En opdatering er krævet for at spille {name}. Venligst opdater til den seneste version for at køre spillet."
|
||||
},
|
||||
@@ -290,6 +299,9 @@
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Installer indhold til instance"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Allerede installeret"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Udvikler-tilstand aktiveret."
|
||||
},
|
||||
@@ -395,6 +407,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -464,6 +479,9 @@
|
||||
"app.update-popup.download-complete": {
|
||||
"message": "Download færdiggjort"
|
||||
},
|
||||
"app.update-popup.reload": {
|
||||
"message": "Genindlæs for at opdater"
|
||||
},
|
||||
"app.update-popup.title": {
|
||||
"message": "Opdatering tilgængelig"
|
||||
},
|
||||
@@ -662,6 +680,12 @@
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "Navn"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha": {
|
||||
"message": "Alpha"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "Beta"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "Startkommandoer"
|
||||
},
|
||||
@@ -844,20 +868,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader er givet af serveren"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "En fil behandles kun, hvis den uploades til Modrinth, uanset filformat (herunder .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Vis ikke denne advarsel igen"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Bekræft installation"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Installer alligevel"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Ukendt fil advarsel"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Weitere laufende Instanzen ausblenden"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Kopiert"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Details kopieren"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Ignorieren"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Wiederholen"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Aufgrund von Schließung der App abgebrochen"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Modpack konnte nicht gelesen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Abgebrochen"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "Bereinigung konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Dateien konnte nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Heruntergeladene Datei ist beschädigt"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Dateien konnten nicht gespeichert werden"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Download konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Instanz konnte nicht gefunden werden"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Dateipfad ist ungültig"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Daten des Modpacks sind ungültig"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Dateien des Modpacks enthalten ungültige Metadaten"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Die Einrichtung von Java konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Einrichtung des Loaders ist fehlgeschlagen"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Lokale Daten konnten nicht aktualisiert werden"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Einrichtung von Minecraft ist fehlgeschlagen"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Modrinth konnte nicht erreicht werden"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Keine Berechtigung zum Schreiben"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Das Pack konnte nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Irgendwas ist schiefgelaufen"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Unbekannte Instanz"
|
||||
},
|
||||
@@ -117,10 +183,10 @@
|
||||
"message": "Spielzeit anzeigen"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Überspringt automatisch Bestätigungen mit geringem Risiko, wie z. B. die doppelte Installation von Modpacks, das Löschen normaler Inhalte, Massenaktualisierungen, das Trennen von Modpacks und Reparaturen. Warnungen bei gefährlichen Aktionen werden weiterhin angezeigt."
|
||||
"message": "Bestätigungen mit geringem Risiko, wie z. B. die Installation doppelter Modpacks, das Löschen normaler Inhalte, Massenaktualisierungen, das Aufheben von Verknüpfungen zu Modpacks und Reparaturaufrufe, werden automatisch übersprungen. Gefährliche Warnungen werden weiterhin angezeigt."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Nicht essenzielle Warnungen überspringen"
|
||||
"message": "Unwichtige Warnungen überspringen"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Ermöglicht das Umschalten der Seitenleiste."
|
||||
@@ -192,7 +258,7 @@
|
||||
"message": "Modpack exportieren"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Modpaketname"
|
||||
"message": "Name des Modpacks"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Modpaketname"
|
||||
@@ -204,40 +270,40 @@
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Lade Inhalte herunter"
|
||||
"message": "Inhalte werden heruntergeladen"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Lade Minecraft herunter"
|
||||
"message": "Minecraft wird heruntergeladen"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Lade Packdatei herunter"
|
||||
"message": "Paketdatei wird herunterladen"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Überschreibungen extrahieren"
|
||||
"message": "Überschreibungen werden extrahiert"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Abschliessen"
|
||||
"message": "Wird finalisiert"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Instanz präparieren"
|
||||
"message": "Installation in Warteschlange"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Java präparieren"
|
||||
"message": "Java wird vorbereitet"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Java {version} herunterladen"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Java {version} extrahieren"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Java {version} wird heruntergeladen"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Java {version} wird extrahiert"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Java {version} wird abgerufen"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Java {version} präparieren"
|
||||
"message": "Java {version} wird vorbereitet"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "Java {version} validieren"
|
||||
"message": "Java {version} wird validiert"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Paketmanifest wird gelesen"
|
||||
@@ -282,10 +348,10 @@
|
||||
"message": "Instanz"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "Lade {current, number}/{total, number} Projekte..."
|
||||
"message": "{current, number}/{total, number} Projekte werden heruntergeladen..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "Update abschliessen..."
|
||||
"message": "Update wird fertiggestellt..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "Versionen werden ermittelt..."
|
||||
@@ -321,7 +387,7 @@
|
||||
"message": "Welt löschen"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "Diese Welt wird permanent gelöscht von dieser Instanz, dies kann nicht rückgängig gemacht werden."
|
||||
"message": "Diese Welt wird permanent von dieser Instanz gelöscht. Diese Aktion kann nicht rückgängig gemacht werden."
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "Lösche {name}"
|
||||
@@ -359,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Durchsuche {count} Welten..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Inhalte benötigt"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installieren zum Spielen"
|
||||
},
|
||||
@@ -371,39 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# Mod} other {# Mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Benötigtes Modpack"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Dieser Server benötigt Mods zum spielen. Klicke auf Installieren um die nötigen Dateien von Modrinth herunterzuladen und dannach direkt dem Server beizutreten."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Geteilte Instanz"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Geteilte Server Instanz"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Inhalte ansehen"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Aktualisieren zum Spielen"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Aktualisierung benötigt"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Eine aktualisierung zum spielen von {name} ist benötigt. Bitte aktualisiere auf die neuste Version um das Spiel zu starten."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Dieses Projekt ist bereits installiert"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Version wechseln"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Zurück zu Entdecken"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Inhalt in Instanz installieren"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Alle Versionen"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Im Browser herunterladen"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Wird installiert"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Bereits installiert"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Entwicklermodus aktiviert."
|
||||
},
|
||||
@@ -524,6 +590,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -1018,26 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader wird vom Server bereitgestellt"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Eine Datei wird nur geprüft, wenn sie auf Modrinth hochgeladen wird, unabhängig von ihrem Dateiformat (auch .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Diese Warnung nicht mehr anzeigen"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Installation bestätigen"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Trotzdem installieren"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Schadsoftware wird häufig über Modpack-Dateien verbreitet, indem diese auf Plattformen wie Discord geteilt werden."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Wir konnten diese Datei auf Modrinth nicht finden. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Warnung vor unbekannter Datei"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Weitere laufende Instanzen ausblenden"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Kopiert"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Details kopieren"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Ausblenden"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Erneut versuchen"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Aufgrund von Schließung der App abgebrochen"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Modpack konnte nicht gelesen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Abgebrochen"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "Bereinigung konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Dateien konnte nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Heruntergeladene Datei ist beschädigt"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Dateien konnten nicht gespeichert werden"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Download konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Instanz konnte nicht gefunden werden"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Dateipfad ist ungültig"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Daten des Modpacks sind ungültig"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Dateien des Modpacks enthalten ungültige Metadaten"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Die Einrichtung von Java konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Einrichtung des Loaders ist fehlgeschlagen"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Lokale Daten konnten nicht aktualisiert werden"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Einrichtung von Minecraft ist fehlgeschlagen"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Modrinth konnte nicht erreicht werden"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Keine Berechtigung zum Schreiben"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Das Pack konnte nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Irgendwas ist schiefgelaufen"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Unbekannte Instanz"
|
||||
},
|
||||
@@ -102,7 +168,7 @@
|
||||
"message": "Launcher minimieren"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.description": {
|
||||
"message": "Fensterdekorationen des Systems verwenden (Neustart der App erforderlich)."
|
||||
"message": "Fensterrahmen des Systems verwenden (Neustart der App erforderlich)."
|
||||
},
|
||||
"app.appearance-settings.native-decorations.title": {
|
||||
"message": "Native Dekorationen"
|
||||
@@ -117,7 +183,7 @@
|
||||
"message": "Spielzeit anzeigen"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Überspringt automatisch Bestätigungen mit geringem Risiko, wie z. B. die doppelte Installation von Modpacks, das Löschen normaler Inhalte, Massenaktualisierungen, das Trennen von Modpacks und Reparaturen. Warnungen bei gefährlichen Aktionen werden weiterhin angezeigt."
|
||||
"message": "Bestätigungen mit geringem Risiko, wie z. B. die Installation doppelter Modpacks, das Löschen normaler Inhalte, Massenaktualisierungen, das Aufheben von Verknüpfungen zu Modpacks und Reparaturaufrufe, werden automatisch übersprungen. Gefährliche Warnungen werden weiterhin angezeigt."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Unwichtige Warnungen überspringen"
|
||||
@@ -192,10 +258,10 @@
|
||||
"message": "Modpack exportieren"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Modpackname"
|
||||
"message": "Name des Modpacks"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Modpackname"
|
||||
"message": "Name des Modpacks"
|
||||
},
|
||||
"app.export-modal.version-number-label": {
|
||||
"message": "Versionsnummer"
|
||||
@@ -219,7 +285,7 @@
|
||||
"message": "Wird finalisiert"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Instanz wird vorbereitet"
|
||||
"message": "Installation in Warteschlange"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Java wird vorbereitet"
|
||||
@@ -231,7 +297,7 @@
|
||||
"message": "Java {version} wird extrahiert"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Java {version} wird heruntergeladen"
|
||||
"message": "Java {version} wird abgerufen"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Java {version} wird vorbereitet"
|
||||
@@ -359,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Durchsuche {count} Welten..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Inhalte benötigt"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installieren zum Spielen"
|
||||
},
|
||||
@@ -371,39 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# Mod} other {# Mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Benötigtes Modpack"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Dieser Server benötigt Mods zum Spielen. Klicke auf Installieren um die nötigen Dateien von Modrinth herunterzuladen und danach direkt dem Server beizutreten."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Geteilte Instanz"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Geteilte Serverinstanz"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Inhalte ansehen"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Aktualisieren zum Spielen"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Aktualisierung erforderlich"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Zum Spielen von {name} ist eine Aktualisierung erforderlich. Bitte aktualisiere auf die neueste Version, um das Spiel zu starten."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Dieses Projekt ist bereits installiert"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Version wechseln"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Zurück zum Entdecken"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Inhalt in Instanz installieren"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Alle Versionen"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Im Browser herunterladen"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Wird installiert"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Bereits installiert"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Entwicklermodus aktiviert."
|
||||
},
|
||||
@@ -524,6 +590,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -576,7 +645,7 @@
|
||||
"message": "Skin-Auswahl"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} wurde heruntergeladen. Neu laden, um jetzt zu aktualisieren, oder automatisch aktualisieren, wenn du die Modrinth App schließt."
|
||||
"message": "Modrinth App v{version} wurde heruntergeladen. Jetzt neu laden, um sofort zu aktualisieren, oder beim Schließen der Modrinth-App automatisch aktualisieren."
|
||||
},
|
||||
"app.update-popup.body.linux": {
|
||||
"message": "Modrinth App v{version} ist verfügbar. Verwende deinen Paketmanager, um die neuesten Funktionen und Fehlerbehebungen zu installieren!"
|
||||
@@ -609,7 +678,7 @@
|
||||
"message": "example.modrinth.gg"
|
||||
},
|
||||
"app.world.server-modal.select-an-option": {
|
||||
"message": "Wählen eine Option"
|
||||
"message": "Wähle eine Option"
|
||||
},
|
||||
"app.world.world-item.incompatible-version": {
|
||||
"message": "Inkompatible Version {version}"
|
||||
@@ -1018,26 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader vom Server vorgegeben"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Eine Datei wird nur geprüft, wenn sie auf Modrinth hochgeladen wird, unabhängig von ihrem Dateiformat (auch .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Diese Warnung nicht mehr anzeigen"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Installation bestätigen"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Trotzdem installieren"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Schadsoftware wird häufig über Modpack-Dateien verbreitet, indem diese auf Plattformen wie Discord geteilt werden."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Wir konnten diese Datei auf Modrinth nicht finden. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Warnung vor unbekannter Datei"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,9 +89,6 @@
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Unknown instance"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Updating shared content"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Installs"
|
||||
},
|
||||
@@ -326,36 +323,6 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Running loader processors"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Added"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "Your local instance is ahead of the users you've shared it with."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "Your changes haven't been shared yet"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Push update"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Pushing..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Removed"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Push update"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "Review the content changes that will be shared with everyone using this instance."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Review changes"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Reviewing..."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "All data for your instance will be permanently deleted, including your worlds, configs, and all installed content."
|
||||
},
|
||||
@@ -407,90 +374,6 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Successfully uploaded"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "You can share this instance with your friends!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "No friends invited"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Invite friends"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "Share {name}"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "You need to sign in as"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "to access this page."
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "the linked account"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "Not signed in"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Switch account"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Wrong account"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-access": {
|
||||
"message": "They will no longer receive updates for this shared instance"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-installed-copy": {
|
||||
"message": "Any copy they already installed will stay on their device"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-invite-again": {
|
||||
"message": "You can invite them again later"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-last-user": {
|
||||
"message": "If this is the last user, sharing will be turned off for this instance"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "What happens?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "Revoke access"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "Revoke access"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "{username}'s avatar"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "If you revoke {username}'s access to this shared instance, you'll need to invite them again before they can receive updates."
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Sign in"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "You must unlink this modpack to share your instance"
|
||||
},
|
||||
"app.instance.share.unlink.header": {
|
||||
"message": "Sharing requires unlinking"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "the linked account"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.owner-admonition-body-v2": {
|
||||
"message": "to manage this shared instance. You won't be able to push updates to users."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Sign in as"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "You need to sign in to Modrinth"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "to receive updates for this shared instance."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.warning-header": {
|
||||
"message": "You are using the wrong Modrinth account"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Add server"
|
||||
},
|
||||
@@ -542,41 +425,38 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Search {count} worlds..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Content required"
|
||||
},
|
||||
"app.modal.install-to-play.external-file-warning": {
|
||||
"message": "{count, plural, one {This instance includes # file that is not from Modrinth.} other {This instance includes # files that are not from Modrinth.}}"
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Dont install"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Install to play"
|
||||
},
|
||||
"app.modal.install-to-play.install-anyway": {
|
||||
"message": "Install anyway"
|
||||
},
|
||||
"app.modal.install-to-play.install-button": {
|
||||
"message": "Install"
|
||||
},
|
||||
"app.modal.install-to-play.invite-warning": {
|
||||
"message": "This invite was created by another Modrinth user, not Modrinth. Only accept invites from people you trust."
|
||||
},
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Required modpack"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "This server requires mods to play. Click Install to set up the required files from Modrinth, then launch directly into the server."
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "A file is only reviewed if it’s published to Modrinth, regardless of its file format (including .mrpack)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Shared instance"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-content": {
|
||||
"message": "Shared instance content"
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "This server modpack contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust."
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Shared server instance"
|
||||
"app.modal.install-to-play.unknown-files-warning": {
|
||||
"message": "Unknown files warning"
|
||||
},
|
||||
"app.modal.install-to-play.trust-warning-description": {
|
||||
"message": "A shared instance will install files on your computer and may include content not from Modrinth."
|
||||
},
|
||||
"app.modal.install-to-play.trust-warning-header": {
|
||||
"message": "Do you trust this user?"
|
||||
"app.modal.install-to-play.unrecognized-files": {
|
||||
"message": "Unrecognized files"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "View contents"
|
||||
@@ -584,17 +464,11 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Update to play"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-added-label": {
|
||||
"message": "Added"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-removed-label": {
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Removed"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Update required"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "An update is required to play {name}. Please update to latest version to launch the game."
|
||||
"message": "An update is required to play {name}. Please update to the latest version to launch the game."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "This project is already installed"
|
||||
@@ -842,39 +716,6 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} online"
|
||||
},
|
||||
"content.shared-instance.change-version-body": {
|
||||
"message": "Changing the version only changes your local copy. Future shared instance updates may restore or change it again."
|
||||
},
|
||||
"content.shared-instance.delete-bulk-body": {
|
||||
"message": "Some selected projects are part of the shared instance. Deleting them only changes your local copy, and future shared instance updates may restore or change them again."
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "Delete anyway"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "Delete {count, number} projects anyway"
|
||||
},
|
||||
"content.shared-instance.delete-single-body": {
|
||||
"message": "Deleting it only changes your local copy. Future shared instance updates may restore or change it again."
|
||||
},
|
||||
"content.shared-instance.disable-bulk-body": {
|
||||
"message": "Some selected projects are part of the shared instance. Disabling them only changes your local copy, and future shared instance updates may re-enable, restore, or change them again."
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "Disable anyway"
|
||||
},
|
||||
"content.shared-instance.disable-many-button": {
|
||||
"message": "Disable {count, number} projects anyway"
|
||||
},
|
||||
"content.shared-instance.disable-single-body": {
|
||||
"message": "Disabling it only changes your local copy. Future shared instance updates may re-enable, restore, or change it again."
|
||||
},
|
||||
"content.shared-instance.unlink-body": {
|
||||
"message": "Unlinking only changes your local copy. Future shared instance updates may restore or change it again."
|
||||
},
|
||||
"content.shared-instance.warning-header": {
|
||||
"message": "This is part of the shared instance"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Add a friend"
|
||||
},
|
||||
@@ -938,48 +779,6 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Sign in to a Modrinth account</link> to add friends and see what they're playing!"
|
||||
},
|
||||
"installation-settings.shared-instance.linked-title": {
|
||||
"message": "Linked shared instance"
|
||||
},
|
||||
"installation-settings.shared-instance.title": {
|
||||
"message": "Shared instance"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-button": {
|
||||
"message": "Unlink shared instance"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-description": {
|
||||
"message": "Disconnect this local instance from future shared updates."
|
||||
},
|
||||
"installation-settings.shared-instance.unlinking-button": {
|
||||
"message": "Unlinking..."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-button": {
|
||||
"message": "Unpublish shared instance"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-description": {
|
||||
"message": "Stop sharing this instance and remove it from Modrinth."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublishing-button": {
|
||||
"message": "Unpublishing..."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-body": {
|
||||
"message": "This only affects your local instance. Your installed content will stay on this device, and the shared instance and other people using it will not be affected."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-header": {
|
||||
"message": "Unlinking shared instance"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.header": {
|
||||
"message": "Unlink shared instance"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-body": {
|
||||
"message": "This deletes the shared instance from Modrinth's servers. People using it in the Modrinth App will stop receiving updates, but your local instance and its content will stay on this device."
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-header": {
|
||||
"message": "Unpublishing shared instance"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.header": {
|
||||
"message": "Unpublish shared instance"
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Add and play"
|
||||
},
|
||||
@@ -1226,30 +1025,6 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Enter width..."
|
||||
},
|
||||
"instance.shared-instance.error.title": {
|
||||
"message": "Something has gone wrong"
|
||||
},
|
||||
"instance.shared-instance.owner-tooltip": {
|
||||
"message": "This instance's content is being shared to other users."
|
||||
},
|
||||
"instance.shared-instance.tooltip": {
|
||||
"message": "This instance's content is being managed by someone else."
|
||||
},
|
||||
"instance.shared-instance.unavailable.access-revoked-text-v2": {
|
||||
"message": "Your access to the shared instance was revoked. Your local instance is still available, but it is no longer linked and won't receive updates."
|
||||
},
|
||||
"instance.shared-instance.unavailable.deleted-text-v2": {
|
||||
"message": "The shared instance was deleted. Your local instance is still available, but it is no longer linked and won't receive updates."
|
||||
},
|
||||
"instance.shared-instance.unavailable.manager-fallback": {
|
||||
"message": "the instance manager"
|
||||
},
|
||||
"instance.shared-instance.unavailable.text-v2": {
|
||||
"message": "Your local instance is still available, but it is no longer linked and won't receive updates."
|
||||
},
|
||||
"instance.shared-instance.unavailable.title": {
|
||||
"message": "Shared instance no longer available"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "A Minecraft Server"
|
||||
},
|
||||
@@ -1313,24 +1088,6 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Sign in to Minecraft"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "Create an account"
|
||||
},
|
||||
"modal.modrinth-account-required.description": {
|
||||
"message": "You'll need to sign into your Modrinth account before you can use this feature."
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "Account required"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "Sign in to Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "Sign in to a Modrinth account"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "Having trouble signing in? <support>Get support</support>"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Provided by the instance"
|
||||
},
|
||||
@@ -1354,26 +1111,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader is provided by the server"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "A file is only reviewed if it’s uploaded to Modrinth, regardless of its file format (including .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Don't show this warning again"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Confirm installation"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Install anyway"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Malware is often distributed through modpack files by sharing them on platforms like Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "We couldn't find this file on Modrinth. We strongly recommend only installing files from sources you trust."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Unknown file warning"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Ocultar más instancias en ejecución"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Copiado"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Copiar detalles"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Descartar"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Reintentar"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Cancelado debido al cierre de la aplicación"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "No se pudo leer el modpack"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Cancelado"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "La limpieza no se completó"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "No se pudieron descargar los archivos"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "El archivo descargado está dañado"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "No se pudieron guardar los archivos"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "No se pudo completar la descarga"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "No se pudo encontrar la instancia"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "La ruta del archivo no es válida"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Los datos del modpack no son válidos"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Los archivos del modpack tienen metadatos no válidos"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "No se pudo completar la configuración de Java"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "No se pudo configurar el cargador"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "No se pudieron actualizar los datos locales"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "La instalación de Minecraft falló"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "No pude comunicarme con Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "No tiene permiso para escribir"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "No se pudo descargar el modpack"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Algo salió mal"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Instancia desconocida"
|
||||
},
|
||||
@@ -168,7 +234,7 @@
|
||||
"message": "Descubrir servidores"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Ocultar servidores ya añadidos"
|
||||
"message": "Ocultar los servidores ya agregados"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacks"
|
||||
@@ -219,7 +285,7 @@
|
||||
"message": "Finalizando"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Preparando la instancia"
|
||||
"message": "En cola para instalarse"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Preparando Java"
|
||||
@@ -359,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Buscar en {count} mundos..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Contenido requerido"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instalar para jugar"
|
||||
},
|
||||
@@ -371,39 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Modpack requerido"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Este servidor requiere mods para poder jugar. Haz clic en Instalar para configurar los archivos requeridos desde Modrinth, después se ejecutará para entrar directamente al servidor."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instancia compartida"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Instancia de servidor compartida"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Ver contenidos"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Actualizar para jugar"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Actualización requerida"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Se requiere una actualización para jugar {name}. Por favor, actualiza a la versión más reciente para iniciar el juego."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Este proyecto ya está instalado"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Cambiar versión"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Volver al explorador"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Instalar contenido a la instancia"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Todas las versiones"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Descargar en el navegador"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Instalando"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Ya instalado"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Modo desarrollador activado."
|
||||
},
|
||||
@@ -524,6 +590,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Constructores y Biomas"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Caos al cubo"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Persigue los Cielos"
|
||||
},
|
||||
@@ -1018,26 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "El loader es proporcionado por el servidor"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Un archivo solo es revisado si es subido a Modrinth, independientemente de su formato de archivo (incluyendo .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "No volver a mostrar esta advertencia"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Confirmar instalación"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Instalar de todos modos"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "El malware a menudo es distribuido mediante modpacks compartidos en aplicaciones como Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "No pudimos encontrar este archivo en Modrinth. Recomendamos solo instalar archivos de sitios de confianza."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Advertencia de archivo desconocido"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,18 @@
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Descartar"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Abrir instancia"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Reintentar"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Instancia desconocida"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Instalaciones"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Establecer como instancia principal"
|
||||
},
|
||||
@@ -104,6 +116,12 @@
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Mostrar tiempo de juego"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Automáticamente omite confirmaciones de bajo riesgo como modpacks duplicados, eliminación de contenido normal, actualizaciones masivas, desvinculando modpacks, y mensajes de reparación. Advertencias importantes seguirán siendo mostradas."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Omitir advertencias no esenciales"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Activa la posibilidad de alternar la barra lateral."
|
||||
},
|
||||
@@ -149,9 +167,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Descubrir servidores"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Ocultar servidores ya añadidos"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacks"
|
||||
},
|
||||
@@ -254,9 +269,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Buscar {count} mundos..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Contenido obligatorio"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instala para jugar"
|
||||
},
|
||||
@@ -266,27 +278,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Modpack requerido"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Este servidor requiere ciertos mods. Pulsa Instalar para instalar los archivos requeridos de Modrinth y luego el launcher te enviara directo al servidor."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instancia compartida"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Instancia de servidor compartida"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Ver contenido"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Actualiza para jugar"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Actualización requerida"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Una actualización es requerida para jugar {name}. Por favor actualízala a la versión más reciente para ejecutar el juego."
|
||||
},
|
||||
@@ -910,26 +910,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader proporcionado por el servidor"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Un archivo solo es revisado si es subido a Modrinth, independientemente de su formato de archivo (incluyendo .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "No mostrar esta advertencia otra vez"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Confirmar instalación"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Instalar de todos modos"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "El malware es normalmente distribuido por archivos de modpack que son normalmente compartidas en aplicaciones como Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "No pudimos encontrar este archivo en Modrinth. Recomendamos solo instalar archivos de sitios de confianza."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Advertencia de archivo desconocido"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,9 +167,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Löydä palvelimia"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Piilota lisätyt palvelimet"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modipaketit"
|
||||
},
|
||||
@@ -191,9 +188,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Vie modipaketti"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Modipaketin nimi"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Modipaketin nimi"
|
||||
},
|
||||
@@ -218,9 +212,6 @@
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Viimeistellään"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Valmistellaan instanssia"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Valmistellaan Javaa"
|
||||
},
|
||||
@@ -359,9 +350,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Hae {count} maailmasta..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Sisältö vaaditaan"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Asenna pelataksesi"
|
||||
},
|
||||
@@ -371,27 +359,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# modia}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Vaadittu modipaketti"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Tämä palvelin vaatii modeja toimiakseen. Klikkaa Asenna ladataksesi vaaditut tiedostot Modrinthista, ja käynnistä peli suoraan palvelimelle."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Jaettu instanssi"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Jaettu palvelininstanssi"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Tarkastele sisältöä"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Päivitä pelataksesi"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Päivitys vaaditaan"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Pävitys vaaditaan pelataksesi {name}. Päivitä viimeisimpään versioon pelataksesi."
|
||||
},
|
||||
@@ -1018,26 +994,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Modialusta on palvelimen tarjoama"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Tiedosto tarkistetaan vain jos se on ladattu Modrinthiin, riippumatta tiedoston muodosta (mukaanlukien .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Älä näytä tätä varoitusta uudestaan"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Vahvista asennus"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Asenna jokatapauksessa"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Haittaohjelmia levitetään usein modipaketti tiedostojen kautta jakamalla niitä alustoilla kuten Discordissa."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Emme löytäneet tätä tiedostoa Modrinthista. Suosittelemme vahvasti että asennat tiedostoja vain lähteistä joihin luotat."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Tuntematon tiedosto varoitus"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Itago ang mas marami pang tumatakbong instansiya"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Subukan muli"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Gumawa ng pangunahing instansiya"
|
||||
},
|
||||
@@ -143,9 +146,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Tumuklas ng mga server"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Itago ang mga nailagay na mga servers"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacks"
|
||||
},
|
||||
@@ -164,9 +164,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Iluwas ang modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Pangalan ng Modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Pangalan ng modpack"
|
||||
},
|
||||
@@ -245,9 +242,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Hanapin sa {count} mundo..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Nangangailangan ng kontento"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Mag-install upang malaro"
|
||||
},
|
||||
@@ -257,27 +251,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# na mod}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Kinailangan na modpack"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Ang server rna ito ay nangangailangan ng mga mod upang makalaro. Pindutin ang install upang maihanda ang mga kinakailangang file galing sa Modrinth, matapos ay ilunsad nang diretso sa server."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Binahaging instansiya"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Binahaging instansiyang pang-server"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Tingnan ang mga kontento"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Mag-update upang malaro"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Kailangang mag-update"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Kailangang mag-update upang malaro ang {name}. Mangyaring mag-update sa pinakabagong bersiyon upang ma-launch ang laro."
|
||||
},
|
||||
@@ -567,7 +549,7 @@
|
||||
"message": "Mga launch hook"
|
||||
},
|
||||
"instance.settings.tabs.hooks.custom-hooks": {
|
||||
"message": "Mga custom na launch hook"
|
||||
"message": "Mga pasadyang launch hook"
|
||||
},
|
||||
"instance.settings.tabs.hooks.description": {
|
||||
"message": "Binibigyan-daan ng mga hook ang mga ekspertong tagagamit na makapagtakbo ng mga pansistemang utos o system command bago at pagkatapos ma-launch ang laro."
|
||||
@@ -630,7 +612,7 @@
|
||||
"message": "Window"
|
||||
},
|
||||
"instance.settings.tabs.window.custom-window-settings": {
|
||||
"message": "Mga setting sa custom na window"
|
||||
"message": "Mga setting sa pasadyang window"
|
||||
},
|
||||
"instance.settings.tabs.window.fullscreen": {
|
||||
"message": "Fullscreen"
|
||||
@@ -739,26 +721,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Ang loader ay handog na ng server"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Ang file ay nasusuri lamang kapag ito ay na-upload sa Modrinth, walang pili sa file format nito (kabilang na ang .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Huwag ipakita ang babalang ito ulit"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Kumpirmahin ang installation"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "I-install pa rin"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Ang malware ay madalas naidadala sa mga modpack files sa pamamagitan ng pag-bigay ng mga ito sa mga platforms kagaya ng Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Hindi namin mahanap ang file na ito sa Modrinth. Mahalagang mag-install ka lamang ng files galing sa mga mapagkakatiwalang sources."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Hindi kilalang file"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Masquer plus d'instances en exécution"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Copié"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Copier les détails"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Rejeter"
|
||||
},
|
||||
@@ -20,6 +26,45 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Réessayer"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Annulé en raison de la fermeture de l'application"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Impossible de lire le modpack"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Annulé"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "Le nettoyage n'est pas terminé"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Impossible de télécharger les fichiers"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Le fichier téléchargé est corrompu"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Impossible de sauvegarder les fichiers"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Impossible de terminer le téléchargement"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "L'instance est introuvable"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Le chemin d'accès au fichier est invalide"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Les données du modpack sont invalides"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Les fichiers du modpack contiennent des métadonnées invalides"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "L'installation de Java n'a pas pu se terminer"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Instance inconnue"
|
||||
},
|
||||
@@ -168,7 +213,7 @@
|
||||
"message": "Découvrir des serveurs"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Masquer les serveurs déjà ajoutés"
|
||||
"message": "Masquer les serveurs déjà installés"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacks"
|
||||
@@ -218,9 +263,6 @@
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Finalisation"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Préparation de l'instance"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Préparation de Java"
|
||||
},
|
||||
@@ -359,9 +401,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Rechercher {count} mondes..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Contenu requis"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installer pour jouer"
|
||||
},
|
||||
@@ -371,39 +410,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Modpack requis"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Ce serveur a besoin de mods pour jouer. Cliquez sur Installer pour mettre en place les fichiers requis depuis Modrinth, puis lancez directement dans le serveur."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instance partagée"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Instance serveur partagée"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Voir le contenu"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Mettre à jour pour jouer"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Mise à jour requise"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Une mise à jour est requise pour jouer à {name}. Veuillez mettre à jour à la dernière version pour lancer le jeu."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ce projet a déjà été installé"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Changer de version"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Retour vers la page découvrir"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Installer du contenu à l'instance"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Toutes les versions"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Télécharger dans le navigateur"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Installation"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Déjà installé"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Mode développeur activé."
|
||||
},
|
||||
@@ -524,6 +566,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Cubes du chaos"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chassez les cieux"
|
||||
},
|
||||
@@ -552,7 +597,7 @@
|
||||
"message": "Striding Hero"
|
||||
},
|
||||
"app.skins.section.the-copper-age": {
|
||||
"message": "The Copper Age"
|
||||
"message": "L'âge du cuivre"
|
||||
},
|
||||
"app.skins.section.the-garden-awakens": {
|
||||
"message": "L'éveil du jardin"
|
||||
@@ -1015,26 +1060,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Le loader est procuré par le serveur"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Un fichier n’est révisé que s’il est téléchargé sur Modrinth, quel que soit son format de fichier (y compris .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Ne plus m'avertir à ce sujet"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Confirmer l'installation"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Installer tout de même"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Les logiciels malveillants sont souvent distribués via des fichiers modpack en les partageant sur des plateformes comme Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Nous ne pouvions pas trouver ce fichier sur Modrinth. Nous vous recommandons fortement de n'installer que des fichiers de sources de confiance."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Avertissement fichier inconnu"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "יצוא חבילת מודים"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "שם חבילת המודים"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "שם חבילת המודים"
|
||||
},
|
||||
@@ -140,9 +137,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "חיפוש ב-{count} עולמות..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "תוכן נדרש"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "צריך להתקין כדי לשחק"
|
||||
},
|
||||
@@ -152,27 +146,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {מוד אחד} other {# מודים}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "חבילת מודים נדרשת"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "שרת זה דורש מודים כדי לשחק. לחץ על \"התקן\" כדי להגדיר את הקבצים הנדרשים מ-Modrinth, ולאחר מכן הפעל ישירות לשרת."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "התקנה משותפת"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "התקנת שרת משותפת"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "הצג תוכן"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "צריך לעדכן כדי לשחק"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "עדכון נדרש"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "עדכון נדרש כדי לשחק ב{name}. ניתן להתחיל את המשחק רק לאחר עדכון לגרסה החדשה."
|
||||
},
|
||||
|
||||
@@ -11,12 +11,87 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "További futó példányok elrejtése"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Másolva"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Részletek másolása"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Elutasítás"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Példány megnyitása"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Újra"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Az alkalmazás bezárása miatt megszakítva"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Nem sikerült beolvasni a modcsomagot"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Megszakítva"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "A tisztítás nem fejeződött be"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Nem sikerült letölteni a fájlokat"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "A letöltött fájl sérült"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Nem sikerült elmenteni a fájlokat"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "A letöltés nem sikerült"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "A példány nem található"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "A fájl elérési útja érvénytelen"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "A modcsomag adatai érvénytelenek"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "A modcsomag fájljainak metaadatai érvénytelenek"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "A Java telepítése nem sikerült"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "A betöltő beállítása sikertelen volt"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "A helyi adatok frissítése nem sikerült"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "A Minecraft telepítése sikertelen volt"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Nem sikerült elérni Modrinthot"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Nincs felülírási jogosultság"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Nem sikerült letölteni a csomagot"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Valami hiba történt"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Ismeretlen profil"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Telepítések"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Beállítás elsődleges példányként"
|
||||
},
|
||||
@@ -48,13 +123,13 @@
|
||||
"message": "Példányok megtekintése"
|
||||
},
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Naplók megtekintése"
|
||||
"message": "Naplózások megtekintése"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Lehetővé teszi olyan speciális megjelenítési effektusok használatát, mint például az elmosódás, amelyek hardveres gyorsítás nélkül teljesítménycsökkenést okozhatnak."
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.title": {
|
||||
"message": "Fejlett renderelés"
|
||||
"message": "Haladó megjelenítési beállítások"
|
||||
},
|
||||
"app.appearance-settings.color-theme.description": {
|
||||
"message": "Válaszd ki a Modrinth Apphoz a kívánt színsémát."
|
||||
@@ -84,7 +159,7 @@
|
||||
"message": "A kezdőlap „Folytasd itt” részében a legújabb világok is megtalálhatók."
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.title": {
|
||||
"message": "Visszaugrás a világokba"
|
||||
"message": "„Folytasd itt” a világokat is"
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.description": {
|
||||
"message": "Minimalizáld az indítót a Minecraft indításakor."
|
||||
@@ -102,11 +177,17 @@
|
||||
"message": "Válassz egy lehetőséget"
|
||||
},
|
||||
"app.appearance-settings.show-play-time.description": {
|
||||
"message": "Megmutatja, mennyi időt töltöttél játszva egy profillal."
|
||||
"message": "Megmutatja, mennyi időt töltöttél egy példányban."
|
||||
},
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Játékidő megjelenítése"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Az alacsony kockázatú megerősítéseket – például a modcsomagok ismételt telepítését, a szokásos tartalomtörlést, a tömeges frissítéseket, a modcsomagok kapcsolatának megszüntetését és a javítási felhívásokat – a rendszer automatikusan kihagyja. A veszélyes figyelmeztetéseket továbbra is megjeleníti."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Hagyd ki a lényegtelen figyelmeztetéseket"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Lehetővé teszi az oldalsáv be- és kikapcsolását."
|
||||
},
|
||||
@@ -153,16 +234,16 @@
|
||||
"message": "Szerverek böngészése"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Már hozzáadott szerverek elrejtése"
|
||||
"message": "A már hozzáadott szerverek elrejtése"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modcsomagok"
|
||||
},
|
||||
"app.browse.server-instance-content-warning": {
|
||||
"message": "A tartalom hozzáadása ronthatja a kompatibilitást a szerverhez való csatlakozáskor. A hozzáadott tartalom elveszik, ha frissíted a szerverprofil tartalmát."
|
||||
"message": "A tartalom hozzáadása ronthatja a kompatibilitást a szerverhez való csatlakozáskor. A hozzáadott tartalom elveszik, ha frissíted a szerverpéldány tartalmát."
|
||||
},
|
||||
"app.browse.server.installing": {
|
||||
"message": "Letöltés..."
|
||||
"message": "Letöltés"
|
||||
},
|
||||
"app.content-install.no-compatible-versions": {
|
||||
"message": "Nincs a(z) {compatibilityLabel} verziónak megfelelő elérhető verzió. Válassz ki egy verziót, ha mégis telepíteni szeretnéd. A függőségek nem települnek automatikusan."
|
||||
@@ -177,7 +258,7 @@
|
||||
"message": "Modcsomag exportálása"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "A modcsomag neve"
|
||||
"message": "Modcsamag neve"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "A modcsomag neve"
|
||||
@@ -188,9 +269,60 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Tartalom letöltése"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Minecraft letöltése"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Csomagfájlok letöltése"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Felülírások kibontása"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Befejezés"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Telepítésre vár"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Java előkészítése"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Java verzió {version} letöltése"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Java verzió {version} kibontása"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Java verzió ellőkészítése {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Java verzió {version} előkészítése"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "A Java {version} ellenőrzése"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Csomag adati kiolvasása"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": ""
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Minecraft Betöltése"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "Tartalom betöltése"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "Visszavonás"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Betöltő folyamatok futtatása"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Az profilodhoz tartozó összes adat véglegesen törlődik, beleértve a világokat, a beállításokat és az összes telepített tartalmat."
|
||||
},
|
||||
@@ -215,6 +347,15 @@
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "Példány"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "{current, number}/{total, number} projekt letöltése..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "Frissítés befejezése..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "Verziók meghatározása..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "projekt"
|
||||
},
|
||||
@@ -239,6 +380,18 @@
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "Szerverek böngészése"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "Törlés"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "Világ törlése"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "Ez a világ véglegesen törölve lesz ebből a példányból. Ezt NEM tudod visszavonni!"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "{name} törlése"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "Modolt"
|
||||
},
|
||||
@@ -257,12 +410,21 @@
|
||||
"app.instance.worlds.no-worlds-heading": {
|
||||
"message": "Nincs szerver vagy világ"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.remove-button": {
|
||||
"message": "Szerver eltávolítása"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.title": {
|
||||
"message": "Szerver eltávolítása"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-body": {
|
||||
"message": "Ez a szerver el lesz távolítva a szerverlistádból és a játékbeli szerverlistából is. Később újra hozzáadhatod, ha tudod a címet."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "{name} eltávolítása"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Keresés {count} világ között..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Szükséges tartalom"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Telepítés a játékhoz"
|
||||
},
|
||||
@@ -272,38 +434,41 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count} mod"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Szükséges modcsomag"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Ehhez a szerverhez modok szükségesek a játékhoz. Kattints a Telepítés gombra, hogy telepítsd a szükséges fájlokat a Modrinth-ról, majd indítsd el közvetlenül a szervert."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Megosztott profil"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Megosztott szerverprofil"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Tartalom megtekintése"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Frissítsd a játékhoz"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Frissítés szükséges"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Frissítés szükséges ehhez: {name}. Kérlek, frissíts a legújabb verzióra a játék elindításához."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ez a projekt már telepítve van"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Verzió váltása"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Vissza a böngészéshez"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Tartalom telepítése a profilba"
|
||||
"message": "Tartalom telepítése a példányba"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Összes verzió"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Letöltés a böngészőben"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Telepítés..."
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Már le van töltve"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Fejlesztői mód bekapcsolva."
|
||||
@@ -416,9 +581,18 @@
|
||||
"app.skins.rate-limit.title": {
|
||||
"message": "Lassíts!"
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "A kinézeted sorrendjét nem sikerült menteni."
|
||||
},
|
||||
"app.skins.reorder-error.title": {
|
||||
"message": "A skinek átrendezése sikertelen"
|
||||
},
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -462,7 +636,7 @@
|
||||
"message": "Kérlek jelentkezz be a Minecraft-fiókodba, hogy használni tudd a Modrinth App kinézetkezelési funkcióit."
|
||||
},
|
||||
"app.skins.sign-in.rinthbot-alt": {
|
||||
"message": "Izgatott Modrinth-bot"
|
||||
"message": "Izgatott Modrinth bot"
|
||||
},
|
||||
"app.skins.sign-in.title": {
|
||||
"message": "Kérlek jelentkezz be"
|
||||
@@ -708,7 +882,7 @@
|
||||
"message": "Kiadás"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release.description": {
|
||||
"message": "Csak a release verziók fognak megjelenni az elérhető frissítések között."
|
||||
"message": "Csak a 'kiadás' verziók fognak megjelenni az elérhető frissítések között."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.select": {
|
||||
"message": "Válaszd ki a frissítési csatornát"
|
||||
@@ -795,7 +969,7 @@
|
||||
"message": "Hozzárendelt memória"
|
||||
},
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/path/to/java"
|
||||
"message": "/eleresi/ut/a/javahoz"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Ablak"
|
||||
@@ -836,11 +1010,14 @@
|
||||
"instance.worlds.copy_address": {
|
||||
"message": "Cím másolása"
|
||||
},
|
||||
"instance.worlds.create_shortcut": {
|
||||
"message": "Gyorshivatkozás létrehozása"
|
||||
},
|
||||
"instance.worlds.dont_show_on_home": {
|
||||
"message": "Ne mutasd a kezdőlapon"
|
||||
},
|
||||
"instance.worlds.game_already_open": {
|
||||
"message": "A példány már el van indítva"
|
||||
"message": "A profil már el van indítva"
|
||||
},
|
||||
"instance.worlds.hardcore": {
|
||||
"message": "Hardcore mód"
|
||||
@@ -858,7 +1035,7 @@
|
||||
"message": "Csak Minecraft Alpha 1.0.5+-tól tudsz egyből szerverhez csatlakozni"
|
||||
},
|
||||
"instance.worlds.no_singleplayer_quick_play": {
|
||||
"message": "Csak Minecraft 1.20+-tól tudsz egyből egyjátékos világba belépni"
|
||||
"message": "Használj 1.20+ verziót az azonnali egyjátékos módba lépéshez"
|
||||
},
|
||||
"instance.worlds.play_instance": {
|
||||
"message": "Játék a profillal"
|
||||
@@ -906,30 +1083,9 @@
|
||||
"message": "Csak kliensoldali modok adhatók hozzá a szerverprofilhoz"
|
||||
},
|
||||
"search.filter.locked.server-game-version.title": {
|
||||
"message": "A játékverziót a szerver biztosítja"
|
||||
"message": "A játékverzió a szerver által van megadva"
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "A betöltőt a szerver biztosítja"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Egy fájlt csak akkor vizsgálunk meg, ha azt feltöltik a Modrinthra, függetlenül a fájlformátumtól (beleértve a .mrpack formátumot is)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Ne mutasd újra ezt a figyelmeztetést"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Telepítés megerősítése"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Letöltés mindenképpen"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "A rosszindulatú programokat gyakran modcsomag-fájlokon keresztül terjesztik, például a Discordhoz hasonló platformokon történő megosztás révén."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Ezt a fájlt nem találtuk meg a Modrinthon. Határozottan javasoljuk, hogy kizárólag megbízható forrásokból származó fájlokat telepíts."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Figyelmeztetés ismeretlen fájlról"
|
||||
"message": "A betöltő a szerver által van megadva"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +146,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Temukan server"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Sembunyikan server yang sudah ditambah"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Paket Mod"
|
||||
},
|
||||
@@ -170,9 +167,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Ekspor paket mod"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Nama Paket Mod"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Nama paket mod"
|
||||
},
|
||||
@@ -251,9 +245,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Cari {count} dunia..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Konten diperlukan"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Pasang untuk memainkan"
|
||||
},
|
||||
@@ -263,27 +254,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {# mod}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Paket mod yang diperlukan"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Mod diperlukan untuk bermain di server ini. Klik pasang untuk menyiapkan berkas-berkas yang diperlukan dari Modrinth, kemudian luncurkan langsung sari server."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instans terbagi"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Instans server terbagi"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Lihat konten"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Perbarui untuk memainkan"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Perlu diperbarui"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name} perlu diperbarui sebelum dimainkan. Mohon perbarui ke versi terkini untuk meluncurkan permainan."
|
||||
},
|
||||
@@ -907,26 +886,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Pemuat disediakan oleh server"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Berkas hanya akan ditinjau bila ia diunggah ke Modrinth, tak peduli format berkasnya (termasuk .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Jangan tampilkan peringatan ini lagi"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Konfirmasi pemasangan"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Tetap pasang"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Program jahat (malware) dibagikan melalui berkas paket mod dengan membagikannya melalui platform seperti Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Kami tidak dapat menemukan berkas ini di Modrinth. Kami sangat menyarankan Anda untuk hanya memasang berkas dari sumber-sumber terpercaya."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Peringatan berkas tidak dikenal"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Mostra meno istanze in esecuzione"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Copiati"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Copia dettagli"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Ignora"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Riprova"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Annullato per app chiusa"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Impossibile leggere il pacchetto"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Annullato"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "La pulizia è stata interrotta"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Impossibile scaricare i file"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Il file scaricato è corrotto"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Impossibile salvare i file"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Il download è stato interrotto"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "L'istanza non è stata trovata"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Percorso del file errato"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Dati del pacchetto non validi"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Metadati del pacchetto non validi"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "La configurazione di Java è stata interrotta"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Il loader non è stato configurato"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Impossibile aggiornare i dati locali"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Minecraft non è stato configurato"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Impossibile collegarsi a Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Permessi di scrittura mancanti"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Impossibile scaricare il pacchetto"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Qualcosa è andato storto"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Istanza sconosciuta"
|
||||
},
|
||||
@@ -213,13 +279,13 @@
|
||||
"message": "Download del pacchetto"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Estrazione degli override"
|
||||
"message": "Estrazione delle sovrascritture"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Finalizzazione"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Preparazione dell'istanza"
|
||||
"message": "In coda per l'installazione"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Preparazione di Java"
|
||||
@@ -252,7 +318,7 @@
|
||||
"message": "Risoluzione dei contenuti"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "Tornando indietro"
|
||||
"message": "Annullamento"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Esecuzione dei processori del loader"
|
||||
@@ -356,9 +422,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Cerca tra {count} mondi..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Contenuto richiesto"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installa per continuare"
|
||||
},
|
||||
@@ -368,39 +431,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count} mod"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Pacchetto di mod richiesto"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Questo server richiede alcune mod. Clicca Installa per scaricarle direttamente da Modrinth, poi sarai pronto a giocare."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Istanza condivisa"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Istanza del server condivisa"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Mostra contenuti"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Aggiorna per continuare"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Aggiornamento richiesto"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name} richiede degli aggiornamenti. Installa l'ultima versione per poter giocare."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Questo progetto è già stato installato"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Cambia versione"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Torna a Esplora"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Installa il contenuto nell'istanza"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Tutte le versioni"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Scarica col browser"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Installazione"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Già installate"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Modalità sviluppatore attiva."
|
||||
},
|
||||
@@ -521,6 +587,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -1015,26 +1084,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Il loader è determinato dal server"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Solo i file caricati su Modrinth vengono esaminati, qualunque sia il loro formato (.mrpack inclusi)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Non mostrare più questo avviso"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Conferma l'installazione"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Installa comunque"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Spesso i malware vengono nascosti nei pacchetti di mod, poi distribuiti su piattaforme come Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Non è stato possibile trovare questo file su Modrinth. Consigliamo di installare file solo da fonti attendibili."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Tipo di file sconosciuto"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,51 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "実行中のインスタンスの一部を非表示"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "コピーしました"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "詳細をコピー"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "閉じる"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "インスタンスを表示"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "再試行"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "アプリの終了によりキャンセルされました"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "ModPackを読み込むことができませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "キャンセルしました"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "クリーンアップが完了しませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "ファイルをダウンロードできませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "ダウンロードしたファイルが破損しています"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "ファイルを保存できませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "ダウンロードを完了することができませんでした"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "不明なインスタンス"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "インストール数"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "デフォルトのインスタンスを作成"
|
||||
},
|
||||
@@ -29,6 +74,9 @@
|
||||
"app.action-bar.stop-instance": {
|
||||
"message": "インスタンスを停止"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "アップデート"
|
||||
},
|
||||
"app.action-bar.view-active-downloads": {
|
||||
"message": "進行中のダウンロードを表示"
|
||||
},
|
||||
@@ -131,9 +179,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "サーバーを探す"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "既に追加済みのサーバーを非表示にする"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modパック"
|
||||
},
|
||||
@@ -149,9 +194,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Modパックを書き出す"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Modパック名"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Modパック名"
|
||||
},
|
||||
@@ -161,6 +203,9 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Java {version} をダウンロードしています"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "インスタンス内のすべてのデータは、ワールド、設定、インストール済みのコンテンツを含め、完全に削除されます。"
|
||||
},
|
||||
@@ -209,6 +254,9 @@
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "サーバーを探す"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "{name} を削除します"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "Mod導入済み"
|
||||
},
|
||||
@@ -230,9 +278,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "{count} 個のワールドを検索…"
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "必須コンテンツ"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "インストールしてプレイ"
|
||||
},
|
||||
@@ -242,30 +287,21 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {#個のMod}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "必須のModパック"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "このサーバーをプレイするにはModが必要です。インストールをクリックしてModrinthから必要なファイルを設定し、サーバーに接続してください。"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "共有インスタンス"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "共有サーバーインスタンス"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "コンテンツを見る"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "更新してプレイ"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "更新が必要です"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name}をプレイするには更新が必要です。ゲームを起動するには最新版に更新してください。"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "すべてのバージョン"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "開発者モードがオンになっています。"
|
||||
},
|
||||
@@ -305,9 +341,18 @@
|
||||
"app.skins.modal.no-cape-tooltip": {
|
||||
"message": "マントなし"
|
||||
},
|
||||
"app.skins.modal.none-cape-option": {
|
||||
"message": "無し"
|
||||
},
|
||||
"app.skins.modal.replace-texture-button": {
|
||||
"message": "アップロード"
|
||||
},
|
||||
"app.skins.modal.save-skin-button": {
|
||||
"message": "スキンを保存する"
|
||||
},
|
||||
"app.skins.modal.saving-tooltip": {
|
||||
"message": "保存しています…"
|
||||
},
|
||||
"app.skins.modal.texture-section": {
|
||||
"message": "テクスチャ"
|
||||
},
|
||||
@@ -566,6 +611,12 @@
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "名前"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "ベータ"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release": {
|
||||
"message": "リリース"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "起動フック"
|
||||
},
|
||||
@@ -745,26 +796,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "ローダーはサーバーによる条件です"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "ファイル形式に関わらず、Modrinthにアップロードされたファイルのみが確認されます。(.mrpackを含む)"
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "この警告を次回から表示しない"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "インストールの確認"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "インストールを続行"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "一般的にマルウェアは、Discord等のプラットフォーム上でModパックファイルを配布して拡散されます"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "このファイルをModrinth上で見つけることができませんでした。信頼できるソースからインストールすることを強くお勧めします。"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "不明なファイルの警告"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"message": "Java {version} 다운로드 중"
|
||||
},
|
||||
"app.action-bar.downloading-update": {
|
||||
"message": "업데이트 다운로드중"
|
||||
"message": "업데이트 다운로드 중"
|
||||
},
|
||||
"app.action-bar.downloads": {
|
||||
"message": "다운로드"
|
||||
@@ -11,6 +11,21 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "실행 중인 인스턴스 숨기기"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "무시"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "인스턴스 열기"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "재시도"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "알 수 없는 인스턴스"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "설치"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "기본 인스턴스로 지정"
|
||||
},
|
||||
@@ -23,12 +38,18 @@
|
||||
"app.action-bar.primary-instance": {
|
||||
"message": "기본 인스턴스"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "업데이트하려면 다시 로드"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "실행 중인 인스턴스 보이기"
|
||||
},
|
||||
"app.action-bar.stop-instance": {
|
||||
"message": "인스턴스 멈추기"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "업데이트"
|
||||
},
|
||||
"app.action-bar.view-active-downloads": {
|
||||
"message": "다운로드 목록 보기"
|
||||
},
|
||||
@@ -95,6 +116,12 @@
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "플레이 시간 표시"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "중복되는 모드팩 설치와 일반적인 콘텐츠 삭제, 동시 업데이트, 모드팩 링크 제거, 프롬프트 복구처럼 리스크가 적은 행위에 대한 확인 절차를 자동으로 넘깁니다. 위험한 경고는 여전히 표시됩니다."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "중요하지 않은 경고 넘기기"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "사이드바를 접거나 펼칠 수 있는 기능을 활성화합니다."
|
||||
},
|
||||
@@ -141,7 +168,7 @@
|
||||
"message": "서버 탐색하기"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "이미 추가된 서버 숨기기"
|
||||
"message": "이미 추가한 서버 숨기기"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "모드팩"
|
||||
@@ -176,6 +203,57 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "콘텐츠 다운로드 중"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Minecraft 다운로드 중"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "팩 파일 다운로드 중"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "재정의 콘텐츠 추출 중"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "마무리 중"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Java 준비 중"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Java {version} 다운로드 중"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Java {version} 추출 중"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Java {version} 가져오는 중"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Java {version} 준비 중"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "Java {version} 유효성 검사 중"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "팩 manifest 읽는 중"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "로더 해결 중"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Minecraft 해결 중"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "콘텐츠 해결 중"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "뒤로 돌리는 중"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "로더 진행기 실행 중"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "인스턴스의 모든 데이터가 삭제됩니다. 세계 폴더, 설정 폴더 등 설치된 모든 컨텐츠가 포함됩니다."
|
||||
},
|
||||
@@ -200,6 +278,15 @@
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "인스턴스"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "{current, number}/{total, number} 프로젝트 다운로드 중..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "업데이트 마무리 중..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "버전 해결 중..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "프로젝트"
|
||||
},
|
||||
@@ -224,6 +311,18 @@
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "서버 탐색하기"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "세계 삭제"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "세계 삭제"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "이 세계는 이 인스턴스로부터 영구적으로 삭제됩니다. 이 작업은 되돌릴 수 없습니다."
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "{name} 삭제 중"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "수정됨"
|
||||
},
|
||||
@@ -242,12 +341,21 @@
|
||||
"app.instance.worlds.no-worlds-heading": {
|
||||
"message": "추가된 서버 또는 세계 없음"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.remove-button": {
|
||||
"message": "서버 제거"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.title": {
|
||||
"message": "서버 제거"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-body": {
|
||||
"message": "이 서버는 서버 목록과 게임 내 서버 목록으로부터 삭제됩니다. 주소를 안다면 추후 다시 추가할 수 있습니다."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "{name} 제거 중"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "{count}개의 세계 검색..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "콘텐츠 설치 필요"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "설치하고 플레이"
|
||||
},
|
||||
@@ -257,27 +365,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {모드 #개} other {모드 #개}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "필요한 모드팩"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "이 서버를 플레이하려면 모드가 필요합니다. '설치'를 클릭하여 Modrinth에서 필수 파일을 내려받은 후, 서버에 바로 접속하세요."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "인스턴스 공유됨"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "서버 인스턴스 공유됨"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "구성 요소 보기"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "업데이트하고 플레이"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "업데이트 필요"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name}을(를) 플레이하려면 업데이트가 필요합니다. 게임을 실행하려면 최신 버전으로 업데이트해 주세요."
|
||||
},
|
||||
@@ -401,9 +497,18 @@
|
||||
"app.skins.rate-limit.title": {
|
||||
"message": "잠시 기다려주세요."
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "이 스킨 정렬은 저장되지 않습니다."
|
||||
},
|
||||
"app.skins.reorder-error.title": {
|
||||
"message": "스킨 재정렬 실패"
|
||||
},
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "카오스 큐브"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -473,6 +578,9 @@
|
||||
"app.update-popup.download-complete": {
|
||||
"message": "다운로드 완료"
|
||||
},
|
||||
"app.update-popup.reload": {
|
||||
"message": "업데이트하려면 다시 로드"
|
||||
},
|
||||
"app.update-popup.title": {
|
||||
"message": "업데이트 가능"
|
||||
},
|
||||
@@ -671,6 +779,30 @@
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "이름"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel": {
|
||||
"message": "채널 업데이트"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha": {
|
||||
"message": "알파"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha.description": {
|
||||
"message": "릴리스와 베타, 알파 버전이 이용 가능한 업데이트에 표시됩니다."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "베타"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta.description": {
|
||||
"message": "릴리스와 베타 버전이 이용 가능한 업데이트에 표시됩니다."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release": {
|
||||
"message": "릴리스"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release.description": {
|
||||
"message": "릴리스 버전만 이용 가능한 업데이트에 표시됩니다."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.select": {
|
||||
"message": "업데이트 채널 선택"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "실행 후크"
|
||||
},
|
||||
@@ -794,6 +926,9 @@
|
||||
"instance.worlds.copy_address": {
|
||||
"message": "주소 복사"
|
||||
},
|
||||
"instance.worlds.create_shortcut": {
|
||||
"message": "바로가기 만들기"
|
||||
},
|
||||
"instance.worlds.dont_show_on_home": {
|
||||
"message": "홈에서 숨기기"
|
||||
},
|
||||
@@ -868,26 +1003,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "로더가 서버에 의해 제공됩니다"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "모든 파일은 형식(.mrpack 포함)에 무관하게 Modrinth에 업로드되어야만 검수를 거칩니다."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "이 경고를 다시 표시하지 않음"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "설치 확인"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "무시하고 설치"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "악성코드는 흔히 디스코드와 같은 플랫폼을 통해 모드팩 파일을 공유하는 방식으로 유포됩니다."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "이 파일을 Modrinth에서 찾을 수 없습니다. 신뢰할 수 있는 출처의 파일만 설치하는 것을 권장합니다."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "출처를 알 수 없는 파일 경고"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Sembunyikan lebih banyak pemasangan yang berjalan"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Ketepikan"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Cuba semula"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Jadikan pemasangan utama"
|
||||
},
|
||||
@@ -26,6 +32,9 @@
|
||||
"app.action-bar.stop-instance": {
|
||||
"message": "Hentikan pemasangan"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "Kemas kini"
|
||||
},
|
||||
"app.action-bar.view-active-downloads": {
|
||||
"message": "Lihat muat turun aktif"
|
||||
},
|
||||
@@ -86,6 +95,9 @@
|
||||
"app.appearance-settings.select-option": {
|
||||
"message": "Pilih satu pilihan"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Melangkau pengesahan berisiko rendah secara automatik seperti pemasangan pek mod pendua, pemadaman kandungan biasa, kemas kini pukal, menyahpautkan pek mod dan gesaan pembaikan. Amaran berbahaya masih akan ditunjukkan."
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Membolehkan keupayaan untuk menogol bar sisi."
|
||||
},
|
||||
@@ -131,9 +143,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Temui pelayan"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Sembunyikan pelayan yang sudah ditambah"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Pek Mod"
|
||||
},
|
||||
@@ -155,9 +164,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Eksport pek mod"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Nama Pek Mod"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Nama pek mod"
|
||||
},
|
||||
@@ -167,6 +173,24 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Sedang memuat turun Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Sedang mengekstrak Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Sedang mengambil Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Sedang menyediakan Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "Sedang mengesahkan Java {version}"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Sedang membaca manifest pek"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Semua data untuk pemasangan anda akan dipadamkan secara kekal, termasuk dunia, konfigurasi dan semua kandungan yang dipasang."
|
||||
},
|
||||
@@ -236,9 +260,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Cari {count} dunia..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Kandungan yang diperlukan"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Pasang untuk mainkan"
|
||||
},
|
||||
@@ -248,27 +269,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {# mod}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Pek mod yang diperlukan"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Pelayan ini memerlukan mod untuk dimainkan. Klik Pasang untuk menyediakan fail yang diperlukan daripada Modrinth, kemudian lancarkan permainan terus ke dalam pelayan."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Pemasangan yang dikongsi"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Pemasangan pelayan yang dikongsi"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Lihat kandungan"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Kemas kini untuk mainkan"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Kemas kini diperlukan"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Kemas kini diperlukan untuk memainkan {name}. Sila kemas kini kepada versi terkini untuk melancarkan permainan."
|
||||
},
|
||||
@@ -626,6 +635,15 @@
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "Nama"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha": {
|
||||
"message": "Alfa"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "Beta"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release": {
|
||||
"message": "Terbitan"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "Cangkuk pelancaran"
|
||||
},
|
||||
@@ -823,26 +841,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Pemuat adalah disediakan oleh pelayan"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Sesuatu fail hanya disemak jika ia dimuat naik ke Modrinth, tanpa mengira format failnya (termasuk .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Jangan tunjukkan amaran ini lagi"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Sahkan pemasangan"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Pasangkan juga"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Perisian hasad sering diedarkan melalui fail pek mod dengan berkongsinya di platform seperti Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Kami tidak dapat menemui fail ini di Modrinth. Kami sangat mengesyorkan anda untuk hanya memasang fail daripada sumber yang anda percayai."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Amaran fail tidak diketahui"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +146,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Ontdek servers"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Verberg al toegevoegde servers"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacks"
|
||||
},
|
||||
@@ -170,9 +167,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Exporteer modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Modpack Naam"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Modpack naam"
|
||||
},
|
||||
@@ -251,9 +245,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Zoek werelden"
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Content vereist"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installeer om te spelen"
|
||||
},
|
||||
@@ -263,27 +254,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural,one {# mod}other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Vereist modpack"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Deze server vereist mods om te spelen. Klik op Installeer om de vereiste bestanden van Modrinth in te stellen, en start direct in de server."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Gedeelde instantie"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Gedeelde server instantie"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Toon content"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Update om te spelen"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Update vereist"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Een update is vereist om {name} te spelen. Update naar de laatste versie om het spel te starten."
|
||||
},
|
||||
@@ -907,26 +886,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader is gegeven door de server"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Een bestand wordt alleen beoordeeld als het naar Modrinth is geüpload, ongeacht het bestandsformaat (inclusief .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Toon deze waarschuwing niet opnieuw"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Bevestig installatie"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Installeer toch"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Malware wordt vaak verspreid via modpack-bestanden door ze te delen op platforms zoals Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "We konden dit bestand niet vinden op Modrinth. We raden ten zeerste aan om alleen bestanden te installeren van bronnen die u vertrouwt."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Waarschuwing voor onbekend bestand"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,220 @@
|
||||
{
|
||||
"app.action-bar.downloading-java": {
|
||||
"message": "Laster ned Java {version}"
|
||||
},
|
||||
"app.action-bar.downloading-update": {
|
||||
"message": "Laster ned oppdatering"
|
||||
},
|
||||
"app.action-bar.downloads": {
|
||||
"message": "Nedlastninger"
|
||||
},
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Skjul flere kjørende tilfeller"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Åpne tilfelle"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Prøv igjen"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Ukjent tilfelle"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Installeringer"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Gjør om til primærtilfelle"
|
||||
},
|
||||
"app.action-bar.no-instances-running": {
|
||||
"message": "Ingen kjørende tilfeller"
|
||||
},
|
||||
"app.action-bar.offline": {
|
||||
"message": "Uten nett"
|
||||
},
|
||||
"app.action-bar.primary-instance": {
|
||||
"message": "Primærtilfelle"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "Last inn på nytt for å oppdatere"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "Vis flere kjørende tilfeller"
|
||||
},
|
||||
"app.action-bar.stop-instance": {
|
||||
"message": "Stopp tilfelle"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "Oppdater"
|
||||
},
|
||||
"app.action-bar.view-active-downloads": {
|
||||
"message": "Vis aktive nedlastninger"
|
||||
},
|
||||
"app.action-bar.view-instance": {
|
||||
"message": "Vis tilfelle"
|
||||
},
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Vis logger"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Skrur på avansert rendering, som for eksempel uskarphetseffekter, som kan forårsake ytelsesproblemer om man ikke har maskinvareaksellerert rendering."
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.title": {
|
||||
"message": "Avansert rendering"
|
||||
},
|
||||
"app.appearance-settings.color-theme.description": {
|
||||
"message": "Velg ditt foretrukne fargetema for Modrinth App."
|
||||
},
|
||||
"app.appearance-settings.color-theme.title": {
|
||||
"message": "Fargetema"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.description": {
|
||||
"message": "Endre sida som vises når launcheren åpnes."
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.home": {
|
||||
"message": "Hjem"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.library": {
|
||||
"message": "Bibliotek"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.title": {
|
||||
"message": "Åpningsside"
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.description": {
|
||||
"message": "Skjuler navnelappen over din spiller på utseende siden."
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.title": {
|
||||
"message": "Gjøm navnelapp"
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.title": {
|
||||
"message": "Minimer launcheren"
|
||||
},
|
||||
"app.appearance-settings.select-option": {
|
||||
"message": "Velg et alternativ"
|
||||
},
|
||||
"app.appearance-settings.show-play-time.description": {
|
||||
"message": "Viser hvor lenge du har spilt et tilfelle."
|
||||
},
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Vis spilletid"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Hopper automatisk over lav-rissiko fastslåelser som modpakkeinstalasjonsduplikat, vanlig innholdsletting, bolkoppdateringer, avkoble modpakker, og reparasjonsprompter. Farlige advarsler vil fortsatt vises."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Hopp over mindre viktige advarsler"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Aktiverer evnen til å skru sidefeltet av/på."
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.title": {
|
||||
"message": "Sidefeltsveksling"
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.description": {
|
||||
"message": "Hvis du prøver å laste ned en Modrinth Pakke fil (.mrpack) som er ukjent for Modrinth så kommer vi til å forsikre oss om at du forstår risikoene før du installerer den."
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.title": {
|
||||
"message": "Advar meg før jeg installerer ukjente modpakker"
|
||||
},
|
||||
"app.auth-servers.unreachable.body": {
|
||||
"message": "Minecraft-autentiseringsservere kan være nede for øyeblikket. Kontroller internettforbindelsen din og prøv igjen senere."
|
||||
},
|
||||
"app.auth-servers.unreachable.header": {
|
||||
"message": "Kan ikke nå autentiseringsservere"
|
||||
},
|
||||
"app.browse.add-servers-to-instance": {
|
||||
"message": "Legger til server til tilfelle"
|
||||
},
|
||||
"app.browse.add-to-an-instance": {
|
||||
"message": "Legg til til et tilfelle"
|
||||
},
|
||||
"app.browse.add-to-instance": {
|
||||
"message": "Legg til til tilfelle"
|
||||
},
|
||||
"app.browse.add-to-instance-name": {
|
||||
"message": "Legg til til {instanceName}"
|
||||
},
|
||||
"app.browse.added": {
|
||||
"message": "Lagt til"
|
||||
},
|
||||
"app.browse.already-added": {
|
||||
"message": "Allerede lagt til"
|
||||
},
|
||||
"app.browse.back-to-instance": {
|
||||
"message": "Tilbake til tilfelle"
|
||||
},
|
||||
"app.browse.discover-content": {
|
||||
"message": "Oppdag innhold"
|
||||
},
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Oppdag servere"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Gjem servere som allerede er lagt til"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpakker"
|
||||
},
|
||||
"app.browse.server-instance-content-warning": {
|
||||
"message": "Å legge til innhold kan ødelegge komatibilitet når du blir med i serveren. Alt tilleggsinnhold vil også forsvinne når du oppdaterer servertilfelleinnholdet."
|
||||
},
|
||||
"app.browse.server.installing": {
|
||||
"message": "Installerer"
|
||||
},
|
||||
"app.content-install.no-compatible-versions": {
|
||||
"message": "Ingen tilgjengelige versjoner matcher {compatibilityLabel}. Velg en versjon for å installere uansett. Avhengigheter vil ikke bli installert automatisk."
|
||||
},
|
||||
"app.export-modal.description-placeholder": {
|
||||
"message": "Skriv en modpakkebeskrivelse..."
|
||||
},
|
||||
"app.export-modal.export-button": {
|
||||
"message": "Eksperter"
|
||||
},
|
||||
"app.export-modal.header": {
|
||||
"message": "Eksperter modpakke"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Navn på modpakke"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "Validerer Java {version}"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Leser pakkemanifest"
|
||||
},
|
||||
"app.instance.confirm-delete.delete-button": {
|
||||
"message": "Slett tilfelle"
|
||||
},
|
||||
"app.instance.confirm-delete.header": {
|
||||
"message": "Slett tilfelle"
|
||||
},
|
||||
"app.instance.modpack-already-installed.create": {
|
||||
"message": "Opprett"
|
||||
},
|
||||
"app.instance.modpack-already-installed.header": {
|
||||
"message": "Modpakka er allerede installert"
|
||||
},
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "Tilfelle"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "Laster ned {current, number}/{total, number} prosjekter..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "Fullfører oppdatering..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "prosjekt"
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "\"{name}\" ble lagt til"
|
||||
},
|
||||
"app.instance.mods.projects-were-added": {
|
||||
"message": "{count} prosjekter ble lagt til"
|
||||
},
|
||||
"app.instance.mods.share-text": {
|
||||
"message": "Sjekk ut prosjektene jeg bruker i min modpakke!"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installer for å spille"
|
||||
},
|
||||
@@ -12,20 +222,14 @@
|
||||
"message": "Installer"
|
||||
},
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {#mod} other {# mods}}"
|
||||
"message": "{count, plural, one {#mod} other {# modder}}"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Delt instans"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Delt serverinstans"
|
||||
"message": "Delt tilfelle"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Oppdater for å spille"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Krever oppdatering"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Ei oppdatering er påkrevd for å spille {name}. Vær så snill å oppdater til den siste versjonen av spillet for å spille det."
|
||||
},
|
||||
@@ -39,7 +243,7 @@
|
||||
"message": "Utseende"
|
||||
},
|
||||
"app.settings.tabs.default-instance-options": {
|
||||
"message": "Standard instansinstillinger"
|
||||
"message": "Vanlige tilfelleinstillinger"
|
||||
},
|
||||
"app.settings.tabs.java-installations": {
|
||||
"message": "Java installasjoner"
|
||||
@@ -102,10 +306,10 @@
|
||||
"message": "Aktiv"
|
||||
},
|
||||
"friends.heading.offline": {
|
||||
"message": "Offline"
|
||||
"message": "Av"
|
||||
},
|
||||
"friends.heading.online": {
|
||||
"message": "Online"
|
||||
"message": "På"
|
||||
},
|
||||
"friends.heading.pending": {
|
||||
"message": "Ventende"
|
||||
@@ -246,10 +450,10 @@
|
||||
"message": "Før oppstart"
|
||||
},
|
||||
"instance.settings.tabs.hooks.pre-launch.description": {
|
||||
"message": "Kørt før instansen startes."
|
||||
"message": "Kjøres før tilfellet startes."
|
||||
},
|
||||
"instance.settings.tabs.hooks.pre-launch.enter": {
|
||||
"message": "Skriv inn kommando før start..."
|
||||
"message": "Skriv inn forstartskommando..."
|
||||
},
|
||||
"instance.settings.tabs.hooks.title": {
|
||||
"message": "Spillstartkroker"
|
||||
@@ -258,7 +462,7 @@
|
||||
"message": "Wrapper"
|
||||
},
|
||||
"instance.settings.tabs.hooks.wrapper.description": {
|
||||
"message": "Wrapper-kommando for å starte Minecraft."
|
||||
"message": "Innpakningskommando for å starte Minecraft."
|
||||
},
|
||||
"instance.settings.tabs.hooks.wrapper.enter": {
|
||||
"message": "Skriv inn wrapper-kommando..."
|
||||
@@ -272,6 +476,9 @@
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Java og minne"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-memory-allocation": {
|
||||
"message": "Egendefinert minneallokasjon"
|
||||
},
|
||||
"instance.settings.tabs.java.environment-variables": {
|
||||
"message": "Miljøvariabler"
|
||||
},
|
||||
@@ -303,7 +510,7 @@
|
||||
"message": "Høyde"
|
||||
},
|
||||
"instance.settings.tabs.window.height.description": {
|
||||
"message": "Høyde av spillvindu når spillet startes."
|
||||
"message": "Høyden til spillvinduet når spillet startes."
|
||||
},
|
||||
"instance.settings.tabs.window.height.enter": {
|
||||
"message": "Angi høyde..."
|
||||
@@ -312,7 +519,7 @@
|
||||
"message": "Bredde"
|
||||
},
|
||||
"instance.settings.tabs.window.width.description": {
|
||||
"message": "Bredde av spillvindu når spillet startes."
|
||||
"message": "Bredden til spillvinduet når spillet startes."
|
||||
},
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Angi bredde..."
|
||||
@@ -330,7 +537,7 @@
|
||||
"message": "Ikke vis på Hjem"
|
||||
},
|
||||
"instance.worlds.game_already_open": {
|
||||
"message": "Instansen er allerede open"
|
||||
"message": "Tilfellet er allerede open"
|
||||
},
|
||||
"instance.worlds.hardcore": {
|
||||
"message": "Hardbarket modus"
|
||||
@@ -348,7 +555,7 @@
|
||||
"message": "Du kan bare hoppe rett inn i enkeltspiller-verdener på Minecraft 1.20+"
|
||||
},
|
||||
"instance.worlds.play_instance": {
|
||||
"message": "Spill instans"
|
||||
"message": "Spill tilfelle"
|
||||
},
|
||||
"instance.worlds.view_instance": {
|
||||
"message": "Vis instans"
|
||||
|
||||
@@ -9,7 +9,13 @@
|
||||
"message": "Pobrania"
|
||||
},
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Ukryj włączone instancje"
|
||||
"message": "Ukryj aktywne instancje"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Skopiowano"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Kopiuj szczegóły"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Odrzuć"
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Spróbuj ponownie"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Anulowano z powodu zamknięcia aplikacji"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Nie można było odczytać paczki modów"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Anulowano"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "Czyszczenie nie powiodło się"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Nie udało się pobrać plików"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Pobrany plik jest uszkodzony"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Nie udało się zapisać plików"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Nie można było ukończyć pobierania"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Nie znaleziono instancji"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Ścieżka plików jest niewłaściwa"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Niewłaściwe dane paczki modów"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Pliki paczki modów zawierają niewłaściwe metadane"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Ustawianie Javy nie powiodło się"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Ustawianie loadera nie powiodło się"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Nie udało się zaktualizować danych lokalnych"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Ustawianie Minecraft nie powiodło się"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Nie udało się połączyć z serwerami Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Brak permisji, aby zapisać pliki"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Pobieranie paczki nie powiodło się"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Coś poszło nie tak"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Nieznana instancja"
|
||||
},
|
||||
@@ -30,7 +96,7 @@
|
||||
"message": "Ustaw jako główną instancję"
|
||||
},
|
||||
"app.action-bar.no-instances-running": {
|
||||
"message": "Żadna instancja nie jest włączona"
|
||||
"message": "Brak włączonych instancji"
|
||||
},
|
||||
"app.action-bar.offline": {
|
||||
"message": "Offline"
|
||||
@@ -39,7 +105,7 @@
|
||||
"message": "Główna instancja"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "Załaduj ponownie, by zaktualizować"
|
||||
"message": "Załaduj ponownie, aby zaktualizować"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "Pokaż więcej włączonych instancji"
|
||||
@@ -66,7 +132,7 @@
|
||||
"message": "Zaawansowane renderowanie"
|
||||
},
|
||||
"app.appearance-settings.color-theme.description": {
|
||||
"message": "Wybierz preferowany motyw w Modrinth app."
|
||||
"message": "Wybierz preferowany motyw kolorystyczny dla Modrinth App."
|
||||
},
|
||||
"app.appearance-settings.color-theme.title": {
|
||||
"message": "Motyw"
|
||||
@@ -84,10 +150,10 @@
|
||||
"message": "Domyślna strona główna"
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.description": {
|
||||
"message": "Wyłącza nazwę użytkownika na stronie skórek."
|
||||
"message": "Wyłącza nazwę użytkownika nad modelem gracza na stronie skórek."
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.title": {
|
||||
"message": "Schowaj nazwę"
|
||||
"message": "Ukryj nazwę"
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.description": {
|
||||
"message": "Pokazuje ostatnie światy w sekcji \"Wskocz z powrotem do światów\" na stronie głównej."
|
||||
@@ -219,7 +285,7 @@
|
||||
"message": "Finalizowanie"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Przygotowywanie instancji"
|
||||
"message": "Oczekuje na instalację"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Przygotowywanie środowiska Java"
|
||||
@@ -228,10 +294,10 @@
|
||||
"message": "Pobieranie Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Wypakowywanie Javy {version}"
|
||||
"message": "Wypakowywanie Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Pobieranie Javy {version}"
|
||||
"message": "Pobieranie Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Przygotowywanie Java {version}"
|
||||
@@ -240,10 +306,10 @@
|
||||
"message": "Sprawdzanie Java {version}"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Ustalanie manifestu paczki"
|
||||
"message": "Sprawdzanie manifestu paczki"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "Ustalanie programu ładującego"
|
||||
"message": "Ustalanie loadera"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Ustalanie wersji Minecraft"
|
||||
@@ -255,13 +321,13 @@
|
||||
"message": "Przywracanie"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Uruchamianie procesorów programu ładującego"
|
||||
"message": "Uruchamianie procesorów loadera"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Wszystkie dane z Twojej instancji zostaną trwale usunięte, w tym Twoje światy, pliki konfiguracji i jakakolwiek dodana zawartość."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-header": {
|
||||
"message": "Tej akcji nie można odwrócić"
|
||||
"message": "Tej akcji nie można cofnąć"
|
||||
},
|
||||
"app.instance.confirm-delete.delete-button": {
|
||||
"message": "Usuń instancję"
|
||||
@@ -297,13 +363,13 @@
|
||||
"message": "Dodano \"{name}\""
|
||||
},
|
||||
"app.instance.mods.share-text": {
|
||||
"message": "Sprawdź projekty, które używam w mojej paczce modów!"
|
||||
"message": "Sprawdź projekty, których używam w mojej paczce modów!"
|
||||
},
|
||||
"app.instance.mods.share-title": {
|
||||
"message": "Udostępnianie zawartości paczki modów"
|
||||
},
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Przesyłanie powiodło się"
|
||||
"message": "Przesyłanie zakończone sukcesem"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Dodaj serwer"
|
||||
@@ -356,9 +422,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Szukaj wśród {count} światów..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Wymagana zawartość"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Zainstaluj, aby grać"
|
||||
},
|
||||
@@ -368,39 +431,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} few {# mody} other {# modów}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Wymagana paczka modów"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Ten serwer wymaga modów, aby na nim grać. Kliknij \"Zainstaluj\" aby otrzymać potrzebne pliki z Modrinth, a potem dołącz bezpośrednio do serwera."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Wspólna instancja"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Wspólna instancja serwera"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Pokaż zawartość"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Zaktualizuj, by grać"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Wymagana jest aktualizacja"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Aktualizacja jest wymagana, aby grać w {name}. Proszę zaktualizować do najnowszej wersji, aby uruchomić grę."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ten projekt jest już zainstalowany"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Zmień wersję"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Powróć do odkrywania"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Zainstaluj zasoby do instancji"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Wszystkie wersje"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Pobierz w przeglądarce"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Instalowanie"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Już zainstalowano"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Tryb dewelopera włączony."
|
||||
},
|
||||
@@ -438,25 +504,25 @@
|
||||
"message": "Usuń skórkę"
|
||||
},
|
||||
"app.skins.delete-modal.description": {
|
||||
"message": "To trwale usunie wybraną skórkę. Tej akcji nie można odwrócić."
|
||||
"message": "To trwale usunie wybraną skórkę. Tej akcji nie można cofnąć."
|
||||
},
|
||||
"app.skins.delete-modal.title": {
|
||||
"message": "Czy na pewno chcesz usunąć tę skórkę?"
|
||||
},
|
||||
"app.skins.dropped-file-error.text": {
|
||||
"message": "Nie udało się odczytać wybranego pliku."
|
||||
"message": "Nie udało się odczytać upuszczonego pliku."
|
||||
},
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Błąd podczas przetwarzania pliku"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Edytuj skina"
|
||||
"message": "Edytuj skórkę"
|
||||
},
|
||||
"app.skins.modal.add-skin-button": {
|
||||
"message": "Dodaj skina"
|
||||
"message": "Dodaj skórkę"
|
||||
},
|
||||
"app.skins.modal.add-title": {
|
||||
"message": "Dodawanie skina"
|
||||
"message": "Dodawanie skórki"
|
||||
},
|
||||
"app.skins.modal.arm-style-section": {
|
||||
"message": "Styl ramion"
|
||||
@@ -474,10 +540,10 @@
|
||||
"message": "Peleryny"
|
||||
},
|
||||
"app.skins.modal.edit-title": {
|
||||
"message": "Edytuj skina"
|
||||
"message": "Edytowanie skórki"
|
||||
},
|
||||
"app.skins.modal.make-edit-first-tooltip": {
|
||||
"message": "Wpierw zmień jakoś skórkę!"
|
||||
"message": "Zmodyfikuj najpierw skórkę!"
|
||||
},
|
||||
"app.skins.modal.no-cape-tooltip": {
|
||||
"message": "Brak peleryny"
|
||||
@@ -489,7 +555,7 @@
|
||||
"message": "Zamień teksturę"
|
||||
},
|
||||
"app.skins.modal.save-skin-button": {
|
||||
"message": "Zapisz skina"
|
||||
"message": "Zapisz skórkę"
|
||||
},
|
||||
"app.skins.modal.saving-tooltip": {
|
||||
"message": "Zapisywanie..."
|
||||
@@ -521,6 +587,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -570,7 +639,7 @@
|
||||
"message": "Zaloguj się"
|
||||
},
|
||||
"app.skins.title": {
|
||||
"message": "Wybierz skórkę"
|
||||
"message": "Wybór skórki"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Wersja Modrinth App v{version} została pobrana. Załaduj ponownie, żeby zaktualizować teraz, albo automatycznie, gdy zamkniesz Modrinth App."
|
||||
@@ -870,7 +939,7 @@
|
||||
"message": "Niestandardowe argumenty Java"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-java-installation": {
|
||||
"message": "Niestandardowa instalacja Javy"
|
||||
"message": "Niestandardowa instalacja Java"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-memory-allocation": {
|
||||
"message": "Niestandardowa alokacja pamięci"
|
||||
@@ -879,7 +948,7 @@
|
||||
"message": "Zmienne środowiskowe..."
|
||||
},
|
||||
"instance.settings.tabs.java.enter-java-arguments": {
|
||||
"message": "Argumenty Javy..."
|
||||
"message": "Argumenty Java..."
|
||||
},
|
||||
"instance.settings.tabs.java.environment-variables": {
|
||||
"message": "Zmienne środowiskowe"
|
||||
@@ -1015,26 +1084,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader jest dostarczony przez serwer"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Plik jest sprawdzony tylko, jeżeli został przesłany na Modrinth, niezależnie od formatu (w tym pliki .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Nie pokazuj ponownie"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Potwierdź instalację"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Instaluj mimo to"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Wirusy są często kryte w plikach paczek modów przesyłanych na platformach takich jak Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Nie mogliśmy znaleźć tego pliku na Modrinth. Stanowczo zalecamy instalowanie plików tylko ze źródeł, którym ufasz."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Ostrzeżenie o nieznanym pliku"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Ocultar mais instâncias em execução"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Copiado"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Copiar detalhes"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Dispensar"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Tentar novamente"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Cancelado devido ao aplicativo ter fechado"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Não foi possível ler o pacote de mods"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Cancelado"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "A limpeza não foi finalizada"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Não foi possível baixar os arquivos"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "O arquivo baixado é corrupto"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Não foi possível salvar os arquivos"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "A transferência não foi finalizada"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Instância não encontrada"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "O caminho do arquivo é inválido"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Os dados do pacote de mods é inválido"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Os arquivos do pacote de mods possui metadados inválidos"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Configuração Java não foi finalizada"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Falha na configuração do loader"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Não foi atualizar os dados locais"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Falha na configuração do Minecraft"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Não foi possível alcançar o Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Sem permissão para escrita"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Não foi possível baixar o pacote"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Algo deu errado"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Instância desconhecida"
|
||||
},
|
||||
@@ -219,7 +285,7 @@
|
||||
"message": "Finalizando"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Preparando instância"
|
||||
"message": "Na fila"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Preparando Java"
|
||||
@@ -359,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Buscar {count} mundos..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Conteúdo necessário"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instale para jogar"
|
||||
},
|
||||
@@ -371,39 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, =0 {Nenhum mod} one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Pacote de mods necessário"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Este servidor exige mods para jogar. Clique em instalar para configurar os arquivos necessários através do Modrinth, e então iniciar diretamente no servidor."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instância compartilhada"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Instância de servidor compartilhada"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Ver conteúdo"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Atualize para jogar"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Atualização necessária"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Uma atualização é necessária para jogar {name}. Atualize para a versão mais recente para iniciar o jogo."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Este projeto já foi instalado"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Trocar versão"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Voltar a descobrir"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Instalar conteúdo para a instância"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Todas as versões"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Baixar no navegador"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Instalando"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Já instalado"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Modo desenvolvedor ativado."
|
||||
},
|
||||
@@ -524,6 +590,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Construtores & Biomas"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -588,7 +657,7 @@
|
||||
"message": "Mudanças"
|
||||
},
|
||||
"app.update-popup.download": {
|
||||
"message": "Baixar ({size})"
|
||||
"message": "Instalar ({size})"
|
||||
},
|
||||
"app.update-popup.download-complete": {
|
||||
"message": "Instalação concluída"
|
||||
@@ -1018,26 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "O loader é fornecido pelo servidor"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Um arquivo só é revisado se for enviado no Modrinth, independente do formato do arquivo (incluindo .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Não exibir aviso novamente"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Confirmar instalação"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Instalar mesmo assim"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "O malware é distribuído frequentemente através de arquivos de pacote de mods compartilhados em plataformas como Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Não encontramos este arquivo no Modrinth. Nós recomendamos fortemente instalar arquivos apenas de fontes confiáveis."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Aviso de arquivo desconhecido"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,9 +110,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Exportar modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Nome do Modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Nome do Modpack"
|
||||
},
|
||||
@@ -191,9 +188,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Pesquisar {count} mundos..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Conteúdo necessário"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instala para jogar"
|
||||
},
|
||||
@@ -203,27 +197,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {mod} other {mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Modpack requerido"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Este servidor requer mods para jogares. Clica Instalar para transferir os ficheiros necessários do Modrinth, e então entrar diretamente no servidor."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instância partilhada"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Instância de servidor partilhada"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Ver conteúdo"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Atualiza para jogar"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Atualização necessária"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Uma atualização é necessária para jogar {name}. Por favor atualiza para a versão mais recente para iniciar o jogo."
|
||||
},
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
"app.auth-servers.unreachable.header": {
|
||||
"message": "Nu se pot accesa serverele de autentificare"
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Conținut necesar"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instalați pentru a juca"
|
||||
},
|
||||
@@ -17,27 +14,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural,one {#mod} other {# moduri}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Pachet de mod necesar"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Acest server necesită modificări pentru a juca. Faceți clic pe Instalare pentru a configura fișierele necesare din Modrinth, apoi lansați direct pe server."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instanță comună"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Instanță de server partajată"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Vizualizați conținutul"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Actualizați pentru a juca"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Actualizare necesară"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Este necesară o actualizare pentru a juca {name}. Vă rugăm să actualizați la cea mai recentă versiune pentru a lansa jocul."
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"message": "Скачивание Java {version}"
|
||||
},
|
||||
"app.action-bar.downloading-update": {
|
||||
"message": "Скачивание"
|
||||
"message": "Скачивание обновления"
|
||||
},
|
||||
"app.action-bar.downloads": {
|
||||
"message": "Загрузки"
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Скрыть другие активные сборки"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Скопировано"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Копировать"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Закрыть"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Повторить"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Отменено из‑за закрытия приложения"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Не удалось прочитать сборку"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Отменено"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "Очистка прервана"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Не удалось скачать файлы"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Скачанный файл повреждён"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Не удалось сохранить файлы"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Скачивание прервано"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Сборка не найдена"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Неверный путь к файлу"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Неверные данные сборки"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Неверные метаданные в файлах сборки "
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Установка Java прервана"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Не удалось установить загрузчик"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Не удалось обновить локальные данные"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Не удалось установить Minecraft"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Не удалось подключиться к Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Нет разрешения на запись"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Не удалось скачать сборку"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Произошла ошибка"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Неизвестная сборка"
|
||||
},
|
||||
@@ -39,7 +105,7 @@
|
||||
"message": "Основная сборка"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "Перезапустить"
|
||||
"message": "Перезапустить и обновить"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "Показать другие активные сборки"
|
||||
@@ -117,10 +183,10 @@
|
||||
"message": "Время игры"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Автоматически пропускает подтверждения с низким уровнем риска, такие как установка дубликатов сборок, обычное удаление контента, массовые обновления, отключение сборок и запросы на восстановление. Опасные предупреждения по-прежнему будут отображаться."
|
||||
"message": "Скрывать малозначимые подтверждения: установку копий сборок, обычное удаление контента, массовые обновления, отвязку и исправление сборок. Критические предупреждения останутся."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Пропустить несущественные предупреждения"
|
||||
"message": "Только опасные предупреждения"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Показывать кнопку скрытия боковой панели."
|
||||
@@ -213,13 +279,13 @@
|
||||
"message": "Скачивание файла сборки"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Извлечение переопределений"
|
||||
"message": "Распаковка переопределений"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Завершение"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Подготовка сборки"
|
||||
"message": "В очереди на установку"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Подготовка Java"
|
||||
@@ -242,11 +308,14 @@
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Чтение манифеста сборки"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "Разрешение загрузчика"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Загрузка версий"
|
||||
"message": "Разрешение Minecraft"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "Загрузка контента"
|
||||
"message": "Разрешение контента"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "Откат"
|
||||
@@ -279,13 +348,13 @@
|
||||
"message": "Сборка"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "Скачивание {current, number}/{total, number} проектов..."
|
||||
"message": "Скачивание проектов: {current, number}/{total, number}..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "Завершение обновления..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "Загрузка версий..."
|
||||
"message": "Разрешение версий..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "проект"
|
||||
@@ -309,7 +378,7 @@
|
||||
"message": "Найти серверы"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "Удалить"
|
||||
"message": "Удалить мир"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "Удаление мира"
|
||||
@@ -339,7 +408,7 @@
|
||||
"message": "Нет серверов и миров"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.remove-button": {
|
||||
"message": "Удалить"
|
||||
"message": "Удалить сервер"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.title": {
|
||||
"message": "Удаление сервера"
|
||||
@@ -350,9 +419,6 @@
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "Удаление {name}"
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Требуется дополнительный контент"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Установка перед запуском"
|
||||
},
|
||||
@@ -362,39 +428,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# мод} few {# мода} other {# модов}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Необходимая сборка"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Для игры на сервере требуются моды. Установите необходимые файлы с Modrinth, чтобы подключиться."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Сборка"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Общая сборка сервера"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Посмотреть содержимое"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Обновление перед запуском"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Требуется обновление"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Обновите {name} до последней версии, чтобы запустить игру."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Этот проект уже установлен"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Сменить версию"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Вернуться к поиску"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Установка контента в сборку"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Все версии"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Скачать в браузере"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Установка"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Уже установлено"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Режим разработчика включён."
|
||||
},
|
||||
@@ -507,7 +576,7 @@
|
||||
"message": "Не так быстро!"
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "Ваш порядок скинов не удалось сохранить."
|
||||
"message": "Порядок скинов не сохранился."
|
||||
},
|
||||
"app.skins.reorder-error.title": {
|
||||
"message": "Не удалось изменить порядок скинов"
|
||||
@@ -515,6 +584,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -888,7 +960,7 @@
|
||||
"message": "Выделенная память"
|
||||
},
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/path/to/java"
|
||||
"message": "/путь/к/java"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Окно"
|
||||
@@ -1006,26 +1078,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Загрузчик управляется сервером"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Файл проверяется только в том случае, если он загружен на Modrinth, независимо от его формата (включая .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Больше не предупреждать"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Подтверждение установки"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Всё равно установить"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Вредоносное ПО часто распространяется через сборки на таких платформах, как Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Этот файл не найден на Modrinth. Рекомендуется скачивать файлы только из надёжных источников."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Предупреждение о неизвестном файле"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,166 @@
|
||||
{
|
||||
"app.action-bar.downloading-java": {
|
||||
"message": "Instalacija Jave {version}"
|
||||
},
|
||||
"app.action-bar.downloading-update": {
|
||||
"message": "Instaliranje ažuriranja"
|
||||
},
|
||||
"app.action-bar.downloads": {
|
||||
"message": "Instalacije"
|
||||
},
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Sakrij više pokrenutih instanca"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Kopirano"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Kopiraj detalje"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Otpusti"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Otvori instancu"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Probaj ponovo"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Otkazano zbog zatvaranja aplikacije"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Otkazano"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Nije bilo moguće spremiti datoteke"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Nepoznata instanca"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Instalacije"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Učini primarnom instancom"
|
||||
},
|
||||
"app.action-bar.no-instances-running": {
|
||||
"message": "Nema pokrenutih instanca"
|
||||
},
|
||||
"app.action-bar.offline": {
|
||||
"message": "Oflajn"
|
||||
},
|
||||
"app.action-bar.primary-instance": {
|
||||
"message": "Primarna instanca"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "Ponovo učitaj da ažuriraš"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "Pokaži više pokrenutih instanca"
|
||||
},
|
||||
"app.action-bar.stop-instance": {
|
||||
"message": "Prekini instancu"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "Ažuiraj"
|
||||
},
|
||||
"app.action-bar.view-active-downloads": {
|
||||
"message": "Vidi aktivna preuzimanja"
|
||||
},
|
||||
"app.action-bar.view-instance": {
|
||||
"message": "Vidi instancu"
|
||||
},
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Pregledaj dnevnike"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Omogućava napredno renderovanje kao što su efekti zamućenja koji mogu izazvati probleme sa performansama bez hardverski ubrzanog renderovanja."
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.title": {
|
||||
"message": "Napredno renderovanje"
|
||||
},
|
||||
"app.appearance-settings.color-theme.description": {
|
||||
"message": "Izaberi svoju preferiranu temu boja za Modrinth aplikaciju."
|
||||
},
|
||||
"app.appearance-settings.color-theme.title": {
|
||||
"message": "Tema boje"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.description": {
|
||||
"message": "Promeni stranicu na kojoj se otvara pokretač."
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.home": {
|
||||
"message": "Početna stranica"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.library": {
|
||||
"message": "Biblioteka"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.title": {
|
||||
"message": "Podrazumevana odredišna stranica"
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.description": {
|
||||
"message": "Onemogućava oznaku sa imenom iznad tvog igrača na stranici sa skinovima."
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.title": {
|
||||
"message": "Sakrij ime"
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.description": {
|
||||
"message": "Uključuje nedavne svetove u odeljku „Povratak“ na početnoj stranici."
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.title": {
|
||||
"message": "Vrati se u svetove"
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.description": {
|
||||
"message": "Minimiziraj pokretač kada se pokrene Minecraft proces."
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.title": {
|
||||
"message": "Minimiziraj pokretač"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.description": {
|
||||
"message": "Koristi okvir sistemskog prozora (potrebno je ponovno pokretanje aplikacije)."
|
||||
},
|
||||
"app.appearance-settings.native-decorations.title": {
|
||||
"message": "Zavičajni ukrasi"
|
||||
},
|
||||
"app.appearance-settings.select-option": {
|
||||
"message": "Izaberi opciju"
|
||||
},
|
||||
"app.appearance-settings.show-play-time.description": {
|
||||
"message": "Pokazuje koliko vremena si proveo igrajući instancu."
|
||||
},
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Pokazivaj vreme igranja"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Automatski preskače potvrde niskog rizika kao duplirane instalacije modpakova, normalno brisanje sadržaja, grupna ažuriranja, prekidanje veze sa modpakovima i upiti za popravku. Opasna upozorenja će se i dalje prikazivati."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Preskači nebitna upozorenja"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Omogućava mogućnost prebacivanja bočne trake."
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.title": {
|
||||
"message": "Prebaci bočnu traku"
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.description": {
|
||||
"message": "Ako pokušaš da instaliraš datoteku Modrinth Pack datoteke (.mrpack) koja nije hostovana na Modrinthu, uverićemo se da razumeš rizike pre nego što je instaliraš."
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.title": {
|
||||
"message": "Upozoti me prije instalacije nepoznatih modpackova"
|
||||
},
|
||||
"app.auth-servers.unreachable.body": {
|
||||
"message": "Minecraft serveri za autentifikaciju su možda trenutno nedostupni. Molimo vas da proverite vašu internet vezu i pokušajte ponovo kasnije."
|
||||
},
|
||||
"app.auth-servers.unreachable.header": {
|
||||
"message": "Serveri za autentifikaciju su nedostupni"
|
||||
},
|
||||
"app.browse.add-servers-to-instance": {
|
||||
"message": "Dodavanje servera na instancu"
|
||||
},
|
||||
"app.browse.add-to-an-instance": {
|
||||
"message": "Dodaj u instancu"
|
||||
},
|
||||
"app.browse.add-to-instance": {
|
||||
"message": "Dodaj na instancu"
|
||||
},
|
||||
@@ -17,12 +173,30 @@
|
||||
"app.browse.already-added": {
|
||||
"message": "Već je dodato"
|
||||
},
|
||||
"app.browse.back-to-instance": {
|
||||
"message": "Nazad na instancu"
|
||||
},
|
||||
"app.browse.discover-content": {
|
||||
"message": "Otkrij sadržaj"
|
||||
},
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Otkrij servere"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Sakrij već dodane servere"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpackovi"
|
||||
},
|
||||
"app.browse.server-instance-content-warning": {
|
||||
"message": "Dodavanje sadržaja može da prekine kompatibilnost prilikom pridruživanja serveru. Bilo koji dodat sadržaj će takođe biti izgubljen kada ažuriraš sadržaj instance servera."
|
||||
},
|
||||
"app.browse.server.installing": {
|
||||
"message": "Instaliranje"
|
||||
},
|
||||
"app.content-install.no-compatible-versions": {
|
||||
"message": "Nijedna dostupna verzija ne odgovara {compatibilityLabel}. Izaberite verziju za instaliranje u svakom slučaju. Zavisnosti se neće instalirati automatski."
|
||||
},
|
||||
"app.export-modal.description-placeholder": {
|
||||
"message": "Ukucaj opis modpacka..."
|
||||
},
|
||||
@@ -33,7 +207,7 @@
|
||||
"message": "Izvezi modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Ime Modpacka"
|
||||
"message": "Ime modpacka"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Ime modpacka"
|
||||
@@ -44,6 +218,57 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Instaliranje sadržaja"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Instaliranja Minecraft-a"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Instaliranje paket datoteke"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Ekstrahovanje prečica"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Finaliziranje"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Pripremanje Jave"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Instalacije Jave {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Izdvajanje Jave {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Preuzimanje Jave {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Pripremanje Jave {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "Validacija Jave {version}"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Čitanje manifesta paketa"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "Rešavanje učitavača"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Rešavanje Minecrafta"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "Rešavanje sadržaja"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "Vraćanje"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Pokret procesora za učitavanje"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Svi podaci za tvoju instancu će biti trajno izbrisani, uključujući tvoje svetove, konfiguracije, i sav instaliran sadržaj."
|
||||
},
|
||||
@@ -57,7 +282,7 @@
|
||||
"message": "Izbriši instancu"
|
||||
},
|
||||
"app.instance.modpack-already-installed.body": {
|
||||
"message": "Ovaj modpack je već instaliran u <bold>{instanceName}</bold> instancu. Da li ste sigurni da želite da je duplirate?"
|
||||
"message": "Ovaj modpack je već instaliran u <bold>{instanceName}</bold> instancu. Da li si siguran da želiš da je dupliraš?"
|
||||
},
|
||||
"app.instance.modpack-already-installed.create": {
|
||||
"message": "Napravi"
|
||||
@@ -68,6 +293,15 @@
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "Instanca"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "Instaliranje {current, number}/{total, number} projekata..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "Ažuriranje se završava..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "Rešavanje verzija..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "projekat"
|
||||
},
|
||||
@@ -92,6 +326,18 @@
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "Pretraži servere"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "Obriši svet"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "Obriši svet"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "Ovaj svet će biti trajno izbrisan iz ove instance. Ova radnja se ne može poništiti."
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "Brisanje {name}"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "Modifikovano"
|
||||
},
|
||||
@@ -110,12 +356,78 @@
|
||||
"app.instance.worlds.no-worlds-heading": {
|
||||
"message": "Nema dodatih servera niti svetova"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.remove-button": {
|
||||
"message": "Ukloni server"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.title": {
|
||||
"message": "Ukloni server"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-body": {
|
||||
"message": "Ovaj server će biti uklonjen sa tvoje liste servera i sa liste servera u igri. Možeš ga ponovo dodati kasnije ako znaš adresu."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "Uklanjanje {name}"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Pretraži {count} svetova..."
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instaliraj da bi igrao"
|
||||
},
|
||||
"app.modal.install-to-play.install-button": {
|
||||
"message": "Instaliraj"
|
||||
},
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# modova}}"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Deljena instanca"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Pogledaj sadržaj"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Ažuriraj da bi igrao"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Potrebno je ažuriranje da biste igrali {name}. Molimo te da ažuriraš na najnoviju verziju da bi pokrenuo igru."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ovaj projekat je već instaliran"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Promeni verziju"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Nazad da otkrivanje"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Instaliraj sadržaj na instancu"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Sve verzije"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Preuzmi u pregledaču"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Instaliranje"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Već instalirano"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Režim programera je ukljućen."
|
||||
},
|
||||
"app.settings.downloading": {
|
||||
"message": "Instaliranje v{version}"
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Izgled"
|
||||
},
|
||||
"app.settings.tabs.default-instance-options": {
|
||||
"message": "Podrazumevane opcije instance"
|
||||
},
|
||||
"app.settings.tabs.java-installations": {
|
||||
"message": "Java instalacije"
|
||||
},
|
||||
@@ -125,6 +437,231 @@
|
||||
"app.settings.tabs.privacy": {
|
||||
"message": "Privatnost"
|
||||
},
|
||||
"app.settings.tabs.resource-management": {
|
||||
"message": "Upravljanje resursima"
|
||||
},
|
||||
"app.skins.add-button": {
|
||||
"message": "Dodaj skin"
|
||||
},
|
||||
"app.skins.add-button.drag-and-drop": {
|
||||
"message": "Prevuci i ispusti"
|
||||
},
|
||||
"app.skins.apply-button": {
|
||||
"message": "Primeni"
|
||||
},
|
||||
"app.skins.delete-button": {
|
||||
"message": "Obriši skin"
|
||||
},
|
||||
"app.skins.delete-modal.description": {
|
||||
"message": "Ovim ćeš trajno obrisati izabrani skin. Ova radnja se ne može poništiti."
|
||||
},
|
||||
"app.skins.delete-modal.title": {
|
||||
"message": "Da li si siguran da želiš da obrišeš ovaj skin?"
|
||||
},
|
||||
"app.skins.dropped-file-error.text": {
|
||||
"message": "Čitanje otpuštene datoteke nije uspelo."
|
||||
},
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Greška pri obradi datoteke"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Uredite skin"
|
||||
},
|
||||
"app.skins.modal.add-skin-button": {
|
||||
"message": "Dodaj skin"
|
||||
},
|
||||
"app.skins.modal.add-title": {
|
||||
"message": "Dodavanje skina"
|
||||
},
|
||||
"app.skins.modal.arm-style-section": {
|
||||
"message": "Stil ruki"
|
||||
},
|
||||
"app.skins.modal.arm-style-slim": {
|
||||
"message": "Tanko"
|
||||
},
|
||||
"app.skins.modal.arm-style-wide": {
|
||||
"message": "Široko"
|
||||
},
|
||||
"app.skins.modal.cape-fallback-name": {
|
||||
"message": "Ogrtač"
|
||||
},
|
||||
"app.skins.modal.cape-section": {
|
||||
"message": "Ogrtač"
|
||||
},
|
||||
"app.skins.modal.edit-title": {
|
||||
"message": "Uređivanje skina"
|
||||
},
|
||||
"app.skins.modal.make-edit-first-tooltip": {
|
||||
"message": "Prvo napravi izmene na skinu!"
|
||||
},
|
||||
"app.skins.modal.no-cape-tooltip": {
|
||||
"message": "Bez ogrtača"
|
||||
},
|
||||
"app.skins.modal.none-cape-option": {
|
||||
"message": "Bez"
|
||||
},
|
||||
"app.skins.modal.replace-texture-button": {
|
||||
"message": "Zameni teksturu"
|
||||
},
|
||||
"app.skins.modal.save-skin-button": {
|
||||
"message": "Sačuvaj kožu"
|
||||
},
|
||||
"app.skins.modal.saving-tooltip": {
|
||||
"message": "Sačuvavanje..."
|
||||
},
|
||||
"app.skins.modal.texture-section": {
|
||||
"message": "Tekstura"
|
||||
},
|
||||
"app.skins.modal.upload-skin-first-tooltip": {
|
||||
"message": "Prvo otpremite skin!"
|
||||
},
|
||||
"app.skins.preview.edit-button": {
|
||||
"message": "Uredi skin"
|
||||
},
|
||||
"app.skins.previewing-badge": {
|
||||
"message": "Pregled"
|
||||
},
|
||||
"app.skins.rate-limit.text": {
|
||||
"message": "Prečesto menjaš skin. Mojangovi serveri su privremeno blokirali dalje zahteve. Molimo sačekaj trenutak pre nego što pokušaš ponovo."
|
||||
},
|
||||
"app.skins.rate-limit.title": {
|
||||
"message": "Uspori!"
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "Tvoj redosled skinova nije mogao biti sačuvan."
|
||||
},
|
||||
"app.skins.reorder-error.title": {
|
||||
"message": "Neuspešno preuređivanje skinova"
|
||||
},
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
"app.skins.section.default-skins": {
|
||||
"message": "Podrazumevani skinovi"
|
||||
},
|
||||
"app.skins.section.minecon-earth-2017": {
|
||||
"message": "MINECON Earth 2017"
|
||||
},
|
||||
"app.skins.section.modrinth": {
|
||||
"message": "Modrinth"
|
||||
},
|
||||
"app.skins.section.modrinth-pride": {
|
||||
"message": "Modrinth Ponos"
|
||||
},
|
||||
"app.skins.section.modrinth-pride.tooltip": {
|
||||
"message": "Dobio si ove skinove za donaciju za prikupljanje sredstava Modrinth Ponos tokom Meseca ponosa."
|
||||
},
|
||||
"app.skins.section.mounts-of-mayhem": {
|
||||
"message": "Mounts of Mayhem"
|
||||
},
|
||||
"app.skins.section.saved-skins": {
|
||||
"message": "Sačuvani skinovi"
|
||||
},
|
||||
"app.skins.section.striding-hero": {
|
||||
"message": "Striding Hero"
|
||||
},
|
||||
"app.skins.section.the-copper-age": {
|
||||
"message": "The Copper Age"
|
||||
},
|
||||
"app.skins.section.the-garden-awakens": {
|
||||
"message": "The Garden Awakens"
|
||||
},
|
||||
"app.skins.section.tiny-takeover": {
|
||||
"message": "Tiny Takeover"
|
||||
},
|
||||
"app.skins.sign-in.button": {
|
||||
"message": "Prijavi se"
|
||||
},
|
||||
"app.skins.sign-in.description": {
|
||||
"message": "Prijavi se na svoj Minecraft račun da bi koristio funkcije upravljanja skinovima u Modrinth aplikaciji."
|
||||
},
|
||||
"app.skins.sign-in.rinthbot-alt": {
|
||||
"message": "Uzbuđeni Modrinth Bot"
|
||||
},
|
||||
"app.skins.sign-in.title": {
|
||||
"message": "Molimo prijavi se"
|
||||
},
|
||||
"app.skins.title": {
|
||||
"message": "Selektor skina"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Preuzimanje Modrinth aplikacije v{version} je završeno. Ponovo učitaj da bi ažurirao sada ili automatski kada zatvoriš Modrinth aplikaciju."
|
||||
},
|
||||
"app.update-popup.body.linux": {
|
||||
"message": "Dostupna je Modrinth aplikacija v{version}. Koristi menadžer paketa da bi ažurirao za najnovije funkcije i ispravke!"
|
||||
},
|
||||
"app.update-popup.body.metered": {
|
||||
"message": "Modrinth aplikacija v{version} je sada dostupna! Pošto si na mreži sa ograničenjem interneta, nismo je automatski preuzeli."
|
||||
},
|
||||
"app.update-popup.changelog": {
|
||||
"message": "Spisak promena"
|
||||
},
|
||||
"app.update-popup.download": {
|
||||
"message": "Instalacija ({size})"
|
||||
},
|
||||
"app.update-popup.download-complete": {
|
||||
"message": "Preuzimanje je završeno"
|
||||
},
|
||||
"app.update-popup.reload": {
|
||||
"message": "Učitaj ponovo da bi ažurirao"
|
||||
},
|
||||
"app.update-popup.title": {
|
||||
"message": "Dostupno je ažuriranje"
|
||||
},
|
||||
"app.update.complete-toast.text": {
|
||||
"message": "Klikni ovde da bi vidio spisak promena."
|
||||
},
|
||||
"app.update.complete-toast.title": {
|
||||
"message": "Verzija {version} je uspešno instalirana!"
|
||||
},
|
||||
"app.world.server-modal.placeholder-address": {
|
||||
"message": "primer.modrinth.gg"
|
||||
},
|
||||
"app.world.server-modal.select-an-option": {
|
||||
"message": "Izaberi opciju"
|
||||
},
|
||||
"app.world.world-item.incompatible-version": {
|
||||
"message": "Nekompatibilna verzija {version}"
|
||||
},
|
||||
"app.world.world-item.not-played-yet": {
|
||||
"message": "Još nije igrano"
|
||||
},
|
||||
"app.world.world-item.offline": {
|
||||
"message": "Oflajn"
|
||||
},
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} onlajn"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Dodaj prijatelja/prijateljicu"
|
||||
},
|
||||
"friends.action.view-friend-requests": {
|
||||
"message": "{count} {count, plural, one {zahtev} other {zahteva}} za prijateljstva"
|
||||
},
|
||||
"friends.add-friend.submit": {
|
||||
"message": "Pošaljite zahtev za prijateljstvo"
|
||||
},
|
||||
"friends.add-friend.title": {
|
||||
"message": "Dodavanje prijatelja"
|
||||
},
|
||||
"friends.add-friend.username.description": {
|
||||
"message": "Možda se razlikuje od njihovog korisničkog imena za Minecraft!"
|
||||
},
|
||||
"friends.add-friend.username.placeholder": {
|
||||
"message": "Unesite korisničko ime za Modrinthu..."
|
||||
},
|
||||
"friends.add-friend.username.title": {
|
||||
"message": "Koje je korisničko ime tvog prijatelja u Modrinthu?"
|
||||
},
|
||||
"friends.add-friends-to-share": {
|
||||
"message": "<link>Dodaj prijatelje</link> da vidiš šta igraju!"
|
||||
},
|
||||
"friends.friend.cancel-request": {
|
||||
"message": "Otkaži zahtev"
|
||||
},
|
||||
@@ -140,6 +677,45 @@
|
||||
"friends.heading": {
|
||||
"message": "Prijatelji"
|
||||
},
|
||||
"friends.heading.active": {
|
||||
"message": "Aktivan"
|
||||
},
|
||||
"friends.heading.offline": {
|
||||
"message": "Oflajn"
|
||||
},
|
||||
"friends.heading.online": {
|
||||
"message": "Onlajn"
|
||||
},
|
||||
"friends.heading.pending": {
|
||||
"message": "Na čekanju"
|
||||
},
|
||||
"friends.no-friends-match": {
|
||||
"message": "Nema prijatelja koji odgovaraju potragi ''{query}''"
|
||||
},
|
||||
"friends.search-friends-placeholder": {
|
||||
"message": "Traži prijatelje..."
|
||||
},
|
||||
"friends.section.heading": {
|
||||
"message": "{title} - {count}"
|
||||
},
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Prijavi se na Modrinth račun</link> da bi dodao prijatelje i vidio šta igraju!"
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Dodaj i igraj"
|
||||
},
|
||||
"instance.add-server.add-server": {
|
||||
"message": "Dodaj server"
|
||||
},
|
||||
"instance.add-server.resource-pack.disabled": {
|
||||
"message": "Onemogućeno"
|
||||
},
|
||||
"instance.add-server.resource-pack.enabled": {
|
||||
"message": "Omogućeno"
|
||||
},
|
||||
"instance.add-server.resource-pack.prompt": {
|
||||
"message": "Upit"
|
||||
},
|
||||
"instance.add-server.title": {
|
||||
"message": "Dodaj server"
|
||||
},
|
||||
@@ -155,22 +731,307 @@
|
||||
"instance.edit-world.placeholder-name": {
|
||||
"message": "Minecraft svet"
|
||||
},
|
||||
"instance.edit-world.reset-icon": {
|
||||
"message": "Resetiraj ikonu"
|
||||
},
|
||||
"instance.edit-world.title": {
|
||||
"message": "Promeni svet"
|
||||
},
|
||||
"instance.files.adding-files": {
|
||||
"message": "Dodavanje datoteka ({completed}/{total})"
|
||||
},
|
||||
"instance.files.save-as": {
|
||||
"message": "Sačuvaj kao..."
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adresa"
|
||||
},
|
||||
"instance.server-modal.name": {
|
||||
"message": "Ime"
|
||||
},
|
||||
"instance.server-modal.placeholder-name": {
|
||||
"message": "Minecraft Server"
|
||||
},
|
||||
"instance.server-modal.resource-pack": {
|
||||
"message": "Resurs paket"
|
||||
},
|
||||
"instance.settings.tabs.general": {
|
||||
"message": "Generalno"
|
||||
},
|
||||
"instance.settings.tabs.general.delete": {
|
||||
"message": "Izbriši instancu"
|
||||
},
|
||||
"instance.settings.tabs.general.delete.button": {
|
||||
"message": "Izbriši instancu"
|
||||
},
|
||||
"instance.settings.tabs.general.delete.description": {
|
||||
"message": "Trajno briše instancu sa vašeg uređaja, uključujući vaše svetove, konfiguracije i sav instalirani sadržaj. Budi oprezan, jer kada jednom obrišeš instancu, ne postoji način da je oporaviš."
|
||||
},
|
||||
"instance.settings.tabs.general.deleting.button": {
|
||||
"message": "Brisanje..."
|
||||
},
|
||||
"instance.settings.tabs.general.duplicate-button": {
|
||||
"message": "Dupliciraj"
|
||||
},
|
||||
"instance.settings.tabs.general.duplicate-button.tooltip.installing": {
|
||||
"message": "Nije moguće napraviti kopiju tokom instalacije."
|
||||
},
|
||||
"instance.settings.tabs.general.duplicate-instance": {
|
||||
"message": "Dupliciraj instancu"
|
||||
},
|
||||
"instance.settings.tabs.general.duplicate-instance.description": {
|
||||
"message": "Pravi kopiju ove instance, uključujući svetove, konfiguracije, modove itd."
|
||||
},
|
||||
"instance.settings.tabs.general.edit-icon": {
|
||||
"message": "Promeni ikonu"
|
||||
},
|
||||
"instance.settings.tabs.general.edit-icon.remove": {
|
||||
"message": "Smakni ikonu"
|
||||
},
|
||||
"instance.settings.tabs.general.edit-icon.replace": {
|
||||
"message": "Izmeni ikonu"
|
||||
},
|
||||
"instance.settings.tabs.general.edit-icon.select": {
|
||||
"message": "Izaberi ikonu"
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups": {
|
||||
"message": "Grupe biblioteke"
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups.create": {
|
||||
"message": "Kreiraj novu grupu"
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups.description": {
|
||||
"message": "Grupe biblioteka ti omogućavaju da organizuješ svoje instance u različite odeljke u svojoj biblioteci."
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups.enter-name": {
|
||||
"message": "Ukucaj ime grupe"
|
||||
},
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "Ime"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel": {
|
||||
"message": "Kanal ažuiranja"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha": {
|
||||
"message": "Alfa"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha.description": {
|
||||
"message": "Izdanja, beta i alfa verzije biće prikazane kao dostupna ažuriranja."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "Beta"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta.description": {
|
||||
"message": "Izdanja i beta verzije biće prikazane kao dostupna ažuriranja."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release": {
|
||||
"message": "Izdanje"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release.description": {
|
||||
"message": "Samo izdanja će biti prikazana kao dostupna ažuriranja."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.select": {
|
||||
"message": "Izaberi kanal ažuiranja"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "Hookovi pokreta"
|
||||
},
|
||||
"instance.settings.tabs.hooks.custom-hooks": {
|
||||
"message": "Prilagođeni hookovi za lansiranje"
|
||||
},
|
||||
"instance.settings.tabs.hooks.description": {
|
||||
"message": "Hookovi omogućavaju naprednim korisnicima da pokreću određene sistemske komande pre i posle pokretanja igre."
|
||||
},
|
||||
"instance.settings.tabs.hooks.post-exit": {
|
||||
"message": "Poslje izlaza"
|
||||
},
|
||||
"instance.settings.tabs.hooks.post-exit.description": {
|
||||
"message": "Pokrenuto nakon zatvaranja igre."
|
||||
},
|
||||
"instance.settings.tabs.hooks.post-exit.enter": {
|
||||
"message": "Unesi komandu nakon izlaska..."
|
||||
},
|
||||
"instance.settings.tabs.hooks.pre-launch": {
|
||||
"message": "Pre lansiranje"
|
||||
},
|
||||
"instance.settings.tabs.hooks.pre-launch.description": {
|
||||
"message": "Pokrenuto pre nego što je instanca pokrenuta."
|
||||
},
|
||||
"instance.settings.tabs.hooks.pre-launch.enter": {
|
||||
"message": "Unesi komandu pre lansiranja..."
|
||||
},
|
||||
"instance.settings.tabs.hooks.title": {
|
||||
"message": "Hookovi za pokretanje igre"
|
||||
},
|
||||
"instance.settings.tabs.hooks.wrapper": {
|
||||
"message": "Omotač"
|
||||
},
|
||||
"instance.settings.tabs.hooks.wrapper.description": {
|
||||
"message": "Komanda omotača za pokretanje Minecrafta."
|
||||
},
|
||||
"instance.settings.tabs.hooks.wrapper.enter": {
|
||||
"message": "Unesite naredbu omotača..."
|
||||
},
|
||||
"instance.settings.tabs.installation": {
|
||||
"message": "Instalacija"
|
||||
},
|
||||
"instance.settings.tabs.installation.loader-version": {
|
||||
"message": "Verzija {loader}"
|
||||
},
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Java i radna memorija"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-environment-variables": {
|
||||
"message": "Prilagođene promenljive okruženja"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-java-arguments": {
|
||||
"message": "Prilagođeni Java argumenti"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-java-installation": {
|
||||
"message": "Prilagođena Java instalacija"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-memory-allocation": {
|
||||
"message": "Prilagođena alokacija radne memorije"
|
||||
},
|
||||
"instance.settings.tabs.java.enter-environment-variables": {
|
||||
"message": "Unesi promenljive sredine..."
|
||||
},
|
||||
"instance.settings.tabs.java.enter-java-arguments": {
|
||||
"message": "Prilagođeni Java argumenti..."
|
||||
},
|
||||
"instance.settings.tabs.java.environment-variables": {
|
||||
"message": "Promenljive okruženja"
|
||||
},
|
||||
"instance.settings.tabs.java.hooks": {
|
||||
"message": "Hookovi"
|
||||
},
|
||||
"instance.settings.tabs.java.java-arguments": {
|
||||
"message": "Java argumenti"
|
||||
},
|
||||
"instance.settings.tabs.java.java-installation": {
|
||||
"message": "Java instalacija"
|
||||
},
|
||||
"instance.settings.tabs.java.java-memory": {
|
||||
"message": "Dodeljena radna memorija"
|
||||
},
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/put/do/jave"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Prozor"
|
||||
},
|
||||
"instance.settings.tabs.window.custom-window-settings": {
|
||||
"message": "Prilagođene postavke prozora"
|
||||
},
|
||||
"instance.settings.tabs.window.fullscreen": {
|
||||
"message": "Potpuni ekran"
|
||||
},
|
||||
"instance.settings.tabs.window.fullscreen.description": {
|
||||
"message": "Napravite da se igra pokrene preko celog ekrana prilikom pokretanja (koristeći options.txt)."
|
||||
},
|
||||
"instance.settings.tabs.window.height": {
|
||||
"message": "Visina"
|
||||
},
|
||||
"instance.settings.tabs.window.height.description": {
|
||||
"message": "Visina prozora igre prilikom pokretanja."
|
||||
},
|
||||
"instance.settings.tabs.window.height.enter": {
|
||||
"message": "Unesi visinu..."
|
||||
},
|
||||
"instance.settings.tabs.window.width": {
|
||||
"message": "Širina"
|
||||
},
|
||||
"instance.settings.tabs.window.width.description": {
|
||||
"message": "Širina prozora igre prilikom pokretanja."
|
||||
},
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Unesi širinu..."
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Minecraft server"
|
||||
},
|
||||
"instance.worlds.cant_connect": {
|
||||
"message": "Ne može se povezati sa serverom"
|
||||
},
|
||||
"instance.worlds.copy_address": {
|
||||
"message": "Kopiraj adresu"
|
||||
},
|
||||
"instance.worlds.create_shortcut": {
|
||||
"message": "Kreiraj prečicu"
|
||||
},
|
||||
"instance.worlds.dont_show_on_home": {
|
||||
"message": "Ne prikazuj na početnoj stranici"
|
||||
},
|
||||
"instance.worlds.game_already_open": {
|
||||
"message": "Instanca je već pokrenuta"
|
||||
},
|
||||
"instance.worlds.hardcore": {
|
||||
"message": "Hardcore mod"
|
||||
},
|
||||
"instance.worlds.incompatible_server": {
|
||||
"message": "Server je nekompatibilan"
|
||||
},
|
||||
"instance.worlds.linked_server": {
|
||||
"message": "Upravljeno serverskim projektom"
|
||||
},
|
||||
"instance.worlds.no_contact": {
|
||||
"message": "Server nije mogao biti kontaktiran"
|
||||
},
|
||||
"instance.worlds.no_server_quick_play": {
|
||||
"message": "Možeš samo direktno ući u servere na Minecraft Alpha 1.0.5+"
|
||||
},
|
||||
"instance.worlds.no_singleplayer_quick_play": {
|
||||
"message": "Možeš samo direktno ući u samostalne svetove na Minecraft 1.20+"
|
||||
},
|
||||
"instance.worlds.play_instance": {
|
||||
"message": "Igraj instancu"
|
||||
},
|
||||
"instance.worlds.view_instance": {
|
||||
"message": "Vidi instancu"
|
||||
},
|
||||
"instance.worlds.world_in_use": {
|
||||
"message": "Svetovi je korišten"
|
||||
},
|
||||
"minecraft-account.add-account": {
|
||||
"message": "Dodaj račun"
|
||||
},
|
||||
"minecraft-account.label": {
|
||||
"message": "Minecraft račun"
|
||||
},
|
||||
"minecraft-account.not-signed-in": {
|
||||
"message": "Nisi prijavljen"
|
||||
},
|
||||
"minecraft-account.remove-account": {
|
||||
"message": "Uklonite račun"
|
||||
},
|
||||
"minecraft-account.select-account": {
|
||||
"message": "Izaberi račun"
|
||||
},
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Prijavi se na Minecraft"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Obezbeđeno od instance"
|
||||
},
|
||||
"search.filter.locked.instance-game-version.title": {
|
||||
"message": "Verzija igre je obezbeđena od instance"
|
||||
},
|
||||
"search.filter.locked.instance-loader.title": {
|
||||
"message": "Učitavač je obezbeđen od instance"
|
||||
},
|
||||
"search.filter.locked.instance.sync": {
|
||||
"message": "Sinhroniziraj sa instancom"
|
||||
},
|
||||
"search.filter.locked.server": {
|
||||
"message": "Obezbeđeno od servera"
|
||||
},
|
||||
"search.filter.locked.server-environment.title": {
|
||||
"message": "Samo modovi za kliente mogu biti dodani na instancu servera"
|
||||
},
|
||||
"search.filter.locked.server-game-version.title": {
|
||||
"message": "Verzije igre je obezbeđena od servera"
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Učitavač je obezbeđen od servera"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Göm fler aktiva instanser"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Kopierat"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Kopiera detaljer"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Avvisa"
|
||||
},
|
||||
@@ -20,6 +26,48 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Försök igen"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Avbröts på grund av att appen stängdes"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Kunde inte läsa modpaket"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Avbruten"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Kunde inte ladda ner filer"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Nedladdad fil är korrupt"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Kunde inte spara filer"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Nedladdning kunde inte slutföras"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Instans kunde inte hittas"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Sökväg är ogiltig"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Kunde inte uppdatera lokal data"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Kunde inte nå Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Ingen behörighet att skriva"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Kunde inte ladda ner paket"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Någonting gick fel"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Okänd instans"
|
||||
},
|
||||
@@ -30,7 +78,7 @@
|
||||
"message": "Gör till primärinstans"
|
||||
},
|
||||
"app.action-bar.no-instances-running": {
|
||||
"message": "Ingen aktiva instans"
|
||||
"message": "Inga aktiva instanser"
|
||||
},
|
||||
"app.action-bar.offline": {
|
||||
"message": "Offline"
|
||||
@@ -168,7 +216,7 @@
|
||||
"message": "Upptäck servrar"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Dölj servrar som redan är tillagda"
|
||||
"message": "Göm redan tillagda servrar"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpaket"
|
||||
@@ -219,7 +267,7 @@
|
||||
"message": "Avslutar"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Förbereder instans"
|
||||
"message": "Köad för installering"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Förbereder Java"
|
||||
@@ -243,19 +291,25 @@
|
||||
"message": "Läser pack information"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "Laddar ner loadern"
|
||||
"message": "Fastställer loader"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Laddar ner Minecraft"
|
||||
"message": "Fastställer Minecraft"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "Laddar ner innehåll"
|
||||
"message": "Fastställer innehåll"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "Återställer"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Kör loader-processorer"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "All data från din instans kommer permanent raderas, däribland dina världar, konfigurationer samt allt installerat innehåll."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-header": {
|
||||
"message": "Detta kan inte ogöras"
|
||||
"message": "Detta kan inte ångras"
|
||||
},
|
||||
"app.instance.confirm-delete.delete-button": {
|
||||
"message": "Radera instans"
|
||||
@@ -282,7 +336,7 @@
|
||||
"message": "Slutför uppdatering..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "Laddar versioner..."
|
||||
"message": "Fastställer versioner..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "projekt"
|
||||
@@ -314,6 +368,9 @@
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "Ta bort värld"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "Denna värld kommer permanent raderas från instansen. Detta kan inte ångras."
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "Raderar {name}"
|
||||
},
|
||||
@@ -341,15 +398,15 @@
|
||||
"app.instance.worlds.remove-server-modal.title": {
|
||||
"message": "Ta bort server"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-body": {
|
||||
"message": "Denna server kommer att tas bort från din serverlista och serverlistan i spelet. Du kan lägga till den igen senare om du känner till adressen."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "Raderar {name}"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Sök {count} världar..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Innehåll krävs"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installera för att spela"
|
||||
},
|
||||
@@ -359,39 +416,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# moddar}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Modpaket som krävs"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Servern kräver moddar för att du ska kunna spela. Klicka på Installera för att sätta upp dem nödvändiga filerna från Modrinth, och starta sedan på servern direkt."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Delad instans"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Delad serverinstans"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Visa innehåll"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Uppdatera för att spela"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Uppdatering krävs"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "En uppdatering krävs för att spela {name}. Vänligen uppdatera till senaste version för att starta spelet."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Detta projekt är redan installerat"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Byt version"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Tillbaka till upptäck"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "Installera innehåll till instans"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Alla versioner"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Ladda ner i webbläsare"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Installerar"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Redan installerat"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Utvecklarläge aktiverat."
|
||||
},
|
||||
@@ -504,11 +564,17 @@
|
||||
"message": "Sakta ner!"
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "Ditt utseende kunde inte sparas."
|
||||
"message": "Din ordning av utseenden kunde inte sparas."
|
||||
},
|
||||
"app.skins.reorder-error.title": {
|
||||
"message": "Misslyckades med att ordna om utseenden"
|
||||
},
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "Builders & Biomes"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Chase the Skies"
|
||||
},
|
||||
@@ -987,7 +1053,7 @@
|
||||
"message": "Spel version är tillhandahållet av instansen"
|
||||
},
|
||||
"search.filter.locked.instance-loader.title": {
|
||||
"message": "Laddaren tillhandahålls av instansen"
|
||||
"message": "Loader tillhandahålls av instansen"
|
||||
},
|
||||
"search.filter.locked.instance.sync": {
|
||||
"message": "Synkronisera med instansen"
|
||||
@@ -1003,26 +1069,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader tillhandahålls av servern"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "En fil granskas bara om den laddas upp till Modrinth, oavsett dess filformat (däribland .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Visa inte denna varning igen"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Bekräfta installation"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Installera ändå"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Skadeprogram distribueras ofta via modpaketfiler genom att dela dem på plattformar som Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Vi kunde inte hitta filen på Modrinth. Vi rekommenderar starkt att endast installera filer från källor du litar på."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Okänd filvarning"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +146,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "สำรวจเซิร์ฟเวอร์"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "ซ่อนเซิร์ฟเวอร์ที่ดำเนินการเพิ่มแล้ว"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "แพ็กม็อด"
|
||||
},
|
||||
@@ -170,9 +167,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "ส่งออกแพ็กม็อด"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "ชื่อแพ็กม็อด"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "ชื่อแพ็กม็อด"
|
||||
},
|
||||
@@ -251,9 +245,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "ค้าหาโลกทั้งหมด {count} โลก"
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "เนื้อหาที่จำเป็น"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "ติดตั้งเพื่อเล่น"
|
||||
},
|
||||
@@ -263,27 +254,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {# ม็อด}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "มอดแพ็กที่จำเป็น"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "เซิร์ฟเวอร์ดังกล่าวจำเป็นต้องใช้ม็อดเพื่อเล่น โปรดติดตั้งและตั้งค่าไฟล์อื่นใดที่จำเป็นจาก Modrinth ก่อน จากนั้นถึงจะสามารถเข้าเล่นเซิร์ฟเวอร์ได้"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "โปรแกรมที่มีร่วมกัน"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "เซิร์ฟเวอร์ของโปรแกรมที่มีร่วมกัน"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "ดูเนื้อหา"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "อัปเดตเพื่อเล่น"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "จำเป็นต้องอัปเดต"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "จำเป็นต้องอัปเดตเพื่อเล่น {name} กรุณาอัปเดตเป็นเวอร์ชันล่าสุดเพื่อเปิดเกม"
|
||||
},
|
||||
@@ -856,26 +835,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "ตัวรันถูกกำหนดโดยเซิร์ฟเวอร์แล้ว"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "ไฟล์จะได้รับการตรวจสอบโดยไม่คำนึงถึงประเภทของไฟล์ (รวมทั้ง .mrpack) เมื่อไฟล์ถูกอัปโหลดขึ้น Modrinth"
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "อย่าแสดงคำเตือนนี้อีก"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "ยืนยันการติดตั้ง"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "ดำเนินการติดตั้งต่อไป"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "มัลแวร์มักแฝงตัวมากับไฟล์แพ็กม็อดผ่านการแชร์ผ่านแพลตฟอร์มที่ไม่ใช่แพลตฟอร์มเฉพาะ เช่น ดิสคอร์ด"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "เราไม่สามารถค้นหาไฟล์ดังกล่าวได้บน Modrinth พวกเราขอแนะนำอย่างมากกว่าควรติดตั้งไฟล์จากแหล่งที่น่าเชื่อถือเท่านั้น"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "แจ้งเตือนไฟล์ไม่รู้จัก"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Diğer çalışan kurulumları gizle"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Kopyalandı"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Detayları kopyala"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Reddet"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Yeniden Dene"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Uygulama kapatıldığı için iptal edildi"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Mod paketi okunamadı"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "İptal edildi"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "Temizleme bitmedi"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Dosyalar indirilemedi"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "İndirilmiş dosya bozuk"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Dosyalar kaydedilemedi"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "İndirme tamamlanamadı"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Kurulum bulunamadı"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Dosya yolu geçersiz"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Mod paketi verileri geçersiz"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Mod paketi dosyaları geçersiz meta verilere sahip"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Java kurulumu bitirilemedi"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Yükleyici kurulumu başarısız oldu"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Yerel veriler güncellenemedi"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Minecraft kurulumu başarısız oldu"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Modrinth'e erişilemiyor"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Yazmak için yetkiniz yok"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Paket indirilemedi"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Bir sorun oluştu"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Bilinmeyen kurulum"
|
||||
},
|
||||
@@ -192,7 +258,7 @@
|
||||
"message": "Mod paketini dışa aktar"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Mod Paketi Adı"
|
||||
"message": "Mod paketi adı"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Mod paketi adı"
|
||||
@@ -219,7 +285,7 @@
|
||||
"message": "Tamamlanıyor"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Kurulum hazırlanıyor"
|
||||
"message": "İndirmek için sıraya alındı"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Java Hazırlanıyor"
|
||||
@@ -359,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "{count} dünya ara..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "İçerik gerekli"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Oynamak için yükleyin"
|
||||
},
|
||||
@@ -371,39 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {#mod} other {#mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Gerekli mod paketi"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Bu sunucuya girebilmek için modlar gereklidir. Gerekli dosyaları Modrinth üzerinden kurmak için Yükle butonuna tıkla, ardından doğrudan sunucuya başlat."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Paylaşılan Kurulum"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Paylaşılan Sunucu Kurulumu"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "İçeriği görüntüle"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Oynamak için güncelle"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Güncelleme gerekli"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name} oyununu oynamak için güncelleme gereklidir. Oyunu başlatmak için lütfen en son sürüme güncelleyin."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Bu proje zaten kurulu"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Sürüm değiştir"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Keşfete geri dön"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "İçeriği kuruluma yükle"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Tüm sürümler"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Tarayıcıdan indir"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Yükleniyor"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Zaten yüklenmiş"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Geliştirici modu açıldı."
|
||||
},
|
||||
@@ -524,6 +590,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "İnşaatçılar & Biyomlar"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Kaos Küpü"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "Gökyüzünü kovala"
|
||||
},
|
||||
@@ -1018,26 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Yükleyici sunucu tarafından sağlanıyor"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Dosya formatı ne olursa olsun (.mrpack dahil), bir dosya yalnızca Modrinth'e yüklendiğinde denetlenir."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Bu uyarıyı tekrar gösterme"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "İndirmeyi onayla"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Yine de indir"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Kötü amaçlı yazılımlar genellikle Discord gibi platformlarda paylaşılan mod paketi dosyaları aracılığıyla yayılır."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Bu dosyayı Modrinth üzerinde bulamadık. Yalnızca güvendiğiniz kaynaklardan gelen dosyaları yüklemenizi şiddetle öneririz."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Bilinmeyen dosya uyarısı"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,81 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Приховати більше запущених профілів"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Скопійовано"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Скопіювати деталі"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Відхилити"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Відкрити екземпляр"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Спробувати знову"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Скасовано через закриття додатку"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Не вдалось прочитати збірку модів"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Скасовано"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Не вдалося завантажити файли"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Завантажений файл пошкоджений"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Не вдалося зберегти файли"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Завантаження не вдалося завершити"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Екземпляр не знайдено"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Шлях до файлу недійсний"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Дані збірки модів недійсні"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Файли збірки модів містять не дійсні метадані"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Не вдалося завершити встановлення Java"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Помилка встановлення завантажувача"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Не вдалося оновити локальні дані"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Не вдалося встановити Minecraft"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Не вдалося зʼєднатися з Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Немає прав для запису"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Не вдалося встановити збірку"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Щось пішло не так"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Невідомий екземпляр"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Зробити основним профілем"
|
||||
},
|
||||
@@ -101,6 +176,12 @@
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Час гри"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Автоматично пропускає підтвердження з низьким рівнем ризику, як-от повторне встановлення збірки модів, видалення звичайного вмісту, масові оновлення, відвʼязування збірки модів та записи на відновлення. Небезпечні попередження все одно зображуватимуться."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Пропустити несуттєві попередження"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Умикає можливість перемикання бокової панелі."
|
||||
},
|
||||
@@ -147,7 +228,7 @@
|
||||
"message": "Дослідити сервера"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Сховати наявні сервери"
|
||||
"message": "Приховати вже додані сервери"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Збірки"
|
||||
@@ -171,7 +252,7 @@
|
||||
"message": "Експортувати збірку"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Назва збірки"
|
||||
"message": "Назва збірки модів"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Назва збірки"
|
||||
@@ -182,6 +263,60 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Завантаження вмісту"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Завантаження Minecraft"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Завантаження файлу пакета"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Розпакування файлів заміщення"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Завершення"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "У черзі на встановлення"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Підготовка Java"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Завантаження Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Розпакування Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Отримання Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Підготовка Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "Перевірка Java {version}"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Читання маніфесту пакета"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "Визначення завантажувача"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Узгодження версії Minecraft"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "Узгодження вмісту"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "Повернення"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Запуск процесорів завантажувача"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Усі дані вашого профілю будуть видалені назавжди, включно з вашими світами, налаштуваннями та всім установленим умістом."
|
||||
},
|
||||
@@ -206,6 +341,9 @@
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "Профіль"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "Завантаження проєктів: {current, number}/{total, number}..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "проєкт"
|
||||
},
|
||||
@@ -251,9 +389,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Пошук {count} світів…"
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Потрібний уміст"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Установлення для гри"
|
||||
},
|
||||
@@ -263,27 +398,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# мод} few {# мода} other {# модів}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Потрібна збірка"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Для гри на цьому сервері потрібні моди. Натисніть «Установити», щоб налаштувати необхідні файли з Modrinth, а потім запустіть безпосередньо на сервері."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Профіль"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Серверний профіль"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Дивитися вміст"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Оновлення для гри"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Необхідне оновлення"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "«{name}» потребує оновлення, щоб грати. Будь ласка, оновіть до останньої версії, щоб запустити гру."
|
||||
},
|
||||
@@ -618,7 +741,7 @@
|
||||
"message": "Додавання файлів ({completed}/{total})"
|
||||
},
|
||||
"instance.files.save-as": {
|
||||
"message": "Зберегти як…"
|
||||
"message": "Зберегти як..."
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Адреса"
|
||||
@@ -907,26 +1030,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Завантажувач наданий сервером"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Файл перевірятиметься лише, якщо його завантажено на Modrinth, незалежно від його формату (включно з .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Не показувати більше це попередження"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Підтвердити встановлення"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Усе одно встановити"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Шкідливе програмне забезпечення часто поширюють через файли збірок, які публікуються на таких платформах, як Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Ми не змогли знайти цей файл на Modrinth. Ми рекомендуємо встановлювати файли лише з тих джерел яким ви довіряєте."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Попередження про невідомий файл"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +146,6 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Khám phá máy chủ"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Ẩn các server đã thêm"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpack"
|
||||
},
|
||||
@@ -170,9 +167,6 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Xuất modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Tên modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Tên modpack"
|
||||
},
|
||||
@@ -251,9 +245,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Tìm kiếm {count} world..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "Nội dung bắt buộc"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Tải xuống để chơi"
|
||||
},
|
||||
@@ -263,27 +254,15 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {# mod}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "Yêu cầu modpack"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "Máy chủ này yêu cầu mod để có thể chơi. Vui lòng ấn vào tải xuống và tải các tệp bắt buộc từ Modrinth và khởi chạy trực tiếp để tham gia máy chủ."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Chia sẻ hồ sơ"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "Chia sẻ hồ sơ máy chủ"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Xem nội dung"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Cập nhật và bắt đầu chơi"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Yêu cầu cập nhật"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Bạn cần cập nhật {name} để có thể chơi. Vui lòng cập nhật lên bản mới nhất để khởi chạy trò chơi."
|
||||
},
|
||||
@@ -907,26 +886,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "Loader được cung cấp bởi máy chủ"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "Tệp chỉ được xem xét nếu nó được tải lên Modrinth, bất kể định dạng tệp của nó là gì (bao gồm cả .mrpack)."
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "Đừng hiển thị cảnh báo này nữa"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "Xác nhận cài đặt"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "Tiếp tục cài đặt"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "Phần mềm độc hại thường được phát tán thông qua các tệp modpack bằng cách chia sẻ chúng trên các nền tảng như Discord."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "Chúng tôi không tìm thấy tập tin này trên Modrinth. Chúng tôi đặc biệt khuyên bạn chỉ nên cài đặt các tập tin từ các nguồn đáng tin cậy."
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "Cảnh báo tệp không xác định"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "隐藏更多运行中的实例"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "已复制"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "复制详情"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "忽略"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "重试"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "由于应用关闭而取消"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "无法读取整合包"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "已取消"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "清理未完成"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "无法下载文件"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "下载的文件已损坏"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "无法保存文件"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "下载无法完成"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "无法找到实例"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "文件路径无效"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "整合包数据无效"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "整合包文件含有无效元数据"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "无法完成 Java 配置"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "加载器配置失败"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "无法更新本地数据"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Minecraft 配置失败"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "无法连接 Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "没有写入权限"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "无法下载包"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "出错了"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "未知的实例"
|
||||
},
|
||||
@@ -219,7 +285,7 @@
|
||||
"message": "完成"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "准备实例"
|
||||
"message": "已加入安装队列"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "正在准备 Java"
|
||||
@@ -327,7 +393,7 @@
|
||||
"message": "正在删除 {name}"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "模组适配"
|
||||
"message": "含模组"
|
||||
},
|
||||
"app.instance.worlds.filter-offline": {
|
||||
"message": "离线"
|
||||
@@ -359,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "搜索 {count} 个世界……"
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "需求内容"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "安装以游玩"
|
||||
},
|
||||
@@ -371,39 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count} 个模组"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "需求整合包"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "此服务器需要安装模组才能游玩。点击安装,从 Modrinth 下载所需文件,然后直接进入服务器。"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "共享实例"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "共享的服务端实例"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "查看内容"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "更新以游玩"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "需要更新"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "需要更新至最新版本才能运行 {name}。请更新后启动游戏。"
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "此项目已安装"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "切换版本"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "返回发现页"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "将内容安装到实例中"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "所有版本"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "在浏览器中下载"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "安装中"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "已安装"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "开发者模式已启用。"
|
||||
},
|
||||
@@ -524,6 +590,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "建造者与生物群系"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "混沌立方"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "追逐天空"
|
||||
},
|
||||
@@ -942,7 +1011,7 @@
|
||||
"message": "复制地址"
|
||||
},
|
||||
"instance.worlds.create_shortcut": {
|
||||
"message": "创建快照"
|
||||
"message": "创建快捷方式"
|
||||
},
|
||||
"instance.worlds.dont_show_on_home": {
|
||||
"message": "在主界面隐藏"
|
||||
@@ -1018,26 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "加载器由服务器提供"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "只有上传到 Modrinth 的文件才会经过审核,无论其文件格式如何(包括 .mrpack)。"
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "不再显示此警告"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "确认安装"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "仍然安装"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "恶意软件常常通过整合包文件在 Discord 等平台上分享而传播。"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "我们在 Modrinth 上找不到此文件。强烈建议你仅从可信来源安装文件。"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "未知文件警告"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "隱藏更多執行中的實例"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "已複製"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "複製詳細資訊"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "忽略"
|
||||
},
|
||||
@@ -20,6 +26,66 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "重試"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "由於應用程式關閉而取消"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "無法讀取模組包"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "已取消"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "未完成清理"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "無法下載檔案"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "下載的檔案已損毀"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "無法儲存檔案"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "無法完成下載"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "找不到實例"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "檔案路徑無效"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "模組包資料無效"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "模組包檔案的詮釋資料無效"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "無法完成 Java 設定"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "無法設定載入器"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "無法更新本地資料"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "無法設定 Minecraft"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "無法連線到 Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "沒有寫入權限"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "無法下載模組包"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "出了點狀況"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "未知的實例"
|
||||
},
|
||||
@@ -219,7 +285,7 @@
|
||||
"message": "即將完成"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "正在準備實例"
|
||||
"message": "已排入安裝佇列"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "正在準備 Java"
|
||||
@@ -321,10 +387,10 @@
|
||||
"message": "刪除世界"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "此世界將會被永久刪除,此操作無法復原。"
|
||||
"message": "這個世界將會被永久刪除,此操作無法復原。"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "正在刪除 {name}"
|
||||
"message": "即將刪除 {name}"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "模組"
|
||||
@@ -354,14 +420,11 @@
|
||||
"message": "這個伺服器將從你的伺服器清單中移除。如果你記得伺服器位址,稍後可以將其重新新增回來。"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "正在移除 {name}"
|
||||
"message": "即將移除 {name}"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "搜尋 {count} 個世界..."
|
||||
},
|
||||
"app.modal.install-to-play.content-required": {
|
||||
"message": "所需內容"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "安裝以遊玩"
|
||||
},
|
||||
@@ -371,39 +434,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {# 個模組}}"
|
||||
},
|
||||
"app.modal.install-to-play.required-modpack": {
|
||||
"message": "所需模組包"
|
||||
},
|
||||
"app.modal.install-to-play.server-requires-mods": {
|
||||
"message": "這個伺服器需要模組才能遊玩。請點選「安裝」以從 Modrinth 設定所需的檔案,完成後即可直接加入伺服器。"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "共用實例"
|
||||
},
|
||||
"app.modal.install-to-play.shared-server-instance": {
|
||||
"message": "共用伺服器實例"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "檢視內容"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "更新以遊玩"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "需要更新"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "需要更新才能遊玩「{name}」。請更新至最新版本以啟動遊戲。"
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "這個專案已安裝"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "切換版本"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "返回瀏覽"
|
||||
},
|
||||
"app.project.install-context.install-content-to-instance": {
|
||||
"message": "將內容安裝至實例"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "所有版本"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "在瀏覽器中下載"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "正在安裝"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "已安裝"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "開發人員模式已啟用。"
|
||||
},
|
||||
@@ -524,6 +590,9 @@
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "建造者&生態域"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "混沌立方"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "追逐天空"
|
||||
},
|
||||
@@ -1018,26 +1087,5 @@
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "載入器由伺服器提供"
|
||||
},
|
||||
"unknown-pack-warning-modal.body": {
|
||||
"message": "只有上傳至 Modrinth 的檔案才會經過審查,無論其檔案格式為何(包含 .mrpack)。"
|
||||
},
|
||||
"unknown-pack-warning-modal.dont-show-again": {
|
||||
"message": "不要再顯示這則警告"
|
||||
},
|
||||
"unknown-pack-warning-modal.header": {
|
||||
"message": "確認安裝"
|
||||
},
|
||||
"unknown-pack-warning-modal.install-anyway": {
|
||||
"message": "仍要安裝"
|
||||
},
|
||||
"unknown-pack-warning-modal.malware-statement": {
|
||||
"message": "惡意軟體經常透過 Discord 等平臺分享模組包檔案來進行傳播。"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.body": {
|
||||
"message": "我們在 Modrinth 上找不到這個檔案。強烈建議你僅安裝來自信任來源的檔案。"
|
||||
},
|
||||
"unknown-pack-warning-modal.warning.title": {
|
||||
"message": "未知檔案警告"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,7 +884,7 @@ async function search(requestParams: string) {
|
||||
const rawResults = await queryClient.fetchQuery({
|
||||
queryKey: ['search', 'v3', requestParams],
|
||||
queryFn: () =>
|
||||
get_search_results_v3(requestParams) as Promise<{
|
||||
get_search_results_v3(requestParams, 'must_revalidate') as Promise<{
|
||||
result: Labrinth.Search.v3.SearchResults & {
|
||||
hits: (Labrinth.Search.v3.ResultSearchProject & { installed?: boolean })[]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
:reload-page="() => router.go(0)"
|
||||
:resolve-viewer="resolveViewer"
|
||||
:show-copy-id-action="themeStore.devMode"
|
||||
:show-play-tab="themeStore.getFeatureFlag('ServerPlayFrontend')"
|
||||
:auth-user="authUser"
|
||||
:navigate-to-billing="() => openUrl('https://modrinth.com/settings/billing')"
|
||||
:navigate-to-servers="() => router.push('/hosting/manage')"
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ServersManagePlayPage } from '@modrinth/ui'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import { useTheming } from '@/store/theme'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const themeStore = useTheming()
|
||||
|
||||
if (!themeStore.getFeatureFlag('ServerPlayFrontend')) {
|
||||
await router.replace(`/hosting/manage/${String(route.params.id)}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ServersManagePlayPage />
|
||||
</template>
|
||||
@@ -4,6 +4,5 @@ import Content from './Content.vue'
|
||||
import Files from './Files.vue'
|
||||
import Index from './Index.vue'
|
||||
import Overview from './Overview.vue'
|
||||
import Play from './Play.vue'
|
||||
|
||||
export { Access, Backups, Content, Files, Index, Overview, Play }
|
||||
export { Access, Backups, Content, Files, Index, Overview }
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
@unlinked="fetchInstance"
|
||||
/>
|
||||
<UpdateToPlayModal ref="updateToPlayModal" :instance="instance" />
|
||||
<SharedInstanceUpdateModal
|
||||
ref="sharedInstanceUpdateModal"
|
||||
@shared-instance-unavailable="handleSharedInstanceUnavailable"
|
||||
/>
|
||||
<ContentPageHeader>
|
||||
<template #icon>
|
||||
<Avatar
|
||||
@@ -29,18 +25,6 @@
|
||||
<template #title>
|
||||
{{ instance.name }}
|
||||
</template>
|
||||
<template v-if="instance.shared_instance" #title-suffix>
|
||||
<div
|
||||
class="inline-flex h-7 items-center gap-1 rounded-full border border-solid border-blue bg-highlight-blue px-2.5 !text-base !font-normal leading-none text-blue"
|
||||
>
|
||||
Shared
|
||||
<UnknownIcon
|
||||
v-tooltip="sharedInstanceTooltip"
|
||||
class="size-4 cursor-help"
|
||||
aria-label="Shared instance information"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #stats>
|
||||
<div class="flex items-center flex-wrap gap-2">
|
||||
<template v-if="!isServerInstance">
|
||||
@@ -105,23 +89,6 @@
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="sharedInstanceManager">
|
||||
<div class="w-1.5 h-1.5 rounded-full bg-surface-5"></div>
|
||||
|
||||
<div class="flex min-w-0 items-center gap-[5px] font-medium">
|
||||
{{ sharedInstanceManager.type === 'server' ? 'Linked to' : 'Managed by' }}
|
||||
<Avatar
|
||||
:src="sharedInstanceManager.avatarUrl"
|
||||
:alt="sharedInstanceManager.name"
|
||||
:tint-by="sharedInstanceManager.tintBy"
|
||||
size="24px"
|
||||
:circle="sharedInstanceManager.type === 'user'"
|
||||
no-shadow
|
||||
/>
|
||||
<span class="min-w-0 truncate">{{ sharedInstanceManager.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
@@ -250,17 +217,6 @@
|
||||
</div>
|
||||
<div :class="['px-6', { 'shrink-0': isFixedRender }]">
|
||||
<NavTabs :links="tabs" />
|
||||
<InstanceAdmonitions
|
||||
class="mt-4"
|
||||
:instance="instance"
|
||||
:shared-instance-unavailable-reason="sharedInstanceUnavailableReason"
|
||||
:shared-instance-unavailable-manager="sharedInstanceUnavailableManager"
|
||||
:shared-instance-wrong-account="sharedInstanceWrongAccount"
|
||||
:shared-instance-expected-user-id="sharedInstanceExpectedUserId"
|
||||
:shared-instance-role="instance.shared_instance?.role"
|
||||
:shared-instance-signed-out="sharedInstanceSignedOut"
|
||||
@published="fetchInstance"
|
||||
/>
|
||||
</div>
|
||||
<div :class="['p-6 pt-4', { 'min-h-0 flex-1 overflow-y-auto': isFixedRender }]">
|
||||
<RouterView v-slot="{ Component }" :key="instance.id" :route="displayedInstanceRoute">
|
||||
@@ -332,7 +288,6 @@ import {
|
||||
SettingsIcon,
|
||||
StopCircleIcon,
|
||||
TerminalSquareIcon,
|
||||
UnknownIcon,
|
||||
UpdatedIcon,
|
||||
UserPlusIcon,
|
||||
XIcon,
|
||||
@@ -341,7 +296,6 @@ import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
ContentPageHeader,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
NavTabs,
|
||||
OverflowMenu,
|
||||
@@ -350,7 +304,6 @@ import {
|
||||
ServerRecentPlays,
|
||||
ServerRegion,
|
||||
useLoadingBarToken,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { useQueryClient } from '@tanstack/vue-query'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
@@ -362,10 +315,8 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import ExportModal from '@/components/ui/ExportModal.vue'
|
||||
import InstanceAdmonitions from '@/components/ui/instance/instance-admonitions/index.vue'
|
||||
import InstanceSettingsModal from '@/components/ui/modal/InstanceSettingsModal.vue'
|
||||
import UpdateToPlayModal from '@/components/ui/modal/UpdateToPlayModal.vue'
|
||||
import SharedInstanceUpdateModal from '@/components/ui/shared-instances/SharedInstanceUpdateModal.vue'
|
||||
import {
|
||||
fetchCachedServerStatus,
|
||||
getFreshCachedServerStatus,
|
||||
@@ -374,15 +325,10 @@ import { useInstanceConsole } from '@/composables/useInstanceConsole'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project_v3 } from '@/helpers/cache.js'
|
||||
import { instance_listener, process_listener } from '@/helpers/events'
|
||||
import {
|
||||
install_existing_instance,
|
||||
install_pack_to_existing_instance,
|
||||
type SharedInstanceUnavailableReason,
|
||||
} from '@/helpers/install'
|
||||
import { install_existing_instance, install_pack_to_existing_instance } from '@/helpers/install'
|
||||
import { get, get_full_path, kill, run } from '@/helpers/instance'
|
||||
import { type InstanceContentData, loadInstanceContentData } from '@/helpers/instance-content'
|
||||
import { get_by_instance_id } from '@/helpers/process'
|
||||
import { useSharedInstanceErrors } from '@/helpers/shared-instance-errors'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { createInstanceShortcut, showInstanceInFolder } from '@/helpers/utils.js'
|
||||
import { refreshWorlds, type ServerStatus } from '@/helpers/worlds'
|
||||
@@ -390,8 +336,6 @@ import { injectServerInstall } from '@/providers/server-install'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { useBreadcrumbs, useTheming } from '@/store/state'
|
||||
|
||||
import { provideSharedInstanceState, useSharedInstanceState } from './use-shared-instance-state'
|
||||
|
||||
dayjs.extend(duration)
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
@@ -423,21 +367,6 @@ const subpagePending = ref(false)
|
||||
const stopping = ref(false)
|
||||
const exportModal = ref<InstanceType<typeof ExportModal>>()
|
||||
const updateToPlayModal = ref<InstanceType<typeof UpdateToPlayModal>>()
|
||||
const sharedInstanceUpdateModal = ref<InstanceType<typeof SharedInstanceUpdateModal>>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const { notifySharedInstanceError, notifySharedInstanceUnavailable } = useSharedInstanceErrors()
|
||||
|
||||
const messages = defineMessages({
|
||||
sharedInstanceTooltip: {
|
||||
id: 'instance.shared-instance.tooltip',
|
||||
defaultMessage: "This instance's content is being managed by someone else.",
|
||||
},
|
||||
sharedInstanceOwnerTooltip: {
|
||||
id: 'instance.shared-instance.owner-tooltip',
|
||||
defaultMessage: "This instance's content is being shared to other users.",
|
||||
},
|
||||
})
|
||||
|
||||
useLoadingBarToken(subpagePending)
|
||||
|
||||
@@ -456,26 +385,6 @@ const playersOnline = ref<number | undefined>(undefined)
|
||||
const ping = ref<number | undefined>(undefined)
|
||||
const loadingServerPing = ref(false)
|
||||
const activeInstanceId = ref<string>()
|
||||
const sharedInstanceState = useSharedInstanceState(instance, offline, notifySharedInstanceError)
|
||||
provideSharedInstanceState(sharedInstanceState)
|
||||
const {
|
||||
actionsLocked: sharedInstanceActionsLocked,
|
||||
expectedUserId: sharedInstanceExpectedUserId,
|
||||
manager: sharedInstanceManager,
|
||||
setUnavailable: setSharedInstanceUnavailable,
|
||||
signedOut: sharedInstanceSignedOut,
|
||||
unavailableManager: sharedInstanceUnavailableManager,
|
||||
unavailableReason: sharedInstanceUnavailableReason,
|
||||
updatePreview: sharedInstanceUpdatePreview,
|
||||
wrongAccount: sharedInstanceWrongAccount,
|
||||
} = sharedInstanceState
|
||||
const sharedInstanceTooltip = computed(() =>
|
||||
formatMessage(
|
||||
instance.value?.shared_instance?.role === 'owner'
|
||||
? messages.sharedInstanceOwnerTooltip
|
||||
: messages.sharedInstanceTooltip,
|
||||
),
|
||||
)
|
||||
|
||||
watch(
|
||||
() => router.currentRoute.value,
|
||||
@@ -509,7 +418,6 @@ async function fetchInstance() {
|
||||
isServerInstance.value = false
|
||||
linkedProjectV3.value = undefined
|
||||
preloadedContent.value = null
|
||||
sharedInstanceState.reset()
|
||||
resetServerStatus()
|
||||
|
||||
const nextInstance = await get(route.params.id as string).catch(handleError)
|
||||
@@ -534,8 +442,8 @@ async function fetchInstance() {
|
||||
}
|
||||
|
||||
const nextPreloadedContent = await contentPreloadPromise
|
||||
|
||||
instance.value = nextInstance ?? undefined
|
||||
sharedInstanceState.refreshAvailability()
|
||||
linkedProjectV3.value = nextLinkedProjectV3
|
||||
isServerInstance.value = nextIsServerInstance
|
||||
preloadedContent.value = nextPreloadedContent
|
||||
@@ -623,50 +531,29 @@ const isFixedRender = computed(() => renderMode.value === 'fixed')
|
||||
const contentSubpageProps = computed(() =>
|
||||
isContentSubpageRoute() ? { preloadedContent: preloadedContent.value } : {},
|
||||
)
|
||||
const showShareTab = computed(() => {
|
||||
const linkType = instance.value?.link?.type
|
||||
|
||||
return (
|
||||
instance.value?.shared_instance?.role !== 'member' &&
|
||||
linkType !== 'server_project' &&
|
||||
linkType !== 'server_project_modpack'
|
||||
)
|
||||
})
|
||||
|
||||
const tabs = computed(() => {
|
||||
const instanceTabs = [
|
||||
{
|
||||
label: 'Content',
|
||||
href: `${basePath.value}`,
|
||||
icon: BoxesIcon,
|
||||
},
|
||||
{
|
||||
label: 'Files',
|
||||
href: `${basePath.value}/files`,
|
||||
icon: FolderOpenIcon,
|
||||
},
|
||||
{
|
||||
label: 'Worlds',
|
||||
href: `${basePath.value}/worlds`,
|
||||
icon: GlobeIcon,
|
||||
},
|
||||
{
|
||||
label: 'Logs',
|
||||
href: `${basePath.value}/logs`,
|
||||
icon: TerminalSquareIcon,
|
||||
},
|
||||
]
|
||||
|
||||
if (showShareTab.value) {
|
||||
instanceTabs.push({
|
||||
label: 'Share',
|
||||
href: `${basePath.value}/share`,
|
||||
icon: UserPlusIcon,
|
||||
})
|
||||
}
|
||||
|
||||
return instanceTabs
|
||||
})
|
||||
const tabs = computed(() => [
|
||||
{
|
||||
label: 'Content',
|
||||
href: `${basePath.value}`,
|
||||
icon: BoxesIcon,
|
||||
},
|
||||
{
|
||||
label: 'Files',
|
||||
href: `${basePath.value}/files`,
|
||||
icon: FolderOpenIcon,
|
||||
},
|
||||
{
|
||||
label: 'Worlds',
|
||||
href: `${basePath.value}/worlds`,
|
||||
icon: GlobeIcon,
|
||||
},
|
||||
{
|
||||
label: 'Logs',
|
||||
href: `${basePath.value}/logs`,
|
||||
icon: TerminalSquareIcon,
|
||||
},
|
||||
])
|
||||
|
||||
if (instance.value) {
|
||||
breadcrumbs.setName(
|
||||
@@ -684,7 +571,13 @@ if (instance.value) {
|
||||
|
||||
const options = ref<InstanceType<typeof ContextMenu> | null>(null)
|
||||
|
||||
const launchInstance = async (context: string) => {
|
||||
const startInstance = async (context: string) => {
|
||||
if (!instance.value) return
|
||||
if (updateToPlayModal.value?.hasUpdate) {
|
||||
updateToPlayModal.value.show(instance.value)
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
await run(route.params.id as string)
|
||||
@@ -694,7 +587,6 @@ const launchInstance = async (context: string) => {
|
||||
}
|
||||
loading.value = false
|
||||
|
||||
if (!instance.value) return
|
||||
trackEvent('InstanceStart', {
|
||||
loader: instance.value.loader,
|
||||
game_version: instance.value.game_version,
|
||||
@@ -702,49 +594,6 @@ const launchInstance = async (context: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
async function handleSharedInstanceUnavailable(
|
||||
reason: SharedInstanceUnavailableReason | null = null,
|
||||
) {
|
||||
notifySharedInstanceUnavailable(reason, sharedInstanceUnavailableManager.value)
|
||||
await fetchInstance()
|
||||
setSharedInstanceUnavailable(reason)
|
||||
}
|
||||
|
||||
const startInstance = async (context: string) => {
|
||||
if (!instance.value) return
|
||||
if (loading.value || playing.value) return
|
||||
|
||||
const isSharedInstanceMember = instance.value.shared_instance?.role === 'member'
|
||||
const canCheckSharedInstanceUpdate =
|
||||
isSharedInstanceMember && !sharedInstanceActionsLocked.value && !offline.value
|
||||
|
||||
if (canCheckSharedInstanceUpdate) {
|
||||
const preview = sharedInstanceUpdatePreview.value
|
||||
|
||||
if (preview?.updateAvailable && sharedInstanceUpdateModal.value) {
|
||||
sharedInstanceUpdateModal.value.show(instance.value, preview, async () => {
|
||||
await fetchInstance()
|
||||
await launchInstance(context)
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (updateToPlayModal.value?.hasUpdate) {
|
||||
if (isSharedInstanceMember) {
|
||||
updateToPlayModal.value.show(instance.value, null, async () => {
|
||||
await fetchInstance()
|
||||
await launchInstance(context)
|
||||
})
|
||||
} else {
|
||||
updateToPlayModal.value.show(instance.value)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
await launchInstance(context)
|
||||
}
|
||||
|
||||
const stopInstance = async (context: string) => {
|
||||
stopping.value = true
|
||||
await kill(route.params.id as string).catch(handleError)
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
<ReadyTransition :pending="loading">
|
||||
<ContentPageLayout>
|
||||
<template #modals>
|
||||
<UnknownFileWarningModal
|
||||
ref="unknownFileWarningModal"
|
||||
mode="mod"
|
||||
:file-name="unknownFileName"
|
||||
@cancel="resolveUnknownFileWarning(false)"
|
||||
@continue="handleUnknownFileContinue"
|
||||
/>
|
||||
<ShareModalWrapper
|
||||
ref="shareModal"
|
||||
:share-title="formatMessage(messages.shareTitle)"
|
||||
@@ -12,24 +19,14 @@
|
||||
ref="modpackContentModal"
|
||||
:modpack-name="displayedModpackProject?.title"
|
||||
:modpack-icon-url="displayedModpackProject?.icon_url ?? undefined"
|
||||
:enable-toggle="!props.isServerInstance && !isSharedMember"
|
||||
:enable-toggle="!props.isServerInstance"
|
||||
:busy="isBulkOperating"
|
||||
:get-overflow-options="getOverflowOptions"
|
||||
:switch-version="
|
||||
props.isServerInstance || isSharedMember ? undefined : handleSwitchVersion
|
||||
"
|
||||
:switch-version="handleSwitchVersion"
|
||||
@update:enabled="handleModpackContentToggle"
|
||||
@bulk:enable="(items) => handleModpackContentBulkToggle(items, true)"
|
||||
@bulk:disable="(items) => handleModpackContentBulkToggle(items, false)"
|
||||
/>
|
||||
<ConfirmDisableModal
|
||||
ref="sharedDisableConfirmModal"
|
||||
:count="pendingModpackDisableItems.length"
|
||||
:item-type="formatMessage(messages.contentTypeProject)"
|
||||
:warning="managedContentPolicy.disableWarning(pendingModpackDisableItems)"
|
||||
:action-disabled="isInstanceBusy"
|
||||
@disable="confirmPendingModpackContentDisable"
|
||||
/>
|
||||
<ConfirmModpackUpdateModal
|
||||
ref="modpackUpdateConfirmModal"
|
||||
:downgrade="isModpackUpdateDowngrade"
|
||||
@@ -81,7 +78,6 @@ import { ClipboardCopyIcon, FolderOpenIcon } from '@modrinth/assets'
|
||||
import {
|
||||
type BulkOperationStatus,
|
||||
commonMessages,
|
||||
ConfirmDisableModal,
|
||||
ConfirmModpackUpdateModal,
|
||||
ContentCardLayout as ContentPageLayout,
|
||||
type ContentItem,
|
||||
@@ -95,8 +91,10 @@ import {
|
||||
ModpackContentModal,
|
||||
type ModpackContentModalState,
|
||||
type OverflowMenuOption,
|
||||
provideAppBackup,
|
||||
provideContentManager,
|
||||
ReadyTransition,
|
||||
UnknownFileWarningModal,
|
||||
useDebugLogger,
|
||||
useVIntl,
|
||||
versionChangesGameVersion,
|
||||
@@ -111,7 +109,6 @@ import { useRouter } from 'vue-router'
|
||||
|
||||
import ExportModal from '@/components/ui/ExportModal.vue'
|
||||
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||
import { useManagedContentPolicy } from '@/composables/instances/use-managed-content-policy'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project_versions, get_version, get_version_many } from '@/helpers/cache.js'
|
||||
import {
|
||||
@@ -119,10 +116,13 @@ import {
|
||||
instance_listener,
|
||||
type InstanceBulkUpdateProgress,
|
||||
} from '@/helpers/events.js'
|
||||
import { install_duplicate_instance, installJobInstanceId } from '@/helpers/install'
|
||||
import {
|
||||
add_project_from_path,
|
||||
edit,
|
||||
get_linked_modpack_content,
|
||||
is_file_on_modrinth,
|
||||
list,
|
||||
remove_project,
|
||||
switch_project_version_with_dependencies,
|
||||
toggle_disable_project,
|
||||
@@ -130,11 +130,12 @@ import {
|
||||
update_managed_modrinth_version,
|
||||
} from '@/helpers/instance'
|
||||
import { type InstanceContentData, loadInstanceContentData } from '@/helpers/instance-content'
|
||||
import { get as getSettings, set as setSettings } from '@/helpers/settings'
|
||||
import type { CacheBehaviour, GameInstance } from '@/helpers/types'
|
||||
import { highlightModInInstance } from '@/helpers/utils.js'
|
||||
import { injectContentInstall } from '@/providers/content-install'
|
||||
import { provideInstanceBackup } from '@/providers/instance-backup'
|
||||
import { useTheming } from '@/store/state'
|
||||
import type { FeatureFlag } from '@/store/theme'
|
||||
|
||||
const messages = defineMessages({
|
||||
shareTitle: {
|
||||
@@ -185,6 +186,7 @@ const router = useRouter()
|
||||
const queryClient = useQueryClient()
|
||||
const debug = useDebugLogger('Mods:ContentUpdate')
|
||||
const themeStore = useTheming()
|
||||
const skipUnknownFileWarningFeatureFlag = 'skip_unknown_pack_warning' as FeatureFlag
|
||||
const skipNonEssentialWarnings = computed(() =>
|
||||
themeStore.getFeatureFlag('skip_non_essential_warnings'),
|
||||
)
|
||||
@@ -195,12 +197,6 @@ const props = defineProps<{
|
||||
openSettings?: () => void
|
||||
preloadedContent?: InstanceContentData | null
|
||||
}>()
|
||||
const managedContentPolicy = useManagedContentPolicy(computed(() => props.instance))
|
||||
const {
|
||||
isManagedModpack: isSharedMember,
|
||||
canMutateContent,
|
||||
canUpdateContent: canUpdateProject,
|
||||
} = managedContentPolicy
|
||||
|
||||
function hasPreloadedContent(contentData: InstanceContentData | null | undefined) {
|
||||
return contentData?.path === props.instance.id
|
||||
@@ -300,8 +296,9 @@ const exportModal = ref(null)
|
||||
const contentUpdaterModal = ref<InstanceType<typeof ContentUpdaterModal> | null>()
|
||||
const modpackContentModal = ref<InstanceType<typeof ModpackContentModal> | null>()
|
||||
const modpackUpdateConfirmModal = ref<InstanceType<typeof ConfirmModpackUpdateModal> | null>()
|
||||
const sharedDisableConfirmModal = ref<InstanceType<typeof ConfirmDisableModal> | null>()
|
||||
const pendingModpackDisableItems = ref<ContentItem[]>([])
|
||||
const unknownFileWarningModal = ref<InstanceType<typeof UnknownFileWarningModal> | null>()
|
||||
const unknownFileName = ref('')
|
||||
let resolveUnknownFileConfirmation: ((confirmed: boolean) => void) | null = null
|
||||
|
||||
const modpackContentQueryKey = computed(() => ['linkedModpackContent', props.instance.id])
|
||||
const modpackContentQuery = useQuery({
|
||||
@@ -380,8 +377,8 @@ function hasContentOperation(item: ContentItem) {
|
||||
return keys.some((key) => activeContentOperationKeys.value.has(key))
|
||||
}
|
||||
|
||||
function canDeleteContent(item: ContentItem) {
|
||||
return canMutateContent(item)
|
||||
function canUpdateProject(item: ContentItem) {
|
||||
return !!item.file_path && !!item.has_update && !!item.update_version_id
|
||||
}
|
||||
|
||||
function setContentItemBusy(item: ContentItem, busy: boolean, originalFileName = item.file_name) {
|
||||
@@ -500,14 +497,34 @@ async function handleUploadFiles() {
|
||||
if (!props.instance) return
|
||||
const files = await open({ multiple: true })
|
||||
if (!files) return
|
||||
|
||||
const addedFiles: string[] = []
|
||||
const selectedFiles: Array<{ path: string; filename: string }> = []
|
||||
for (const file of files) {
|
||||
const path = (file as { path?: string }).path ?? file
|
||||
const fileName = typeof path === 'string' ? (path.split('/').pop() ?? path) : String(path)
|
||||
if (typeof path !== 'string') continue
|
||||
selectedFiles.push({
|
||||
path,
|
||||
filename: path.split(/[\\/]/).pop() ?? path,
|
||||
})
|
||||
}
|
||||
|
||||
const fileRecognition = await Promise.all(
|
||||
selectedFiles.map(async ({ path }) => {
|
||||
try {
|
||||
return await is_file_on_modrinth(path)
|
||||
} catch {
|
||||
return true
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
const addedFiles: string[] = []
|
||||
for (const [index, { path, filename }] of selectedFiles.entries()) {
|
||||
if (!fileRecognition[index] && !(await confirmUnknownFileInstallation(filename))) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
await add_project_from_path(props.instance.id, path)
|
||||
addedFiles.push(fileName)
|
||||
addedFiles.push(filename)
|
||||
} catch (e) {
|
||||
handleError(e as Error)
|
||||
}
|
||||
@@ -532,6 +549,39 @@ async function handleUploadFiles() {
|
||||
}
|
||||
}
|
||||
|
||||
function confirmUnknownFileInstallation(fileName: string) {
|
||||
if (themeStore.getFeatureFlag(skipUnknownFileWarningFeatureFlag)) {
|
||||
return Promise.resolve(true)
|
||||
}
|
||||
|
||||
unknownFileName.value = fileName
|
||||
return new Promise<boolean>((resolve) => {
|
||||
resolveUnknownFileConfirmation = resolve
|
||||
void nextTick(() => unknownFileWarningModal.value?.show())
|
||||
})
|
||||
}
|
||||
|
||||
function resolveUnknownFileWarning(confirmed: boolean) {
|
||||
const resolve = resolveUnknownFileConfirmation
|
||||
resolveUnknownFileConfirmation = null
|
||||
unknownFileName.value = ''
|
||||
resolve?.(confirmed)
|
||||
}
|
||||
|
||||
async function handleUnknownFileContinue(dontShowAgain: boolean) {
|
||||
if (dontShowAgain) {
|
||||
themeStore.featureFlags[skipUnknownFileWarningFeatureFlag] = true
|
||||
try {
|
||||
const settings = await getSettings()
|
||||
settings.feature_flags[skipUnknownFileWarningFeatureFlag] = true
|
||||
await setSettings(settings)
|
||||
} catch (error) {
|
||||
handleError(error as Error)
|
||||
}
|
||||
}
|
||||
resolveUnknownFileWarning(true)
|
||||
}
|
||||
|
||||
async function toggleDisableMod(mod: ContentItem, desiredEnabled?: boolean) {
|
||||
if (!mod.file_path) return
|
||||
const operation = beginContentOperation(mod)
|
||||
@@ -734,7 +784,6 @@ async function updateProject(mod: ContentItem) {
|
||||
}
|
||||
|
||||
async function switchProjectVersion(mod: ContentItem, version: Labrinth.Versions.v2.Version) {
|
||||
if (!canMutateContent(mod)) return
|
||||
if (!mod.file_path) return
|
||||
const operation = beginContentOperation(mod)
|
||||
if (!operation) return
|
||||
@@ -871,7 +920,6 @@ async function handleUpdate(id: string) {
|
||||
}
|
||||
|
||||
async function handleSwitchVersion(item: ContentItem) {
|
||||
if (!canMutateContent(item)) return
|
||||
if (!item.project?.id || !item.version?.id) return
|
||||
|
||||
const requestId = beginUpdateRequest()
|
||||
@@ -899,32 +947,10 @@ async function handleSwitchVersion(item: ContentItem) {
|
||||
}
|
||||
|
||||
async function handleModpackContentToggle(item: ContentItem, enabled: boolean) {
|
||||
if (!enabled && managedContentPolicy.disableWarning([item])) {
|
||||
pendingModpackDisableItems.value = [item]
|
||||
sharedDisableConfirmModal.value?.show()
|
||||
return
|
||||
}
|
||||
|
||||
await toggleDisableDebounced(item, enabled)
|
||||
}
|
||||
|
||||
async function handleModpackContentBulkToggle(items: ContentItem[], enabled: boolean) {
|
||||
if (!enabled && managedContentPolicy.disableWarning(items)) {
|
||||
pendingModpackDisableItems.value = items
|
||||
sharedDisableConfirmModal.value?.show()
|
||||
return
|
||||
}
|
||||
|
||||
await setModpackContentEnabled(items, enabled)
|
||||
}
|
||||
|
||||
async function confirmPendingModpackContentDisable() {
|
||||
const items = [...pendingModpackDisableItems.value]
|
||||
pendingModpackDisableItems.value = []
|
||||
await setModpackContentEnabled(items, false)
|
||||
}
|
||||
|
||||
async function setModpackContentEnabled(items: ContentItem[], enabled: boolean) {
|
||||
await Promise.all(items.map((item) => toggleDisableMod(item, enabled)))
|
||||
}
|
||||
|
||||
@@ -1274,7 +1300,29 @@ function applyContentData(contentData: InstanceContentData) {
|
||||
return true
|
||||
}
|
||||
|
||||
provideInstanceBackup(() => props.instance)
|
||||
provideAppBackup({
|
||||
async createBackup() {
|
||||
const allInstances = await list()
|
||||
const prefix = `${props.instance.name} - Backup #`
|
||||
const existingNums = allInstances
|
||||
.filter((p) => p.name.startsWith(prefix))
|
||||
.map((p) => parseInt(p.name.slice(prefix.length), 10))
|
||||
.filter((n) => !isNaN(n))
|
||||
const nextNum = existingNums.length > 0 ? Math.max(...existingNums) + 1 : 1
|
||||
const job = await install_duplicate_instance(props.instance.id)
|
||||
const newInstanceId = installJobInstanceId(job)
|
||||
if (newInstanceId) {
|
||||
await edit(newInstanceId, { name: `${prefix}${nextNum}` })
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const CONTENT_HINT_KEY = 'content-tab-modpack-hint-dismissed'
|
||||
const showContentHint = ref(localStorage.getItem(CONTENT_HINT_KEY) === null)
|
||||
function dismissContentHint() {
|
||||
showContentHint.value = false
|
||||
localStorage.setItem(CONTENT_HINT_KEY, 'true')
|
||||
}
|
||||
|
||||
provideContentManager({
|
||||
items: mergedProjects,
|
||||
@@ -1336,23 +1384,15 @@ provideContentManager({
|
||||
toggleEnabled: toggleDisableDebounced,
|
||||
bulkEnableItems: (items: ContentItem[]) =>
|
||||
Promise.all(
|
||||
items
|
||||
.filter((item) => canMutateContent(item) && !item.enabled)
|
||||
.map((item) => toggleDisableMod(item, true)),
|
||||
items.filter((item) => !item.enabled).map((item) => toggleDisableMod(item, true)),
|
||||
).then(() => {}),
|
||||
bulkDisableItems: (items: ContentItem[]) =>
|
||||
Promise.all(
|
||||
items
|
||||
.filter((item) => canMutateContent(item) && item.enabled)
|
||||
.map((item) => toggleDisableMod(item, false)),
|
||||
items.filter((item) => item.enabled).map((item) => toggleDisableMod(item, false)),
|
||||
).then(() => {}),
|
||||
deleteItem: removeMod,
|
||||
bulkDeleteItems: (items: ContentItem[]) =>
|
||||
Promise.all(items.filter(canMutateContent).map((item) => removeMod(item))).then(() => {}),
|
||||
canDeleteItem: canDeleteContent,
|
||||
canToggleItem: canMutateContent,
|
||||
getDeleteWarning: managedContentPolicy.deleteWarning,
|
||||
getDisableWarning: managedContentPolicy.disableWarning,
|
||||
Promise.all(items.map((item) => removeMod(item))).then(() => {}),
|
||||
getDeleteDependencyWarning,
|
||||
refresh: () => initProjects('must_revalidate'),
|
||||
browse: handleBrowseContent,
|
||||
@@ -1361,12 +1401,14 @@ provideContentManager({
|
||||
updateItem: handleUpdate,
|
||||
bulkUpdateAll: bulkUpdateAllProjects,
|
||||
bulkUpdateItem: updateProject,
|
||||
updateModpack: props.isServerInstance || isSharedMember.value ? undefined : handleModpackUpdate,
|
||||
updateModpack: props.isServerInstance ? undefined : handleModpackUpdate,
|
||||
viewModpackContent: handleModpackContent,
|
||||
unlinkModpack: unpairInstance,
|
||||
openSettings: props.openSettings,
|
||||
switchVersion: handleSwitchVersion,
|
||||
getOverflowOptions,
|
||||
showContentHint,
|
||||
dismissContentHint,
|
||||
shareItems: handleShareItems,
|
||||
getItemId: getContentItemId,
|
||||
mapToTableItem: (item: ContentItem) => ({
|
||||
@@ -1398,11 +1440,8 @@ provideContentManager({
|
||||
link: () => openUrl(`https://modrinth.com/${item.owner!.type}/${item.owner!.id}`),
|
||||
}
|
||||
: undefined,
|
||||
enabled: canMutateContent(item) ? item.enabled : undefined,
|
||||
enabled: item.enabled,
|
||||
installing: item.installing,
|
||||
hideDelete: !canDeleteContent(item),
|
||||
hideSwitchVersion: !canMutateContent(item),
|
||||
hasUpdate: canUpdateProject(item),
|
||||
}),
|
||||
filterPersistKey: props.instance.id,
|
||||
})
|
||||
|
||||
@@ -3,7 +3,6 @@ import Index from './Index.vue'
|
||||
import Logs from './Logs.vue'
|
||||
import Mods from './Mods.vue'
|
||||
import Overview from './Overview.vue'
|
||||
import Share from './share/index.vue'
|
||||
import Worlds from './Worlds.vue'
|
||||
|
||||
export { Files, Index, Logs, Mods, Overview, Share, Worlds }
|
||||
export { Files, Index, Logs, Mods, Overview, Worlds }
|
||||
|
||||
@@ -1,356 +0,0 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<ModrinthAccountRequiredModal ref="accountRequiredModal" :request-auth="requestAuth" />
|
||||
<InvitePlayersModal
|
||||
ref="invitePlayersModal"
|
||||
:header="formatMessage(messages.shareModalHeader, { name: instance.name })"
|
||||
:friends="inviteFriends"
|
||||
:search-users="searchInviteUsers"
|
||||
:link="inviteLink.link.value"
|
||||
:link-expires-at="inviteLink.details.value?.expiresAt"
|
||||
:link-max-uses="inviteLink.details.value?.maxUses"
|
||||
:update-invite-link="inviteLink.update"
|
||||
:user-profile-link="userProfileLink"
|
||||
@invite="invitePlayer"
|
||||
@cancel="cancelInvite"
|
||||
/>
|
||||
<ConfirmUnlinkModal
|
||||
ref="unlinkModal"
|
||||
:warning="{
|
||||
header: formatMessage(messages.unlinkForShareHeader),
|
||||
body: formatMessage(messages.unlinkForShareBody),
|
||||
}"
|
||||
:backup-tip="importedModpackBackupTip"
|
||||
@unlink="unlinkImportedModpack"
|
||||
/>
|
||||
<SharedInstanceRemoveMemberModal
|
||||
ref="removeMemberModal"
|
||||
:row="pendingRemovalRow"
|
||||
:member-count="members.rows.value.length"
|
||||
@confirm="removeMember"
|
||||
@clear="pendingRemovalRow = null"
|
||||
/>
|
||||
|
||||
<SharedPlayersTable
|
||||
v-if="members.rows.value.length > 0"
|
||||
:rows="members.rows.value"
|
||||
:actions-locked="sharedInstanceActionsLocked"
|
||||
:invite-pending="inviteLink.pending.value"
|
||||
:user-profile-link="userProfileLink"
|
||||
@invite="showInvitePlayers"
|
||||
@remove="showRemoveMemberModal"
|
||||
/>
|
||||
|
||||
<SharedInstanceShareEmptyState
|
||||
v-else-if="sharedInstanceUnavailable"
|
||||
:heading="formatMessage(sharedInstanceErrorMessages.unavailableTitle)"
|
||||
:description="
|
||||
formatSharedInstanceUnavailable(
|
||||
sharedInstanceUnavailableReason,
|
||||
sharedInstanceUnavailableManager,
|
||||
)
|
||||
"
|
||||
/>
|
||||
|
||||
<SharedInstanceShareEmptyState
|
||||
v-else-if="sharedInstanceActionsLocked"
|
||||
:heading="formatMessage(lockedEmptyHeading)"
|
||||
>
|
||||
<template #description>
|
||||
<span class="flex flex-wrap items-center justify-center gap-x-1.5 gap-y-1">
|
||||
<span>{{ formatMessage(messages.lockedEmptyDescriptionPrefix) }}</span>
|
||||
<span
|
||||
v-if="linkedAccount"
|
||||
class="inline-flex max-w-full min-w-0 items-center gap-1.5 align-middle font-semibold text-primary"
|
||||
>
|
||||
<Avatar
|
||||
:src="linkedAccount.avatarUrl"
|
||||
:alt="linkedAccount.username"
|
||||
:tint-by="linkedAccount.tintBy"
|
||||
size="20px"
|
||||
circle
|
||||
no-shadow
|
||||
/>
|
||||
<span class="min-w-0 truncate">{{ linkedAccount.username }}</span>
|
||||
</span>
|
||||
<span v-else class="font-semibold text-primary">{{
|
||||
formatMessage(messages.linkedAccountFallback)
|
||||
}}</span>
|
||||
<span>{{ formatMessage(messages.lockedEmptyDescriptionSuffix) }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template #actions>
|
||||
<ButtonStyled color="brand"
|
||||
><button class="!h-10" @click="signInToShare">
|
||||
<LogInIcon aria-hidden="true" />{{ formatMessage(lockedActionButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</template>
|
||||
</SharedInstanceShareEmptyState>
|
||||
|
||||
<SharedInstanceShareEmptyState
|
||||
v-else
|
||||
:heading="formatMessage(messages.noFriendsInvitedHeading)"
|
||||
:description="formatMessage(messages.noFriendsInvitedDescription)"
|
||||
>
|
||||
<template #actions>
|
||||
<ButtonStyled color="brand"
|
||||
><button
|
||||
class="!h-10"
|
||||
:disabled="inviteLink.pending.value"
|
||||
@click="showInvitePlayers($event)"
|
||||
>
|
||||
<SpinnerIcon
|
||||
v-if="inviteLink.pending.value"
|
||||
class="animate-spin"
|
||||
aria-hidden="true"
|
||||
/><UserPlusIcon v-else aria-hidden="true" />{{
|
||||
formatMessage(messages.inviteFriendsButton)
|
||||
}}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</template>
|
||||
</SharedInstanceShareEmptyState>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LogInIcon, SpinnerIcon, UserPlusIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
ConfirmUnlinkModal,
|
||||
defineMessages,
|
||||
injectAuth,
|
||||
injectNotificationManager,
|
||||
type InvitePlayersInvitePayload,
|
||||
InvitePlayersModal,
|
||||
type InvitePlayersUser,
|
||||
SharedPlayersTable,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { useQueryClient } from '@tanstack/vue-query'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { computed, ref, toRef, watch } from 'vue'
|
||||
|
||||
import ModrinthAccountRequiredModal from '@/components/ui/modal/ModrinthAccountRequiredModal.vue'
|
||||
import {
|
||||
getSharedInstanceUnavailableReason,
|
||||
isSharedInstanceUnavailableError,
|
||||
} from '@/helpers/install'
|
||||
import { edit } from '@/helpers/instance'
|
||||
import type { ModrinthAuthFlow } from '@/helpers/mr_auth.ts'
|
||||
import {
|
||||
sharedInstanceErrorMessages,
|
||||
useSharedInstanceErrors,
|
||||
} from '@/helpers/shared-instance-errors'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { provideInstanceBackup } from '@/providers/instance-backup'
|
||||
|
||||
import { injectSharedInstanceState } from '../use-shared-instance-state'
|
||||
import SharedInstanceRemoveMemberModal from './shared-instance-remove-member-modal.vue'
|
||||
import SharedInstanceShareEmptyState from './shared-instance-share-empty-state.vue'
|
||||
import type { ShareRow } from './shared-instance-share-types'
|
||||
import { useSharedInstanceInviteCandidates } from './use-shared-instance-invite-candidates'
|
||||
import { useSharedInstanceInviteLink } from './use-shared-instance-invite-link'
|
||||
import { useSharedInstanceMembers } from './use-shared-instance-members'
|
||||
|
||||
const props = defineProps<{ instance: GameInstance }>()
|
||||
const auth = injectAuth()
|
||||
const queryClient = useQueryClient()
|
||||
const { handleError } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const {
|
||||
formatSharedInstanceUnavailable,
|
||||
notifySharedInstanceError,
|
||||
notifySharedInstanceUnavailable,
|
||||
} = useSharedInstanceErrors()
|
||||
const sharedInstanceState = injectSharedInstanceState()
|
||||
const instance = toRef(props, 'instance')
|
||||
const actionsLocked = sharedInstanceState.shareActionsLocked
|
||||
const sharedInstanceActionsLocked = actionsLocked
|
||||
const currentUserId = computed(() => auth.user.value?.id ?? null)
|
||||
const isSignedIn = computed(() => !!auth.session_token.value)
|
||||
const accountRequiredModal = ref<InstanceType<typeof ModrinthAccountRequiredModal>>()
|
||||
const invitePlayersModal = ref<InstanceType<typeof InvitePlayersModal>>()
|
||||
const unlinkModal = ref<InstanceType<typeof ConfirmUnlinkModal>>()
|
||||
const removeMemberModal = ref<InstanceType<typeof SharedInstanceRemoveMemberModal>>()
|
||||
const pendingRemovalRow = ref<ShareRow | null>(null)
|
||||
const importedModpackUnlinked = ref(false)
|
||||
|
||||
function notifyOperationError(error: unknown) {
|
||||
if (isSharedInstanceUnavailableError(error)) {
|
||||
notifySharedInstanceUnavailable(
|
||||
getSharedInstanceUnavailableReason(error),
|
||||
sharedInstanceState.unavailableManager.value,
|
||||
)
|
||||
} else {
|
||||
notifySharedInstanceError(error instanceof Error ? error : new Error(String(error)))
|
||||
}
|
||||
}
|
||||
|
||||
const members = useSharedInstanceMembers({
|
||||
instance,
|
||||
currentUserId,
|
||||
isSignedIn,
|
||||
actionsLocked,
|
||||
onError: notifyOperationError,
|
||||
onHydrationError: handleError,
|
||||
})
|
||||
const {
|
||||
inviteFriends,
|
||||
search: searchInviteUsers,
|
||||
requestFriend,
|
||||
} = useSharedInstanceInviteCandidates({
|
||||
rows: members.rows,
|
||||
currentUserId,
|
||||
isSignedIn,
|
||||
actionsLocked,
|
||||
})
|
||||
const inviteLink = useSharedInstanceInviteLink(
|
||||
computed(() => props.instance.id),
|
||||
notifyOperationError,
|
||||
)
|
||||
|
||||
const linkedAccount = computed(() => {
|
||||
const manager = sharedInstanceState.manager.value
|
||||
return manager?.type === 'user'
|
||||
? { username: manager.name, avatarUrl: manager.avatarUrl, tintBy: manager.tintBy }
|
||||
: null
|
||||
})
|
||||
const lockedEmptyHeading = computed(() =>
|
||||
isSignedIn.value ? messages.lockedWrongAccountHeading : messages.lockedSignedOutHeading,
|
||||
)
|
||||
const lockedActionButton = computed(() =>
|
||||
isSignedIn.value ? messages.switchAccountButton : messages.signInButton,
|
||||
)
|
||||
const sharedInstanceUnavailableReason = sharedInstanceState.unavailableReason
|
||||
const sharedInstanceUnavailable = computed(() => !!sharedInstanceUnavailableReason.value)
|
||||
const sharedInstanceUnavailableManager = sharedInstanceState.unavailableManager
|
||||
const requiresUnlink = computed(
|
||||
() =>
|
||||
props.instance.link?.type === 'imported_modpack' &&
|
||||
!props.instance.shared_instance &&
|
||||
!importedModpackUnlinked.value,
|
||||
)
|
||||
const importedModpackBackupTip = computed(() =>
|
||||
props.instance.link?.type === 'imported_modpack'
|
||||
? (props.instance.link.name ?? props.instance.link.filename ?? undefined)
|
||||
: undefined,
|
||||
)
|
||||
|
||||
const messages = defineMessages({
|
||||
signInButton: { id: 'app.instance.share.sign-in.button', defaultMessage: 'Sign in' },
|
||||
noFriendsInvitedHeading: {
|
||||
id: 'app.instance.share.empty.heading',
|
||||
defaultMessage: 'No friends invited',
|
||||
},
|
||||
noFriendsInvitedDescription: {
|
||||
id: 'app.instance.share.empty.description',
|
||||
defaultMessage: 'You can share this instance with your friends!',
|
||||
},
|
||||
inviteFriendsButton: {
|
||||
id: 'app.instance.share.empty.invite-friends-button',
|
||||
defaultMessage: 'Invite friends',
|
||||
},
|
||||
shareModalHeader: {
|
||||
id: 'app.instance.share.invite-modal.heading',
|
||||
defaultMessage: 'Share {name}',
|
||||
},
|
||||
lockedWrongAccountHeading: {
|
||||
id: 'app.instance.share.locked.wrong-account-heading',
|
||||
defaultMessage: 'Wrong account',
|
||||
},
|
||||
lockedSignedOutHeading: {
|
||||
id: 'app.instance.share.locked.signed-out-heading',
|
||||
defaultMessage: 'Not signed in',
|
||||
},
|
||||
lockedEmptyDescriptionPrefix: {
|
||||
id: 'app.instance.share.locked.empty-description-prefix',
|
||||
defaultMessage: 'You need to sign in as',
|
||||
},
|
||||
lockedEmptyDescriptionSuffix: {
|
||||
id: 'app.instance.share.locked.empty-description-suffix',
|
||||
defaultMessage: 'to access this page.',
|
||||
},
|
||||
linkedAccountFallback: {
|
||||
id: 'app.instance.share.locked.linked-account-fallback',
|
||||
defaultMessage: 'the linked account',
|
||||
},
|
||||
switchAccountButton: {
|
||||
id: 'app.instance.share.locked.switch-account-button',
|
||||
defaultMessage: 'Switch account',
|
||||
},
|
||||
unlinkForShareHeader: {
|
||||
id: 'app.instance.share.unlink.header',
|
||||
defaultMessage: 'Sharing requires unlinking',
|
||||
},
|
||||
unlinkForShareBody: {
|
||||
id: 'app.instance.share.unlink.body',
|
||||
defaultMessage: 'You must unlink this modpack to share your instance',
|
||||
},
|
||||
})
|
||||
|
||||
function invitePlayer(payload: InvitePlayersInvitePayload) {
|
||||
if (actionsLocked.value) return
|
||||
if (payload.source === 'search') void requestFriend(payload.user)
|
||||
members.invite(payload.user)
|
||||
}
|
||||
function cancelInvite(user: InvitePlayersUser) {
|
||||
const row = members.find(user.id, user.username)
|
||||
if (row) members.remove(row.id)
|
||||
}
|
||||
async function showInvitePlayers(event?: MouseEvent) {
|
||||
if (actionsLocked.value) return
|
||||
if (!isSignedIn.value) return signInToShare(event)
|
||||
if (requiresUnlink.value) return unlinkModal.value?.show()
|
||||
if (await inviteLink.ensure()) invitePlayersModal.value?.show(event)
|
||||
}
|
||||
async function unlinkImportedModpack() {
|
||||
try {
|
||||
await edit(props.instance.id, { link: null as unknown as undefined })
|
||||
importedModpackUnlinked.value = true
|
||||
await queryClient.invalidateQueries({ queryKey: ['linkedModpackInfo', props.instance.id] })
|
||||
if (await inviteLink.ensure()) invitePlayersModal.value?.show()
|
||||
} catch (error) {
|
||||
notifyOperationError(error)
|
||||
}
|
||||
}
|
||||
function showRemoveMemberModal(row: ShareRow) {
|
||||
if (!actionsLocked.value) {
|
||||
pendingRemovalRow.value = row
|
||||
removeMemberModal.value?.show()
|
||||
}
|
||||
}
|
||||
function removeMember(row: ShareRow) {
|
||||
members.remove(row.id)
|
||||
}
|
||||
function userProfileLink(username: string) {
|
||||
return !username || username.includes('@')
|
||||
? undefined
|
||||
: () => openUrl(`https://modrinth.com/user/${encodeURIComponent(username)}`)
|
||||
}
|
||||
async function requestAuth(flow: ModrinthAuthFlow) {
|
||||
await auth.requestSignIn(`/instance/${encodeURIComponent(props.instance.id)}/share`, flow)
|
||||
return !!auth.session_token.value
|
||||
}
|
||||
function signInToShare(event?: MouseEvent) {
|
||||
void accountRequiredModal.value?.show(event)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.instance.id,
|
||||
() => {
|
||||
importedModpackUnlinked.value = false
|
||||
},
|
||||
)
|
||||
watch(
|
||||
[() => auth.isReady.value, isSignedIn, actionsLocked],
|
||||
([ready, signedIn, locked]) => {
|
||||
if (ready && !signedIn && !locked) signInToShare()
|
||||
},
|
||||
{ immediate: true, flush: 'post' },
|
||||
)
|
||||
|
||||
provideInstanceBackup(() => props.instance)
|
||||
</script>
|
||||
@@ -1,122 +0,0 @@
|
||||
<template>
|
||||
<NewModal
|
||||
ref="modal"
|
||||
:header="formatMessage(messages.header)"
|
||||
max-width="470px"
|
||||
@after-hide="emit('clear')"
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<Admonition type="warning">{{ formatMessage(messages.warning, { username }) }}</Admonition>
|
||||
<div class="flex min-w-0 items-center gap-2 rounded-[20px] bg-surface-2 p-3">
|
||||
<Avatar
|
||||
:src="row?.avatarUrl"
|
||||
:alt="formatMessage(messages.avatarAlt, { username })"
|
||||
:tint-by="username"
|
||||
size="40px"
|
||||
circle
|
||||
no-shadow
|
||||
/>
|
||||
<div class="flex min-w-0 flex-1 flex-col gap-0.5">
|
||||
<span class="min-w-0 truncate font-medium text-contrast">{{ username }}</span>
|
||||
<span class="truncate text-sm text-secondary">{{
|
||||
row ? methodLabels[row.method] : ''
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="font-semibold text-contrast">{{ formatMessage(messages.effectsLabel) }}</span>
|
||||
<ul class="m-0 list-disc pl-6 text-primary">
|
||||
<li v-for="effect in effects" :key="effect.id" class="leading-6 marker:text-secondary">
|
||||
{{ formatMessage(effect) }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2 pt-1">
|
||||
<ButtonStyled type="outlined"
|
||||
><button class="!border !border-surface-5" @click="modal?.hide()">
|
||||
<XIcon aria-hidden="true" />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
<ButtonStyled color="orange"
|
||||
><button :disabled="!row" @click="confirm">
|
||||
<UserXIcon aria-hidden="true" />{{ formatMessage(messages.removeButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UserXIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
NewModal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { methodLabels, type ShareRow } from './shared-instance-share-types'
|
||||
|
||||
const props = defineProps<{ row: ShareRow | null; memberCount: number }>()
|
||||
const emit = defineEmits<{ confirm: [row: ShareRow]; clear: [] }>()
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const { formatMessage } = useVIntl()
|
||||
const username = computed(() => props.row?.username ?? '')
|
||||
const messages = defineMessages({
|
||||
header: { id: 'app.instance.share.remove-user-modal.header', defaultMessage: 'Revoke access' },
|
||||
warning: {
|
||||
id: 'app.instance.share.remove-user-modal.warning-body',
|
||||
defaultMessage:
|
||||
"If you revoke {username}'s access to this shared instance, you'll need to invite them again before they can receive updates.",
|
||||
},
|
||||
avatarAlt: {
|
||||
id: 'app.instance.share.remove-user-modal.user-avatar-alt',
|
||||
defaultMessage: "{username}'s avatar",
|
||||
},
|
||||
effectsLabel: {
|
||||
id: 'app.instance.share.remove-user-modal.effects-label',
|
||||
defaultMessage: 'What happens?',
|
||||
},
|
||||
effectAccess: {
|
||||
id: 'app.instance.share.remove-user-modal.effect-access',
|
||||
defaultMessage: 'They will no longer receive updates for this shared instance',
|
||||
},
|
||||
effectInstalledCopy: {
|
||||
id: 'app.instance.share.remove-user-modal.effect-installed-copy',
|
||||
defaultMessage: 'Any copy they already installed will stay on their device',
|
||||
},
|
||||
effectInviteAgain: {
|
||||
id: 'app.instance.share.remove-user-modal.effect-invite-again',
|
||||
defaultMessage: 'You can invite them again later',
|
||||
},
|
||||
effectLastUser: {
|
||||
id: 'app.instance.share.remove-user-modal.effect-last-user',
|
||||
defaultMessage: 'If this is the last user, sharing will be turned off for this instance',
|
||||
},
|
||||
removeButton: {
|
||||
id: 'app.instance.share.remove-user-modal.remove-button',
|
||||
defaultMessage: 'Revoke access',
|
||||
},
|
||||
})
|
||||
const effects = computed(() => {
|
||||
const result = [messages.effectAccess, messages.effectInstalledCopy, messages.effectInviteAgain]
|
||||
if (props.memberCount === 1) result.push(messages.effectLastUser)
|
||||
return result
|
||||
})
|
||||
|
||||
function show(event?: MouseEvent) {
|
||||
modal.value?.show(event)
|
||||
}
|
||||
function confirm() {
|
||||
if (props.row) {
|
||||
modal.value?.hide()
|
||||
emit('confirm', props.row)
|
||||
}
|
||||
}
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<EmptyState type="empty-inbox">
|
||||
<template #heading>{{ heading }}</template>
|
||||
<template #description
|
||||
><slot name="description">{{ description }}</slot></template
|
||||
>
|
||||
<template v-if="$slots.actions" #actions><slot name="actions" /></template>
|
||||
</EmptyState>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { EmptyState } from '@modrinth/ui'
|
||||
|
||||
defineProps<{ heading: string; description?: string }>()
|
||||
</script>
|
||||
@@ -1,8 +0,0 @@
|
||||
export {
|
||||
type SharedPlayersTableMethodFilter as MethodFilter,
|
||||
sharedPlayersTableMethodLabels as methodLabels,
|
||||
normalizeInviteKey,
|
||||
type SharedPlayersTableMethod as ShareMethod,
|
||||
type SharedPlayersTableRow as ShareRow,
|
||||
type SharedPlayersTableColumn as ShareTableColumn,
|
||||
} from '@modrinth/ui'
|
||||
@@ -1,105 +0,0 @@
|
||||
import {
|
||||
injectNotificationManager,
|
||||
type InvitePlayersSearchUser,
|
||||
type InvitePlayersUser,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, type Ref } from 'vue'
|
||||
|
||||
import { useFriends } from '@/composables/use-friends'
|
||||
import { getFriendUserId } from '@/helpers/friends.ts'
|
||||
import { get as getCredentials } from '@/helpers/mr_auth.ts'
|
||||
import { search_user } from '@/helpers/users.ts'
|
||||
|
||||
import { normalizeInviteKey, type ShareRow } from './shared-instance-share-types'
|
||||
|
||||
export function useSharedInstanceInviteCandidates(options: {
|
||||
rows: Ref<ShareRow[]>
|
||||
currentUserId: Ref<string | null>
|
||||
isSignedIn: Ref<boolean>
|
||||
actionsLocked: Ref<boolean>
|
||||
}) {
|
||||
const { handleError } = injectNotificationManager()
|
||||
const friendsState = useFriends({
|
||||
currentUserId: options.currentUserId,
|
||||
getCredentials,
|
||||
enabled: computed(
|
||||
() =>
|
||||
options.isSignedIn.value && !!options.currentUserId.value && !options.actionsLocked.value,
|
||||
),
|
||||
onError: handleError,
|
||||
})
|
||||
const friends = friendsState.friends
|
||||
const invitedRows = computed(() => {
|
||||
const invited = new Map<string, ShareRow>()
|
||||
for (const row of options.rows.value) {
|
||||
invited.set(normalizeInviteKey(row.id), row)
|
||||
invited.set(normalizeInviteKey(row.username), row)
|
||||
}
|
||||
return invited
|
||||
})
|
||||
const inviteFriends = computed<InvitePlayersUser[]>(() =>
|
||||
friends.value
|
||||
.filter((friend) => friend.username && friend.accepted)
|
||||
.sort((a, b) => Number(b.online) - Number(a.online))
|
||||
.map((friend) => {
|
||||
const id = getFriendUserId(friend, options.currentUserId.value)
|
||||
const invited =
|
||||
invitedRows.value.get(normalizeInviteKey(id)) ??
|
||||
invitedRows.value.get(normalizeInviteKey(friend.username))
|
||||
return {
|
||||
id,
|
||||
username: friend.username,
|
||||
avatarUrl: friend.avatar,
|
||||
online: friend.online,
|
||||
status: invited ? (invited.pending ? 'pending' : 'added') : 'available',
|
||||
}
|
||||
}),
|
||||
)
|
||||
const candidateKeys = computed(() => {
|
||||
const keys = new Set<string>()
|
||||
for (const friend of inviteFriends.value) {
|
||||
keys.add(normalizeInviteKey(friend.id))
|
||||
keys.add(normalizeInviteKey(friend.username))
|
||||
}
|
||||
return keys
|
||||
})
|
||||
|
||||
async function search(query: string): Promise<InvitePlayersSearchUser[]> {
|
||||
if (options.actionsLocked.value) return []
|
||||
const credentials = await getCredentials()
|
||||
const ownUserId = options.currentUserId.value ?? credentials?.user_id ?? null
|
||||
return (await search_user(query))
|
||||
.filter((user) => user.id !== ownUserId)
|
||||
.filter((user) => {
|
||||
const id = normalizeInviteKey(user.id)
|
||||
const username = normalizeInviteKey(user.username)
|
||||
return (
|
||||
!candidateKeys.value.has(id) &&
|
||||
!candidateKeys.value.has(username) &&
|
||||
!invitedRows.value.has(id) &&
|
||||
!invitedRows.value.has(username)
|
||||
)
|
||||
})
|
||||
.map((user) => ({
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
avatarUrl: user.avatar_url || undefined,
|
||||
}))
|
||||
}
|
||||
|
||||
async function requestFriend(user: InvitePlayersUser) {
|
||||
if (options.actionsLocked.value) return
|
||||
const credentials = await getCredentials()
|
||||
const ownUserId = options.currentUserId.value ?? credentials?.user_id ?? null
|
||||
if (ownUserId && normalizeInviteKey(user.id) === normalizeInviteKey(ownUserId)) return
|
||||
if (!friendsState.findFriend(user.id, user.username)) {
|
||||
friendsState.requestFriend({
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
avatarUrl: user.avatarUrl,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return { inviteFriends, search, requestFriend }
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import type { InviteLinkSettings } from '@modrinth/ui'
|
||||
import { computed, type Ref, ref, watch } from 'vue'
|
||||
|
||||
import { config } from '@/config'
|
||||
import { toError } from '@/helpers/errors'
|
||||
import { create_shared_instance_invite_link } from '@/helpers/instance'
|
||||
|
||||
export function useSharedInstanceInviteLink(
|
||||
instanceId: Ref<string>,
|
||||
onError: (error: unknown) => void,
|
||||
) {
|
||||
const details = ref<Awaited<ReturnType<typeof create_shared_instance_invite_link>>>()
|
||||
const pending = ref(false)
|
||||
const link = computed(() =>
|
||||
details.value
|
||||
? `${config.siteUrl}/share/${encodeURIComponent(details.value.inviteId)}`
|
||||
: undefined,
|
||||
)
|
||||
|
||||
async function ensure() {
|
||||
if (details.value) return true
|
||||
if (pending.value) return false
|
||||
|
||||
pending.value = true
|
||||
try {
|
||||
details.value = await create_shared_instance_invite_link(instanceId.value)
|
||||
return true
|
||||
} catch (error) {
|
||||
onError(error)
|
||||
return false
|
||||
} finally {
|
||||
pending.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function update(settings: InviteLinkSettings) {
|
||||
if (!details.value) return
|
||||
|
||||
pending.value = true
|
||||
try {
|
||||
const maxAgeSeconds = Math.max(
|
||||
1,
|
||||
Math.min(604800, Math.floor((settings.expiresAt.getTime() - Date.now()) / 1000)),
|
||||
)
|
||||
details.value = await create_shared_instance_invite_link(instanceId.value, {
|
||||
maxAgeSeconds,
|
||||
maxUses: settings.maxUses,
|
||||
replaceInviteId: details.value.inviteId,
|
||||
})
|
||||
} catch (error) {
|
||||
throw toError(error)
|
||||
} finally {
|
||||
pending.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(instanceId, () => {
|
||||
details.value = undefined
|
||||
pending.value = false
|
||||
})
|
||||
|
||||
return { details, pending, link, ensure, update }
|
||||
}
|
||||
@@ -1,294 +0,0 @@
|
||||
import type { InvitePlayersUser } from '@modrinth/ui'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, type Ref, ref, watch } from 'vue'
|
||||
|
||||
import { get_user_many } from '@/helpers/cache.js'
|
||||
import { toError } from '@/helpers/errors'
|
||||
import {
|
||||
get_shared_instance_users,
|
||||
invite_shared_instance_users,
|
||||
remove_shared_instance_users,
|
||||
type SharedInstanceUser,
|
||||
type SharedInstanceUsers,
|
||||
} from '@/helpers/instance'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
import { normalizeInviteKey, type ShareRow } from './shared-instance-share-types'
|
||||
|
||||
type MutationContext = {
|
||||
queryKey: readonly ['sharedInstanceUsers', string]
|
||||
previousRows?: ShareRow[]
|
||||
previousPendingRows: Record<string, ShareRow>
|
||||
}
|
||||
|
||||
export function useSharedInstanceMembers(options: {
|
||||
instance: Ref<GameInstance>
|
||||
currentUserId: Ref<string | null>
|
||||
isSignedIn: Ref<boolean>
|
||||
actionsLocked: Ref<boolean>
|
||||
onError: (error: unknown) => void
|
||||
onHydrationError: (error: Error) => void
|
||||
}) {
|
||||
const queryClient = useQueryClient()
|
||||
const queryKey = computed(() => ['sharedInstanceUsers', options.instance.value.id] as const)
|
||||
const pendingRows = ref<Record<string, ShareRow>>(loadPendingRows(options.instance.value.id))
|
||||
|
||||
async function usersToRows(users: SharedInstanceUsers): Promise<ShareRow[]> {
|
||||
const excludedIds = new Set(
|
||||
[options.instance.value.shared_instance?.manager_id, options.currentUserId.value].filter(
|
||||
(id): id is string => !!id,
|
||||
),
|
||||
)
|
||||
const usersToDisplay = userEntries(users).filter((user) => !excludedIds.has(user.id))
|
||||
if (usersToDisplay.length === 0) return []
|
||||
|
||||
const profiles = (await get_user_many(usersToDisplay.map((user) => user.id))) as Array<{
|
||||
id: string
|
||||
username?: string
|
||||
avatar_url?: string | null
|
||||
}>
|
||||
|
||||
return usersToDisplay.map((user) => {
|
||||
const profile = profiles.find((candidate) => candidate.id === user.id)
|
||||
const joinedAt = parseDate(user.joined_at)
|
||||
return {
|
||||
id: user.id,
|
||||
username: profile?.username ?? user.id,
|
||||
avatarUrl: profile?.avatar_url ?? undefined,
|
||||
lastPlayedAt: parseDate(user.last_played),
|
||||
joinedAt,
|
||||
method: user.join_type === 'link' ? 'link' : 'direct',
|
||||
pending: !joinedAt,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function loadRows() {
|
||||
if (options.actionsLocked.value) return []
|
||||
const loadedRows = await usersToRows(await get_shared_instance_users(options.instance.value.id))
|
||||
removePendingRows(loadedRows.map((row) => row.id))
|
||||
return loadedRows
|
||||
}
|
||||
|
||||
const query = useQuery({
|
||||
queryKey,
|
||||
queryFn: loadRows,
|
||||
enabled: () =>
|
||||
options.isSignedIn.value && !!options.instance.value.id && !options.actionsLocked.value,
|
||||
staleTime: Infinity,
|
||||
})
|
||||
const remoteRows = computed(
|
||||
() => query.data.value ?? queryClient.getQueryData<ShareRow[]>(queryKey.value) ?? [],
|
||||
)
|
||||
const rows = computed(() => {
|
||||
if (options.actionsLocked.value) return remoteRows.value
|
||||
const remoteIds = new Set(remoteRows.value.map((row) => normalizeInviteKey(row.id)))
|
||||
return [
|
||||
...Object.values(pendingRows.value).filter(
|
||||
(row) => !remoteIds.has(normalizeInviteKey(row.id)),
|
||||
),
|
||||
...remoteRows.value,
|
||||
]
|
||||
})
|
||||
|
||||
const inviteMutation = useMutation({
|
||||
mutationFn: async (user: InvitePlayersUser) => {
|
||||
if (options.actionsLocked.value) return
|
||||
return await invite_shared_instance_users(options.instance.value.id, [user.id])
|
||||
},
|
||||
onMutate: async (user): Promise<MutationContext> => {
|
||||
const currentKey = queryKey.value
|
||||
await queryClient.cancelQueries({ queryKey: currentKey })
|
||||
const context = {
|
||||
queryKey: currentKey,
|
||||
previousRows: queryClient.getQueryData<ShareRow[]>(currentKey),
|
||||
previousPendingRows: pendingRows.value,
|
||||
}
|
||||
setPendingRow(user)
|
||||
return context
|
||||
},
|
||||
onError: (error, user, context) => {
|
||||
removePendingRow(user.id)
|
||||
restore(context)
|
||||
options.onError(error)
|
||||
},
|
||||
onSuccess: async (users, user) => {
|
||||
try {
|
||||
if (users) {
|
||||
queryClient.setQueryData<ShareRow[]>(queryKey.value, await usersToRows(users))
|
||||
} else {
|
||||
upsert(inviteUserToRow(user))
|
||||
}
|
||||
} catch (error) {
|
||||
options.onHydrationError(toError(error))
|
||||
upsert(inviteUserToRow(user))
|
||||
await queryClient.invalidateQueries({ queryKey: queryKey.value })
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const removeMutation = useMutation({
|
||||
mutationFn: async (id: string) => {
|
||||
if (options.actionsLocked.value) {
|
||||
return { user_ids: [], users: [], tokens: 0 } satisfies SharedInstanceUsers
|
||||
}
|
||||
return await remove_shared_instance_users(options.instance.value.id, [id])
|
||||
},
|
||||
onMutate: async (id): Promise<MutationContext> => {
|
||||
const currentKey = queryKey.value
|
||||
await queryClient.cancelQueries({ queryKey: currentKey })
|
||||
const context = {
|
||||
queryKey: currentKey,
|
||||
previousRows: queryClient.getQueryData<ShareRow[]>(currentKey),
|
||||
previousPendingRows: pendingRows.value,
|
||||
}
|
||||
queryClient.setQueryData<ShareRow[]>(currentKey, (currentRows = []) =>
|
||||
currentRows.filter((row) => normalizeInviteKey(row.id) !== normalizeInviteKey(id)),
|
||||
)
|
||||
removePendingRow(id)
|
||||
return context
|
||||
},
|
||||
onError: (error, _id, context) => {
|
||||
restore(context)
|
||||
options.onError(error)
|
||||
},
|
||||
onSuccess: async (users) => {
|
||||
try {
|
||||
queryClient.setQueryData<ShareRow[]>(queryKey.value, await usersToRows(users))
|
||||
} catch (error) {
|
||||
options.onHydrationError(toError(error))
|
||||
await queryClient.invalidateQueries({ queryKey: queryKey.value })
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
function find(id: string, username: string) {
|
||||
const normalizedId = normalizeInviteKey(id)
|
||||
const normalizedUsername = normalizeInviteKey(username)
|
||||
return rows.value.find(
|
||||
(row) =>
|
||||
normalizeInviteKey(row.id) === normalizedId ||
|
||||
normalizeInviteKey(row.username) === normalizedUsername,
|
||||
)
|
||||
}
|
||||
|
||||
function invite(user: InvitePlayersUser) {
|
||||
if (!options.actionsLocked.value && !find(user.id, user.username)) inviteMutation.mutate(user)
|
||||
}
|
||||
|
||||
function remove(id: string) {
|
||||
if (!options.actionsLocked.value) removeMutation.mutate(id)
|
||||
}
|
||||
|
||||
function setPendingRow(user: InvitePlayersUser) {
|
||||
pendingRows.value = { ...pendingRows.value, [user.id]: inviteUserToRow(user) }
|
||||
savePendingRows()
|
||||
}
|
||||
|
||||
function removePendingRow(id: string) {
|
||||
const normalizedId = normalizeInviteKey(id)
|
||||
pendingRows.value = Object.fromEntries(
|
||||
Object.entries(pendingRows.value).filter(
|
||||
([pendingId]) => normalizeInviteKey(pendingId) !== normalizedId,
|
||||
),
|
||||
)
|
||||
savePendingRows()
|
||||
}
|
||||
|
||||
function removePendingRows(ids: string[]) {
|
||||
if (ids.length === 0) return
|
||||
const normalizedIds = new Set(ids.map(normalizeInviteKey))
|
||||
pendingRows.value = Object.fromEntries(
|
||||
Object.entries(pendingRows.value).filter(
|
||||
([id]) => !normalizedIds.has(normalizeInviteKey(id)),
|
||||
),
|
||||
)
|
||||
savePendingRows()
|
||||
}
|
||||
|
||||
function upsert(row: ShareRow) {
|
||||
queryClient.setQueryData<ShareRow[]>(queryKey.value, (currentRows = []) => [
|
||||
row,
|
||||
...currentRows.filter(
|
||||
(existing) => normalizeInviteKey(existing.id) !== normalizeInviteKey(row.id),
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
function restore(context?: MutationContext) {
|
||||
if (!context) return
|
||||
if (context.previousRows === undefined) {
|
||||
queryClient.removeQueries({ queryKey: context.queryKey, exact: true })
|
||||
} else {
|
||||
queryClient.setQueryData(context.queryKey, context.previousRows)
|
||||
}
|
||||
pendingRows.value = context.previousPendingRows
|
||||
savePendingRows()
|
||||
}
|
||||
|
||||
function savePendingRows() {
|
||||
if (typeof localStorage === 'undefined') return
|
||||
const key = pendingRowsStorageKey(options.instance.value.id)
|
||||
const storedRows = Object.values(pendingRows.value)
|
||||
if (storedRows.length === 0) localStorage.removeItem(key)
|
||||
else localStorage.setItem(key, JSON.stringify(storedRows))
|
||||
}
|
||||
|
||||
watch(
|
||||
() => options.instance.value.id,
|
||||
(instanceId) => {
|
||||
pendingRows.value = loadPendingRows(instanceId)
|
||||
},
|
||||
)
|
||||
|
||||
return { rows, query, find, invite, remove }
|
||||
}
|
||||
|
||||
function userEntries(users: SharedInstanceUsers): SharedInstanceUser[] {
|
||||
if (users.users?.length > 0) return users.users
|
||||
return users.user_ids.map((id) => ({
|
||||
id,
|
||||
joined_at: null,
|
||||
join_type: 'invite',
|
||||
last_played: null,
|
||||
}))
|
||||
}
|
||||
|
||||
function parseDate(value?: string | null) {
|
||||
if (!value) return null
|
||||
const date = new Date(value)
|
||||
return Number.isNaN(date.getTime()) ? null : date
|
||||
}
|
||||
|
||||
function inviteUserToRow(user: InvitePlayersUser): ShareRow {
|
||||
return {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
avatarUrl: user.avatarUrl ?? undefined,
|
||||
lastPlayedAt: null,
|
||||
joinedAt: null,
|
||||
method: 'direct',
|
||||
pending: true,
|
||||
}
|
||||
}
|
||||
|
||||
function loadPendingRows(instanceId: string): Record<string, ShareRow> {
|
||||
if (typeof localStorage === 'undefined') return {}
|
||||
try {
|
||||
const stored = localStorage.getItem(pendingRowsStorageKey(instanceId))
|
||||
if (!stored) return {}
|
||||
const rows = JSON.parse(stored) as ShareRow[]
|
||||
return Object.fromEntries(
|
||||
rows.map((row) => [
|
||||
row.id,
|
||||
{ ...row, lastPlayedAt: null, joinedAt: null, pending: true } satisfies ShareRow,
|
||||
]),
|
||||
)
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
function pendingRowsStorageKey(instanceId: string) {
|
||||
return `modrinth:shared-instance-pending-users:${instanceId}`
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
import { injectAuth } from '@modrinth/ui'
|
||||
import { computed, inject, type InjectionKey, provide, type Ref, ref, watch } from 'vue'
|
||||
|
||||
import { useUserQuery } from '@/composables/users/use-user-query'
|
||||
import {
|
||||
getSharedInstanceUnavailableReason,
|
||||
install_get_shared_instance_update_preview,
|
||||
isSharedInstanceUnavailableError,
|
||||
type SharedInstanceUnavailableReason,
|
||||
} from '@/helpers/install'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
export type SharedInstanceManager =
|
||||
| {
|
||||
type: 'user'
|
||||
name: string
|
||||
avatarUrl?: string
|
||||
tintBy: string
|
||||
}
|
||||
| {
|
||||
type: 'server'
|
||||
name: string
|
||||
avatarUrl?: string
|
||||
tintBy: string
|
||||
}
|
||||
|
||||
export function useSharedInstanceState(
|
||||
instance: Ref<GameInstance | undefined>,
|
||||
offline: Ref<boolean>,
|
||||
notifyError: (error: unknown) => void,
|
||||
) {
|
||||
const auth = injectAuth()
|
||||
const updatePreview =
|
||||
ref<Awaited<ReturnType<typeof install_get_shared_instance_update_preview>>>(null)
|
||||
const unavailableReason = ref<SharedInstanceUnavailableReason | null>(null)
|
||||
const availabilityCheckKey = ref<string | null>(null)
|
||||
const availabilityRefresh = ref(0)
|
||||
let availabilityRequestId = 0
|
||||
|
||||
const expectedUserId = computed(() => instance.value?.shared_instance?.linked_user_id ?? null)
|
||||
const wrongAccount = computed(() => {
|
||||
if (auth.isReady && !auth.isReady.value) return false
|
||||
if (!expectedUserId.value) return false
|
||||
return auth.user.value?.id !== expectedUserId.value
|
||||
})
|
||||
const actionsLocked = computed(() => wrongAccount.value)
|
||||
const shareActionsLocked = computed(() => actionsLocked.value || unavailableReason.value !== null)
|
||||
const signedOut = computed(() => !auth.session_token.value)
|
||||
const managerUserId = computed(() => {
|
||||
const attachment = instance.value?.shared_instance
|
||||
if (!attachment) return null
|
||||
if (attachment.role === 'owner') {
|
||||
return actionsLocked.value ? (attachment.linked_user_id ?? null) : null
|
||||
}
|
||||
return attachment.manager_id ?? null
|
||||
})
|
||||
const managerUserQuery = useUserQuery(managerUserId)
|
||||
const manager = computed<SharedInstanceManager | null>(() => {
|
||||
const attachment = instance.value?.shared_instance
|
||||
if (!attachment) return null
|
||||
|
||||
if (attachment.server_manager_name) {
|
||||
return {
|
||||
type: 'server',
|
||||
name: attachment.server_manager_name,
|
||||
avatarUrl: attachment.server_manager_icon_url ?? undefined,
|
||||
tintBy: attachment.server_manager_name,
|
||||
}
|
||||
}
|
||||
|
||||
const user = managerUserQuery.data.value
|
||||
if (!user) return null
|
||||
return {
|
||||
type: 'user',
|
||||
name: user.username,
|
||||
avatarUrl: user.avatar_url ?? undefined,
|
||||
tintBy: user.id,
|
||||
}
|
||||
})
|
||||
const unavailableManager = computed(() => manager.value?.name ?? null)
|
||||
|
||||
function reset() {
|
||||
availabilityRequestId++
|
||||
availabilityCheckKey.value = null
|
||||
updatePreview.value = null
|
||||
unavailableReason.value = null
|
||||
}
|
||||
|
||||
function refreshAvailability() {
|
||||
availabilityRefresh.value++
|
||||
}
|
||||
|
||||
function setUnavailable(reason: SharedInstanceUnavailableReason | null) {
|
||||
availabilityRequestId++
|
||||
availabilityCheckKey.value = null
|
||||
updatePreview.value = null
|
||||
unavailableReason.value = reason
|
||||
}
|
||||
|
||||
async function checkAvailability(instanceId: string, key: string) {
|
||||
const requestId = ++availabilityRequestId
|
||||
try {
|
||||
const preview = await install_get_shared_instance_update_preview(instanceId)
|
||||
if (!isCurrentRequest(requestId, instanceId, key)) return
|
||||
updatePreview.value = preview
|
||||
unavailableReason.value = null
|
||||
} catch (error) {
|
||||
if (!isCurrentRequest(requestId, instanceId, key)) return
|
||||
if (isSharedInstanceUnavailableError(error)) {
|
||||
updatePreview.value = null
|
||||
unavailableReason.value = getSharedInstanceUnavailableReason(error)
|
||||
return
|
||||
}
|
||||
notifyError(error)
|
||||
}
|
||||
}
|
||||
|
||||
function isCurrentRequest(requestId: number, instanceId: string, key: string) {
|
||||
return (
|
||||
requestId === availabilityRequestId &&
|
||||
instance.value?.id === instanceId &&
|
||||
availabilityCheckKey.value === key
|
||||
)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => ({
|
||||
refresh: availabilityRefresh.value,
|
||||
instanceId: instance.value?.id,
|
||||
role: instance.value?.shared_instance?.role,
|
||||
locked: actionsLocked.value,
|
||||
offline: offline.value,
|
||||
signedIn: !!auth.session_token.value,
|
||||
userId: auth.user.value?.id ?? null,
|
||||
authReady: auth.isReady?.value ?? true,
|
||||
}),
|
||||
async ({ instanceId, role, locked, offline, signedIn, userId, authReady }) => {
|
||||
if (
|
||||
!instanceId ||
|
||||
role !== 'member' ||
|
||||
locked ||
|
||||
offline ||
|
||||
!authReady ||
|
||||
!signedIn ||
|
||||
!userId
|
||||
) {
|
||||
availabilityRequestId++
|
||||
availabilityCheckKey.value = null
|
||||
updatePreview.value = null
|
||||
if (instanceId && role) unavailableReason.value = null
|
||||
return
|
||||
}
|
||||
|
||||
const key = `${instanceId}:${userId}`
|
||||
if (availabilityCheckKey.value === key) return
|
||||
availabilityCheckKey.value = key
|
||||
await checkAvailability(instanceId, key)
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
return {
|
||||
actionsLocked,
|
||||
shareActionsLocked,
|
||||
unavailableReason,
|
||||
unavailableManager,
|
||||
manager,
|
||||
updatePreview,
|
||||
expectedUserId,
|
||||
wrongAccount,
|
||||
signedOut,
|
||||
reset,
|
||||
refreshAvailability,
|
||||
setUnavailable,
|
||||
}
|
||||
}
|
||||
|
||||
export type SharedInstanceState = ReturnType<typeof useSharedInstanceState>
|
||||
|
||||
const sharedInstanceStateKey: InjectionKey<SharedInstanceState> = Symbol('shared-instance-state')
|
||||
|
||||
export function provideSharedInstanceState(state: SharedInstanceState) {
|
||||
provide(sharedInstanceStateKey, state)
|
||||
}
|
||||
|
||||
export function injectSharedInstanceState() {
|
||||
const state = inject(sharedInstanceStateKey)
|
||||
if (!state) throw new Error('Shared instance state has not been provided.')
|
||||
return state
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { provideAppBackup } from '@modrinth/ui'
|
||||
import { type MaybeRefOrGetter, toValue } from 'vue'
|
||||
|
||||
import { install_duplicate_instance, installJobInstanceId } from '@/helpers/install'
|
||||
import { edit, list } from '@/helpers/instance'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
export function provideInstanceBackup(instance: MaybeRefOrGetter<GameInstance>) {
|
||||
provideAppBackup({
|
||||
async createBackup() {
|
||||
const source = toValue(instance)
|
||||
const prefix = `${source.name} - Backup #`
|
||||
const existingNumbers = (await list())
|
||||
.filter((candidate) => candidate.name.startsWith(prefix))
|
||||
.map((candidate) => Number.parseInt(candidate.name.slice(prefix.length), 10))
|
||||
.filter(Number.isFinite)
|
||||
const nextNumber = existingNumbers.length ? Math.max(...existingNumbers) + 1 : 1
|
||||
const job = await install_duplicate_instance(source.id)
|
||||
const backupInstanceId = installJobInstanceId(job)
|
||||
if (backupInstanceId) {
|
||||
await edit(backupInstanceId, { name: `${prefix}${nextNumber}` })
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { type AuthFlow, type AuthProvider, type AuthUser, provideAuth } from '@modrinth/ui'
|
||||
import { type AuthProvider, type AuthUser, provideAuth } from '@modrinth/ui'
|
||||
import { computed, type Ref, ref, watchEffect } from 'vue'
|
||||
|
||||
type AppCredentials = {
|
||||
@@ -9,7 +9,7 @@ type AppCredentials = {
|
||||
|
||||
export function setupAuthProvider(
|
||||
credentials: Ref<AppCredentials | null | undefined>,
|
||||
requestSignIn: (redirectPath: string, flow?: AuthFlow) => void | Promise<void>,
|
||||
requestSignIn: (redirectPath: string) => void | Promise<void>,
|
||||
) {
|
||||
const sessionToken = ref<string | null>(null)
|
||||
const user = ref<AuthUser | null>(null)
|
||||
|
||||
@@ -110,7 +110,7 @@ export function setupCreationModal(notificationManager: AbstractWebNotificationM
|
||||
}
|
||||
const preview = await install_get_modpack_preview(location)
|
||||
|
||||
if (preview.unknownFile) {
|
||||
if (preview.unknownFile || preview.externalFilesInModpack.length > 0) {
|
||||
const splitPath = config.modpackFilePath.value.split(/[\\/]/)
|
||||
const fileName = splitPath
|
||||
? splitPath[splitPath.length - 1]
|
||||
@@ -119,6 +119,7 @@ export function setupCreationModal(notificationManager: AbstractWebNotificationM
|
||||
unknownPackWarningModal.value?.show(
|
||||
() => install_create_modpack_instance(location).then(() => undefined),
|
||||
fileName,
|
||||
preview.externalFilesInModpack,
|
||||
)
|
||||
} else {
|
||||
await install_create_modpack_instance(location)
|
||||
|
||||
@@ -41,14 +41,6 @@ export default new createRouter({
|
||||
name: 'ServerManage',
|
||||
component: Hosting.Index,
|
||||
children: [
|
||||
{
|
||||
path: 'play',
|
||||
name: 'ServerManagePlay',
|
||||
component: Hosting.Play,
|
||||
meta: {
|
||||
breadcrumb: [{ name: '?Server' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
name: 'ServerManageOverview',
|
||||
@@ -223,15 +215,6 @@ export default new createRouter({
|
||||
breadcrumb: [{ name: '?Instance', link: '/instance/{id}/' }, { name: 'Worlds' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'share',
|
||||
name: 'InstanceShare',
|
||||
component: Instance.Share,
|
||||
meta: {
|
||||
useRootContext: true,
|
||||
breadcrumb: [{ name: '?Instance', link: '/instance/{id}/' }, { name: 'Share' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
name: 'Mods',
|
||||
|
||||
@@ -17,7 +17,6 @@ export const DEFAULT_FEATURE_FLAGS = {
|
||||
i18n_debug: false,
|
||||
show_instance_play_time: true,
|
||||
advanced_filters_collapsed: true,
|
||||
ServerPlayFrontend: false,
|
||||
}
|
||||
|
||||
export const THEME_OPTIONS = ['dark', 'light', 'oled', 'system'] as const
|
||||
|
||||
+1
-21
@@ -148,11 +148,6 @@ fn main() {
|
||||
"install_get_modpack_preview",
|
||||
"install_create_instance",
|
||||
"install_create_modpack_instance",
|
||||
"install_get_shared_instance_preview",
|
||||
"install_accept_shared_instance_invite",
|
||||
"install_get_shared_instance_update_preview",
|
||||
"install_shared_instance",
|
||||
"install_update_shared_instance",
|
||||
"install_import_instance",
|
||||
"install_duplicate_instance",
|
||||
"install_existing_instance",
|
||||
@@ -207,6 +202,7 @@ fn main() {
|
||||
"instance_install_project_with_dependencies",
|
||||
"instance_switch_project_version_with_dependencies",
|
||||
"instance_add_project_from_path",
|
||||
"instance_is_file_on_modrinth",
|
||||
"instance_toggle_disable_project",
|
||||
"instance_remove_project",
|
||||
"instance_update_managed_modrinth_version",
|
||||
@@ -215,14 +211,6 @@ fn main() {
|
||||
"instance_kill",
|
||||
"instance_edit",
|
||||
"instance_edit_icon",
|
||||
"instance_share_get_users",
|
||||
"instance_share_invite_users",
|
||||
"instance_share_create_invite_link",
|
||||
"instance_share_remove_users",
|
||||
"instance_share_get_publish_preview",
|
||||
"instance_share_publish",
|
||||
"instance_share_unlink",
|
||||
"instance_share_unpublish",
|
||||
"instance_export_mrpack",
|
||||
"instance_get_pack_export_candidates",
|
||||
])
|
||||
@@ -264,14 +252,6 @@ fn main() {
|
||||
DefaultPermissionRule::AllowAllCommands,
|
||||
),
|
||||
)
|
||||
.plugin(
|
||||
"users",
|
||||
InlinedPlugin::new()
|
||||
.commands(&["search_user"])
|
||||
.default_permission(
|
||||
DefaultPermissionRule::AllowAllCommands,
|
||||
),
|
||||
)
|
||||
.plugin(
|
||||
"utils",
|
||||
InlinedPlugin::new()
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"settings:default",
|
||||
"shortcuts:default",
|
||||
"tags:default",
|
||||
"users:default",
|
||||
"utils:default",
|
||||
"ads:default",
|
||||
"friends:default",
|
||||
|
||||
@@ -38,6 +38,10 @@ function installAdsConsentOverlayStyle() {
|
||||
html.modrinth-ads-consent-overlay #modrinth-rail-1 {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.qc-cmp2-close-icon {
|
||||
background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath d='M.5.5l23 23m0-23l-23 23' fill='none' stroke='%23b0bac5' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10'/%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3C/svg%3E") 0% 0% / 66% auto no-repeat !important;
|
||||
}
|
||||
`
|
||||
document.documentElement.appendChild(style)
|
||||
}
|
||||
@@ -186,6 +190,7 @@ function muteVideos() {
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
installAdsConsentOverlayStyle()
|
||||
muteVideos()
|
||||
muteAudioContext()
|
||||
installTcfConsentListener()
|
||||
|
||||
@@ -6,10 +6,6 @@ use theseus::data::ModLoader;
|
||||
use theseus::install::{
|
||||
InstallJobSnapshot, InstallModpackPreview, InstallPostInstallEdit,
|
||||
};
|
||||
use theseus::instance::{
|
||||
SharedInstanceInstallPreview, SharedInstanceInviteInstallPreview,
|
||||
SharedInstanceUpdatePreview,
|
||||
};
|
||||
use theseus::pack::import::ImportLauncherType;
|
||||
use theseus::pack::install_from::CreatePackLocation;
|
||||
use uuid::Uuid;
|
||||
@@ -20,11 +16,6 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
install_get_modpack_preview,
|
||||
install_create_instance,
|
||||
install_create_modpack_instance,
|
||||
install_get_shared_instance_preview,
|
||||
install_accept_shared_instance_invite,
|
||||
install_get_shared_instance_update_preview,
|
||||
install_shared_instance,
|
||||
install_update_shared_instance,
|
||||
install_import_instance,
|
||||
install_duplicate_instance,
|
||||
install_existing_instance,
|
||||
@@ -110,67 +101,6 @@ pub async fn install_create_modpack_instance(
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn install_get_shared_instance_preview(
|
||||
shared_instance_id: String,
|
||||
name: String,
|
||||
) -> Result<SharedInstanceInstallPreview> {
|
||||
Ok(theseus::instance::get_shared_instance_install_preview(
|
||||
&shared_instance_id,
|
||||
name,
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn install_accept_shared_instance_invite(
|
||||
invite_id: String,
|
||||
) -> Result<SharedInstanceInviteInstallPreview> {
|
||||
Ok(
|
||||
theseus::instance::accept_shared_instance_invite_for_install(
|
||||
&invite_id,
|
||||
)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn install_get_shared_instance_update_preview(
|
||||
instance_id: String,
|
||||
) -> Result<Option<SharedInstanceUpdatePreview>> {
|
||||
Ok(
|
||||
theseus::instance::get_shared_instance_update_preview(&instance_id)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn install_shared_instance(
|
||||
shared_instance_id: String,
|
||||
name: String,
|
||||
manager_id: Option<String>,
|
||||
server_manager_name: Option<String>,
|
||||
server_manager_icon_url: Option<String>,
|
||||
instance_icon_url: Option<String>,
|
||||
) -> Result<InstallJobSnapshot> {
|
||||
Ok(theseus::instance::install_shared_instance(
|
||||
&shared_instance_id,
|
||||
name,
|
||||
manager_id,
|
||||
server_manager_name,
|
||||
server_manager_icon_url,
|
||||
instance_icon_url,
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn install_update_shared_instance(
|
||||
instance_id: String,
|
||||
) -> Result<InstallJobSnapshot> {
|
||||
Ok(theseus::instance::update_shared_instance(&instance_id).await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn install_import_instance(
|
||||
launcher_type: ImportLauncherType,
|
||||
|
||||
+25
-133
@@ -10,8 +10,6 @@ use theseus::data::{
|
||||
EditInstance as CoreEditInstance, InstanceInstallCandidate,
|
||||
InstanceInstallTarget, InstanceLaunchOverridesPatch,
|
||||
InstanceLink as CoreInstanceLink, InstanceMetadata, LinkedModpackInfo,
|
||||
SharedInstanceAttachment as CoreSharedInstanceAttachment,
|
||||
SharedInstanceRole,
|
||||
};
|
||||
use theseus::instance::InstallProjectWithDependenciesRequest;
|
||||
use theseus::instance::QuickPlayType;
|
||||
@@ -43,6 +41,7 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
instance_install_project_with_dependencies,
|
||||
instance_switch_project_version_with_dependencies,
|
||||
instance_add_project_from_path,
|
||||
instance_is_file_on_modrinth,
|
||||
instance_toggle_disable_project,
|
||||
instance_remove_project,
|
||||
instance_update_managed_modrinth_version,
|
||||
@@ -51,14 +50,6 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
instance_kill,
|
||||
instance_edit,
|
||||
instance_edit_icon,
|
||||
instance_share_get_users,
|
||||
instance_share_invite_users,
|
||||
instance_share_create_invite_link,
|
||||
instance_share_remove_users,
|
||||
instance_share_get_publish_preview,
|
||||
instance_share_publish,
|
||||
instance_share_unlink,
|
||||
instance_share_unpublish,
|
||||
instance_export_mrpack,
|
||||
instance_get_pack_export_candidates,
|
||||
])
|
||||
@@ -79,7 +70,6 @@ pub struct Instance {
|
||||
pub loader_version: Option<String>,
|
||||
pub groups: Vec<String>,
|
||||
pub link: Option<InstanceLink>,
|
||||
pub shared_instance: Option<SharedInstanceAttachment>,
|
||||
pub update_channel: ReleaseChannel,
|
||||
pub created: chrono::DateTime<chrono::Utc>,
|
||||
pub modified: chrono::DateTime<chrono::Utc>,
|
||||
@@ -125,40 +115,10 @@ pub enum InstanceLink {
|
||||
active_instance_id: Option<String>,
|
||||
},
|
||||
SharedInstance {
|
||||
modpack_project_id: Option<String>,
|
||||
modpack_version_id: Option<String>,
|
||||
shared_instance_id: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Clone)]
|
||||
pub struct SharedInstanceAttachment {
|
||||
pub id: String,
|
||||
pub role: SharedInstanceRole,
|
||||
pub manager_id: Option<String>,
|
||||
pub server_manager_name: Option<String>,
|
||||
pub server_manager_icon_url: Option<String>,
|
||||
pub linked_user_id: Option<String>,
|
||||
pub status: String,
|
||||
pub applied_version: Option<i32>,
|
||||
pub latest_version: Option<i32>,
|
||||
}
|
||||
|
||||
impl From<CoreSharedInstanceAttachment> for SharedInstanceAttachment {
|
||||
fn from(attachment: CoreSharedInstanceAttachment) -> Self {
|
||||
Self {
|
||||
id: attachment.id.to_string(),
|
||||
role: attachment.role,
|
||||
manager_id: attachment.manager_id,
|
||||
server_manager_name: attachment.server_manager_name,
|
||||
server_manager_icon_url: attachment.server_manager_icon_url,
|
||||
linked_user_id: attachment.linked_user_id,
|
||||
status: attachment.status.as_str().to_string(),
|
||||
applied_version: attachment.applied_version,
|
||||
latest_version: attachment.latest_version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct EditInstance {
|
||||
pub name: Option<String>,
|
||||
@@ -241,7 +201,6 @@ impl From<InstanceMetadata> for Instance {
|
||||
loader_version: metadata.applied_content_set.loader_version,
|
||||
groups: metadata.groups,
|
||||
link: InstanceLink::from_core(metadata.link),
|
||||
shared_instance: metadata.shared_instance.map(Into::into),
|
||||
update_channel: metadata.instance.update_channel,
|
||||
created: metadata.instance.created,
|
||||
modified: metadata.instance.modified,
|
||||
@@ -309,13 +268,11 @@ impl InstanceLink {
|
||||
.collect(),
|
||||
active_instance_id: active_instance_id.map(|id| id.to_string()),
|
||||
}),
|
||||
CoreInstanceLink::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
} => Some(Self::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
}),
|
||||
CoreInstanceLink::SharedInstance { shared_instance_id } => {
|
||||
Some(Self::SharedInstance {
|
||||
shared_instance_id: shared_instance_id.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,13 +345,19 @@ impl InstanceLink {
|
||||
})
|
||||
.transpose()?,
|
||||
}),
|
||||
Self::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
} => Ok(CoreInstanceLink::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
}),
|
||||
Self::SharedInstance { shared_instance_id } => {
|
||||
Ok(CoreInstanceLink::SharedInstance {
|
||||
shared_instance_id: shared_instance_id.parse().map_err(
|
||||
|err| {
|
||||
theseus::Error::from(
|
||||
theseus::ErrorKind::InputError(format!(
|
||||
"Invalid shared instance id: {err}"
|
||||
)),
|
||||
)
|
||||
},
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -671,6 +634,11 @@ pub async fn instance_add_project_from_path(
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_is_file_on_modrinth(project_path: &Path) -> Result<bool> {
|
||||
Ok(theseus::instance::is_file_on_modrinth(project_path).await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_toggle_disable_project(
|
||||
instance_id: &str,
|
||||
@@ -776,79 +744,3 @@ pub async fn instance_edit_icon(
|
||||
theseus::instance::edit_icon(instance_id, icon_path).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_get_users(
|
||||
instance_id: &str,
|
||||
) -> Result<theseus::instance::SharedInstanceUsers> {
|
||||
Ok(theseus::instance::get_shared_instance_users(instance_id).await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_invite_users(
|
||||
instance_id: &str,
|
||||
user_ids: Vec<String>,
|
||||
) -> Result<theseus::instance::SharedInstanceUsers> {
|
||||
Ok(
|
||||
theseus::instance::invite_shared_instance_users(instance_id, user_ids)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_create_invite_link(
|
||||
instance_id: &str,
|
||||
max_age_seconds: Option<i32>,
|
||||
max_uses: Option<i32>,
|
||||
replace_invite_id: Option<String>,
|
||||
) -> Result<theseus::instance::SharedInstanceInviteLink> {
|
||||
Ok(theseus::instance::create_shared_instance_invite_link(
|
||||
instance_id,
|
||||
max_age_seconds,
|
||||
max_uses,
|
||||
replace_invite_id,
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_remove_users(
|
||||
instance_id: &str,
|
||||
user_ids: Vec<String>,
|
||||
) -> Result<theseus::instance::SharedInstanceUsers> {
|
||||
Ok(
|
||||
theseus::instance::remove_shared_instance_users(instance_id, user_ids)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_get_publish_preview(
|
||||
instance_id: &str,
|
||||
) -> Result<Option<theseus::instance::SharedInstancePublishPreview>> {
|
||||
Ok(
|
||||
theseus::instance::get_shared_instance_publish_preview(instance_id)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_publish(
|
||||
instance_id: &str,
|
||||
) -> Result<SharedInstanceAttachment> {
|
||||
Ok(theseus::instance::publish_shared_instance(instance_id)
|
||||
.await?
|
||||
.into())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_unlink(instance_id: &str) -> Result<()> {
|
||||
theseus::instance::unlink_shared_instance(instance_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_unpublish(instance_id: &str) -> Result<()> {
|
||||
theseus::instance::unpublish_shared_instance(instance_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+1
-13
@@ -15,7 +15,6 @@ pub mod process;
|
||||
pub mod settings;
|
||||
pub mod shortcuts;
|
||||
pub mod tags;
|
||||
pub mod users;
|
||||
pub mod utils;
|
||||
|
||||
pub mod ads;
|
||||
@@ -86,20 +85,9 @@ macro_rules! impl_serialize {
|
||||
TheseusSerializableError::Theseus(theseus_error) => {
|
||||
$crate::error::display_tracing_error(theseus_error);
|
||||
|
||||
let unavailable_reason = match theseus_error.raw.as_ref() {
|
||||
theseus::ErrorKind::SharedInstanceUnavailable(reason) => Some(reason),
|
||||
_ => None,
|
||||
};
|
||||
let mut state = serializer.serialize_struct(
|
||||
"Theseus",
|
||||
if unavailable_reason.is_some() { 4 } else { 2 },
|
||||
)?;
|
||||
let mut state = serializer.serialize_struct("Theseus", 2)?;
|
||||
state.serialize_field("field_name", "Theseus")?;
|
||||
state.serialize_field("message", &theseus_error.to_string())?;
|
||||
if let Some(reason) = unavailable_reason {
|
||||
state.serialize_field("code", "shared_instance_unavailable")?;
|
||||
state.serialize_field("reason", reason)?;
|
||||
}
|
||||
state.end()
|
||||
}
|
||||
$(
|
||||
|
||||
@@ -22,7 +22,6 @@ pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
|
||||
#[tauri::command]
|
||||
pub async fn modrinth_login<R: Runtime>(
|
||||
app: tauri::AppHandle<R>,
|
||||
flow: mr_auth::ModrinthAuthFlow,
|
||||
) -> Result<ModrinthCredentials> {
|
||||
let (auth_code_recv_socket_tx, auth_code_recv_socket) = oneshot::channel();
|
||||
let auth_code = tokio::spawn(oauth_utils::auth_code_reply::listen(
|
||||
@@ -33,7 +32,7 @@ pub async fn modrinth_login<R: Runtime>(
|
||||
|
||||
let auth_request_uri = format!(
|
||||
"{}?launcher=true&ipver={}&port={}",
|
||||
mr_auth::authenticate_begin_flow(flow),
|
||||
mr_auth::authenticate_begin_flow(),
|
||||
if auth_code_recv_socket.is_ipv4() {
|
||||
"4"
|
||||
} else {
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
use crate::api::Result;
|
||||
use theseus::users::SearchUser;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn search_user(query: &str) -> Result<Vec<SearchUser>> {
|
||||
Ok(theseus::users::search_user(query).await?)
|
||||
}
|
||||
|
||||
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
tauri::plugin::Builder::new("users")
|
||||
.invoke_handler(tauri::generate_handler![search_user])
|
||||
.build()
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user