diff --git a/.agents/skills/api-module/SKILL.md b/.agents/skills/api-module/SKILL.md new file mode 100644 index 0000000000..32cc16756b --- /dev/null +++ b/.agents/skills/api-module/SKILL.md @@ -0,0 +1,23 @@ +--- +name: api-module +description: Add an API endpoint module to packages/api-client from an OpenAPI schema. Use for new backend endpoints, API client modules, or tasks that provide an OpenAPI schema. +--- + +# Add an API Module + +Read the applicable `AGENTS.md` files before you edit code. + +Read [the API module standard](../../../standards/frontend/ADDING_API_MODULES.md) in full. + +1. Identify the OpenAPI schema from the request. If more than one schema is possible, ask the user to select one. +2. Read the schema. Identify each endpoint, HTTP method, request type, response type, and path parameter. +3. Get the service and version from the URL prefix. For example, map `/v3/projects` to `labrinth/v3/`. +4. Define the API types in `types.ts`. Make each type match the schema exactly. +5. Do not change, rename, or remove API fields. +6. Make a module class that extends `AbstractModule`. Implement each endpoint with `this.client.request()` or `this.client.upload()`. +7. Use the request-option pattern from the standard. Do not call `$fetch`, `fetch`, or another HTTP client directly. +8. Add the module to `MODULE_REGISTRY` so the client can instantiate it. +9. Export new service types from the applicable barrel `index.ts`. +10. Check the module paths, registry key, public type exports, and endpoint types. + +Run only the checks that the user or the applicable `AGENTS.md` permits. diff --git a/.agents/skills/api-module/agents/openai.yaml b/.agents/skills/api-module/agents/openai.yaml new file mode 100644 index 0000000000..c8dd768afe --- /dev/null +++ b/.agents/skills/api-module/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Add API Module" + short_description: "Add typed API client modules from OpenAPI" + default_prompt: "Use $api-module to add an API client module from this OpenAPI schema." diff --git a/.agents/skills/cross-platform-pages/SKILL.md b/.agents/skills/cross-platform-pages/SKILL.md new file mode 100644 index 0000000000..2399604821 --- /dev/null +++ b/.agents/skills/cross-platform-pages/SKILL.md @@ -0,0 +1,38 @@ +--- +name: cross-platform-pages +description: Convert a page to the shared Modrinth page system for the website and desktop app. Use for shared layouts, wrapped layouts, or platform dependency-injection contracts. +--- + +# Convert a Cross-Platform Page + +Read the applicable `AGENTS.md` files before you edit code. + +Read these standards in full: + +- [Cross-platform pages](../../../standards/frontend/CROSS_PLATFORM_PAGES.md) +- [Dependency injection](../../../standards/frontend/DEPENDENCY_INJECTION.md) + +1. Identify the target page from the request. +2. Read the page and its route shell. Identify data sources, mutations, navigation, and platform APIs. +3. Use a wrapped layout when both platforms use the same API source and page logic. +4. Use a shared layout when platform data or operations have different implementations. + +For a shared layout: + +1. Define a provider contract for all platform operations. +2. Put common UI and state logic in the shared layout. +3. Put reusable search, filter, and selection logic in local composables. +4. Implement the contract in `apps/frontend/` and `apps/app-frontend/`. +5. Use optional contract fields only for capabilities that are not available on both platforms. + +For a wrapped layout: + +1. Move the page to `packages/ui/src/layouts/wrapped/` and preserve its route structure. +2. Replace platform-only imports with common utilities or provider calls. +3. Make each frontend route shell render the wrapped component. +4. Match primary query options in both route shells when the layout uses `ReadyTransition` and `useReadyState`. +5. Prefetch these queries with `ensureQueryData`, as the standard specifies. + +Check that both route shells resolve their imports. Check that all required provider fields have implementations. + +Run only the checks that the user or the applicable `AGENTS.md` permits. diff --git a/.agents/skills/cross-platform-pages/agents/openai.yaml b/.agents/skills/cross-platform-pages/agents/openai.yaml new file mode 100644 index 0000000000..ad15d4df68 --- /dev/null +++ b/.agents/skills/cross-platform-pages/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Convert Cross-Platform Page" + short_description: "Share pages across the web and desktop app" + default_prompt: "Use $cross-platform-pages to convert this page for the website and desktop app." diff --git a/.agents/skills/figma-mcp/SKILL.md b/.agents/skills/figma-mcp/SKILL.md new file mode 100644 index 0000000000..b6d99eecca --- /dev/null +++ b/.agents/skills/figma-mcp/SKILL.md @@ -0,0 +1,21 @@ +--- +name: figma-mcp +description: Convert a Figma design into a Modrinth Vue page or component. Use when a request provides a Figma URL or asks to implement a Figma layout. +--- + +# Implement a Figma Design + +Read the applicable `AGENTS.md` files before you edit code. + +Read `packages/ui/AGENTS.md` in full. + +1. Load the available Figma design-to-code instructions and follow the MCP tool guidance. +2. Call `get_design_context` first with `clientLanguages: "typescript,html,css"` and `clientFrameworks: "vue"`. +3. Treat the result as reference code and adapt it to the Modrinth codebase. +4. Map Figma color variables to the applicable `surface-*` and `text-*` tokens. Do not use aliased Figma names directly. +5. Reuse applicable components from `packages/ui/src/components/` before creating new ones. Also refer to `standards/frontend/COMPONENT_STRUCTURE.md` +6. Read `packages/assets/styles/variables.scss` when Figma does not supply a required token. +7. Use exact spacing values from the design. +8. Implement the result as a Vue SFC with Tailwind classes and the existing component library. + +Run only the checks that the user or the applicable `AGENTS.md` permits. diff --git a/.agents/skills/figma-mcp/agents/openai.yaml b/.agents/skills/figma-mcp/agents/openai.yaml new file mode 100644 index 0000000000..1a7c61d304 --- /dev/null +++ b/.agents/skills/figma-mcp/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Implement Figma Design" + short_description: "Build Modrinth Vue UI from Figma designs" + default_prompt: "Use $figma-mcp to implement this Figma design as a Modrinth Vue component." diff --git a/.agents/skills/i18n-pass/SKILL.md b/.agents/skills/i18n-pass/SKILL.md new file mode 100644 index 0000000000..05f69de695 --- /dev/null +++ b/.agents/skills/i18n-pass/SKILL.md @@ -0,0 +1,32 @@ +--- +name: i18n-pass +description: Convert hard-coded English text in changed Vue components to the @modrinth/ui localization system. Use for an i18n pass, untranslated-string review, pull request, or component migration. +--- + +# Do an Internationalization Pass + +Read the applicable `AGENTS.md` files before you edit code. + +Read [the internationalization standard](../../../standards/frontend/INTERNATIONALIZATION.md) in full. + +1. Identify the scope from the request. +2. For a pull request, use `gh pr diff ` to identify changed files. +3. For a file path, inspect that file. +4. When the request gives no scope, inspect the current uncommitted diff. +5. Limit the pass to changed `.vue` files. +6. Find user-visible text in templates and scripts. + +Check inner text, `alt`, `placeholder`, `aria-label`, buttons, tooltips, notifications, dropdown labels, and error messages. + +Do not change dynamic expressions, HTML tag names, CSS classes, internal identifiers, or log messages. + +1. Define stable message IDs with `defineMessage` or `defineMessages`. +2. Replace simple text with `formatMessage()` calls. +3. Use `` for text that contains links or markup. +4. Use ICU selections and plurals when grammar depends on a value. +5. Add a space before `}}` when an ICU placeholder ends at the Vue delimiter. +6. Do not change component logic, layout, or reactivity. +7. Do not edit localization JSON files. The user maintains those files. +8. Check the changed templates again for hard-coded English text. + +Run only the checks that the user or the applicable `AGENTS.md` permits. diff --git a/.agents/skills/i18n-pass/agents/openai.yaml b/.agents/skills/i18n-pass/agents/openai.yaml new file mode 100644 index 0000000000..347ef98b2d --- /dev/null +++ b/.agents/skills/i18n-pass/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Run Internationalization Pass" + short_description: "Localize user-visible text in Vue files" + default_prompt: "Use $i18n-pass to localize the user-visible text in these changed Vue files." diff --git a/.agents/skills/review-changelog/SKILL.md b/.agents/skills/review-changelog/SKILL.md new file mode 100644 index 0000000000..5ab041c1c9 --- /dev/null +++ b/.agents/skills/review-changelog/SKILL.md @@ -0,0 +1,40 @@ +--- +name: review-changelog +description: Review the latest packages/blog/changelog.ts entry against the Modrinth changelog standard. Use before a pull request or when asked to review or lint a changelog entry. +--- + +# Review a Changelog Entry + +Read [the changelog standard](../../../standards/maintaining/CHANGELOG.md) in full before the review. + +1. Open `packages/blog/changelog.ts`. +2. Find the first entry in the `VERSIONS` array. +3. If the request names `web`, `hosting`, or `app`, review the latest entry for that product. +4. Otherwise, review the latest entry and all adjacent entries with the same date. + +Check the entry structure: + +- `date` contains a valid ISO 8601 timestamp. +- `product` is `web`, `hosting`, or `app`. +- An `app` entry has a `version` value. +- A `web` or `hosting` entry does not have a `version` value. +- Standard headings are `## Added`, `## Changed`, `## Fixed`, and `## Security`. +- A featured release can use a linked heading. +- Flag the legacy `## Improvements` heading. + +Check each bullet: + +- The voice and tense agree with the section. +- The first verb agrees with the section. +- The bullet describes user-visible behavior, not implementation. +- The bullet identifies the applicable page, tab, modal, or feature. +- The bullet contains one sentence, uses sentence case, and ends with a period. +- Product and UI names use the public labels. +- The bullet does not contain filler, vague intensifiers, apologies, or internal references. +- The bullet is not a duplicate detail of a larger listed change. + +Group findings by entry. For each finding, show the original bullet and a proposed replacement. + +If the entry has no findings, state this result. Do not edit the changelog unless the user asks you to apply fixes. + +When the user asks for fixes, preserve tab indentation and template-literal formatting. diff --git a/.agents/skills/review-changelog/agents/openai.yaml b/.agents/skills/review-changelog/agents/openai.yaml new file mode 100644 index 0000000000..421afc3587 --- /dev/null +++ b/.agents/skills/review-changelog/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Review Changelog" + short_description: "Review changelog entries for style problems" + default_prompt: "Use $review-changelog to review the latest changelog entry." diff --git a/.agents/skills/tanstack-query/SKILL.md b/.agents/skills/tanstack-query/SKILL.md new file mode 100644 index 0000000000..71c3ecc71b --- /dev/null +++ b/.agents/skills/tanstack-query/SKILL.md @@ -0,0 +1,39 @@ +--- +name: tanstack-query +description: Convert Vue server-state code to TanStack Query. Use for useQuery, useMutation, cache invalidation, optimistic updates, or replacement of useAsyncData and manual ref patterns. +--- + +# Convert Data Code to TanStack Query + +Read the applicable `AGENTS.md` files before you edit code. + +Read [the TanStack Query standard](../../../standards/frontend/FETCHING_DATA.md) in full. + +1. Identify the target file from the request. +2. Find `useAsyncData`, `useFetch`, manual API refs, and fetch calls in `onMounted`. +3. Identify mutations that use manual loading, error, or result refs. + +For queries: + +1. Replace manual fetch logic with `useQuery`. +2. Get `api-client` with `injectModrinthClient()`. +3. Use a hierarchical query key with the resource, qualifier, and parameters. +4. Use a computed query key for reactive parameters. +5. Use a computed `enabled` option when the query depends on other data. +6. Use a shared query-option factory when multiple components use the query. + +For mutations: + +1. Replace manual mutation state with `useMutation`. +2. Invalidate or update related query data after success. +3. Use an optimistic update only when the UI needs an immediate response. +4. Cancel the applicable query and save its prior data before an optimistic update. +5. Restore the prior data after an error. Invalidate the query after settlement. + +Remove manual loading and error refs that TanStack Query replaces. Remove obsolete `onMounted` fetch calls. + +Keep Nuxt SSR behavior. Match route-shell prefetch options when `ReadyTransition` and `useReadyState` depend on the query. + +Check query keys, invalidation prefixes, reactive values, and rollback data. + +Run only the checks that the user or the applicable `AGENTS.md` permits. diff --git a/.agents/skills/tanstack-query/agents/openai.yaml b/.agents/skills/tanstack-query/agents/openai.yaml new file mode 100644 index 0000000000..2db5ece878 --- /dev/null +++ b/.agents/skills/tanstack-query/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Migrate to TanStack Query" + short_description: "Migrate Vue server state to TanStack Query" + default_prompt: "Use $tanstack-query to migrate this Vue component to TanStack Query." diff --git a/.claude/skills/api-module/SKILL.md b/.claude/skills/api-module/SKILL.md deleted file mode 100644 index 37b4ac7788..0000000000 --- a/.claude/skills/api-module/SKILL.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: api-module -description: Add a new API endpoint module to packages/api-client from an OpenAPI schema. Use when adding new backend endpoints, creating API client modules, or when an openapi.yml is provided. -argument-hint: ---- - -Refer to the standard: @standards/frontend/ADDING_API_MODULES.md - -## Steps - -1. **Read the OpenAPI schema** at `$ARGUMENTS` — identify the endpoints, request/response shapes, and path parameters. -2. **Read the standard above** for naming conventions, type rules, and the module registration pattern. -3. **Determine the service and version** — the URL path prefix tells you which service directory and version namespace to use (e.g. `/v3/projects` → `labrinth/v3/`). -4. **Define types in `types.ts`** — types must match the API response 1:1. Use the OpenAPI schema as the source of truth. Do not reshape or rename fields. -5. **Create the module class** — extend `BaseModule`, implement each endpoint as a method. Use the correct HTTP verb and request options pattern from the standard. -6. **Register in `MODULE_REGISTRY`** — add the module entry so it's auto-instantiated on the client. -7. **Export types** from the service's barrel `index.ts`. -8. **Verify** — check that the module compiles and the types are accessible from `@modrinth/api-client`. diff --git a/.claude/skills/cross-platform-pages/SKILL.md b/.claude/skills/cross-platform-pages/SKILL.md deleted file mode 100644 index 6558eed3c3..0000000000 --- a/.claude/skills/cross-platform-pages/SKILL.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: cross-platform-pages -description: Convert a page to the cross-platform page system so it works in both the website and the desktop app. Use when moving a page into packages/ui/src/layouts/, creating shared or wrapped layouts, or setting up DI contracts for platform abstraction. -argument-hint: ---- - -Refer to the standards: @standards/frontend/CROSS_PLATFORM_PAGES.md and @standards/frontend/DEPENDENCY_INJECTION.md - -## Steps - -1. **Read the target page** at `$ARGUMENTS` and understand its data sources, mutations, and navigation. -2. **Read the standards above** to understand the shared vs wrapped distinction and the DI pattern. -3. **Decide the category:** - - **Wrapped** (`layouts/wrapped/`) — if the page uses the same API source on both platforms (e.g. web requests, not Tauri plugins). Just move the page component into `packages/ui` and import it from both frontends. - - **Shared** (`layouts/shared/`) — if the page has different data-fetching logic per platform (e.g. website uses `api-client`, app uses Tauri `invoke`). Requires a DI contract. -4. **For shared layouts:** - - Define a DI contract interface in `providers/` capturing all platform-specific operations. - - Create the layout component that injects the context and handles all UI logic. - - Extract reusable stateful logic (search, filtering, selection) into `composables/`. - - Implement the contract separately in each frontend (`apps/frontend/`, `apps/app-frontend/`). -5. **For wrapped pages:** - - Move the page component into `packages/ui/src/layouts/wrapped/` matching the route structure. - - Replace any platform-specific imports with shared utilities. - - Import and render the wrapped page from both frontends as a simple component. - - If the layout uses TanStack Query for initial route paint with `ReadyTransition` / `useReadyState`, each platform route shell must call `ensureQueryData` for those queries with matching keys and fetchers — see **Platform route shells: prefetch with `ensureQueryData`** in `standards/frontend/CROSS_PLATFORM_PAGES.md`. -6. **Verify** the page renders correctly by checking for missing imports and that all DI contracts are satisfied. diff --git a/.claude/skills/figma-mcp/SKILL.md b/.claude/skills/figma-mcp/SKILL.md deleted file mode 100644 index defabf8d2e..0000000000 --- a/.claude/skills/figma-mcp/SKILL.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: figma-mcp -description: Use the Figma MCP server to translate a Figma design into a Vue page or component layout. Use when the user provides a Figma URL, asks to implement a design, or wants to draft a page layout from Figma. -argument-hint: ---- - -Refer to the standard: @standards/frontend/FIGMA_MCP_USAGE.md -Also read @packages/ui/CLAUDE.md for color token mapping and component conventions. - -## Steps - -1. **Parse the Figma URL** from `$ARGUMENTS` — extract the `fileKey` and `nodeId`. Convert `-` to `:` in the node ID. -2. **Read the standards above** for the available tools, adaptation rules, and color usage. -3. **Call `get_design_context`** with the extracted `nodeId` and `fileKey`, using `clientLanguages: "typescript,html,css"` and `clientFrameworks: "vue"`. This is always the first tool to call. -5. **Adapt the output to the Modrinth codebase:** - - Map Figma color variables to `surface-*` / `text-*` tokens — never use Figma's aliased names directly. - - Check `packages/ui/src/components/` for existing components that match elements in the design (buttons, cards, modals, inputs, etc.). - - Check `packages/assets/styles/variables.scss` for tokens not exposed in Figma. - - Match spacing values exactly from the design. -6. **Use `get_screenshot`** if you need a closer visual reference of specific nodes. -7. **Use `get_variable_defs`** to verify which design tokens are applied to ambiguous elements. -8. **Build the component** as a Vue SFC using Tailwind classes and the project's existing component library. diff --git a/.claude/skills/i18n-pass/SKILL.md b/.claude/skills/i18n-pass/SKILL.md deleted file mode 100644 index 7edd69996c..0000000000 --- a/.claude/skills/i18n-pass/SKILL.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: i18n-pass -description: Perform an i18n localization pass on changed files or a pull request, converting hard-coded English strings to the @modrinth/ui i18n system. Use when internationalizing a set of changes, reviewing a PR for untranslated strings, or converting a specific component. -argument-hint: [file-path-or-pr-number] ---- - -Refer to the standard: @standards/frontend/INTERNATIONALIZATION.md - -## Steps - -1. **Identify the scope of changes:** - - If `$ARGUMENTS` is a PR number, run `gh pr diff $ARGUMENTS` to get the changed files. - - If `$ARGUMENTS` is a file path, use that directly. - - If no argument, check `git diff` for uncommitted changes. -2. **Read the standard above** for the message definition pattern, ICU format rules, and `IntlFormatted` usage. -3. **Filter to Vue SFCs** — only `.vue` files need i18n passes. Skip non-component files. -4. **For each file, scan for hard-coded strings:** - - `
- - Get support - - - - + Get support +
@@ -145,10 +146,10 @@ import { UserPlusIcon, XIcon, } from '@modrinth/assets' +import { Button, IconButton } from '@modrinth/ui' import { AutoLink, Avatar, - ButtonStyled, defineMessages, type SortDirection, StyledInput, @@ -161,6 +162,7 @@ import { } from '@modrinth/ui' import { computed, ref, watch } from 'vue' +import { injectSharedInstanceManagement } from './shared-instance-management-context' import { type MethodFilter, methodLabels, @@ -169,19 +171,15 @@ import { type ShareTableColumn, } from './shared-instance-share-types' -const props = defineProps<{ - rows: ShareRow[] - actionsLocked?: boolean - inviteDisabled?: boolean - invitePending?: boolean - pushUpdateDisabled?: boolean - pushUpdatePending?: boolean -}>() -const emit = defineEmits<{ - invite: [event: MouseEvent] - remove: [row: ShareRow] - 'push-update': [event: MouseEvent] -}>() +const management = injectSharedInstanceManagement() +const { + rows, + actionsLocked, + inviteDisabled, + invitePending, + pushUpdateDisabled, + pushUpdatePending, +} = management const search = ref('') const methodFilter = ref('all') const sortColumn = ref('joined') @@ -194,7 +192,7 @@ const methodFilterOptions: Array<{ id: ShareMethod; label: string }> = [ { id: 'direct', label: methodLabels.direct }, { id: 'link', label: methodLabels.link }, ] -const hasMultipleMethods = computed(() => new Set(props.rows.map((row) => row.method)).size > 1) +const hasMultipleMethods = computed(() => new Set(rows.value.map((row) => row.method)).size > 1) const columns = computed[]>(() => { const result: TableColumn[] = [ { @@ -230,7 +228,7 @@ const columns = computed[]>(() => { cellClass: 'whitespace-nowrap !px-2', }, ] - if (!props.actionsLocked) + if (!actionsLocked.value) result.push({ key: 'actions', label: 'Actions', @@ -243,7 +241,7 @@ const columns = computed[]>(() => { }) const filteredRows = computed(() => { const query = search.value.trim().toLowerCase() - return props.rows.filter((row) => { + return rows.value.filter((row) => { if (methodFilter.value !== 'all' && row.method !== methodFilter.value) return false if (!query) return true return [ @@ -285,7 +283,7 @@ function filterClass(active: boolean) { return [ 'cursor-pointer rounded-full border border-solid px-3 py-1.5 text-base font-semibold leading-5 transition-all duration-100 active:scale-[0.97]', active - ? 'border-green bg-brand-highlight text-brand' + ? 'border-brand bg-brand-highlight text-brand' : 'border-surface-5 bg-surface-4 text-primary hover:bg-surface-5', ] } diff --git a/apps/app-frontend/src/pages/instance/share/shared-instance-remove-member-modal.vue b/apps/app-frontend/src/pages/instance/share/shared-instance-remove-member-modal.vue index 1f7983dcdd..96d67be712 100644 --- a/apps/app-frontend/src/pages/instance/share/shared-instance-remove-member-modal.vue +++ b/apps/app-frontend/src/pages/instance/share/shared-instance-remove-member-modal.vue @@ -32,16 +32,12 @@
- - + +
@@ -52,7 +48,7 @@ import { UserXIcon, XIcon } from '@modrinth/assets' import { Admonition, Avatar, - ButtonStyled, + Button, commonMessages, defineMessages, NewModal, diff --git a/apps/app-frontend/src/pages/instance/share/use-shared-instance-members.ts b/apps/app-frontend/src/pages/instance/share/use-shared-instance-members.ts index 801f9a3552..cd0c43304c 100644 --- a/apps/app-frontend/src/pages/instance/share/use-shared-instance-members.ts +++ b/apps/app-frontend/src/pages/instance/share/use-shared-instance-members.ts @@ -12,13 +12,14 @@ import { } from '@/helpers/instance' import type { GameInstance } from '@/helpers/types' +import { instanceKeys } from '../query-options' import { normalizeInviteKey, SHARED_INSTANCE_USER_LIMIT, type ShareRow, } from './shared-instance-share-types' -type MembersQueryKey = readonly ['sharedInstanceUsers', string] +type MembersQueryKey = ReturnType type OptimisticChange = { queryKey: MembersQueryKey @@ -48,7 +49,7 @@ export function useSharedInstanceMembers(options: { onError: (error: unknown) => void }) { const queryClient = useQueryClient() - const queryKey = computed(() => ['sharedInstanceUsers', options.instance.value.id] as const) + const queryKey = computed(() => instanceKeys.sharedMembers(options.instance.value.id)) const invitingUserIds = new Set() const removingUserIds = new Set() const exclusiveMutationPending = ref(false) diff --git a/apps/app-frontend/src/pages/instance/shared-instance-context.ts b/apps/app-frontend/src/pages/instance/shared-instance-context.ts new file mode 100644 index 0000000000..57c424d5ca --- /dev/null +++ b/apps/app-frontend/src/pages/instance/shared-instance-context.ts @@ -0,0 +1,184 @@ +import { createContext, injectAuth } from '@modrinth/ui' +import { useQuery, useQueryClient } from '@tanstack/vue-query' +import { computed, 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 { can_current_user_use_shared_instances } from '@/helpers/instance' +import type { GameInstance } from '@/helpers/types' + +import { instanceKeys } from './query-options' + +export type SharedInstanceManager = + | { + type: 'user' + name: string + avatarUrl?: string + tintBy: string + } + | { + type: 'server' + name: string + avatarUrl?: string + tintBy: string + } + +export function createSharedInstanceContext( + instance: Ref, + offline: Ref, + notifyError: (error: unknown) => void, +) { + const auth = injectAuth() + const queryClient = useQueryClient() + const forcedUnavailableReason = ref(null) + + 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 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(() => { + 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) + + const eligibilityQuery = useQuery({ + queryKey: computed(() => instanceKeys.sharedEligibility(auth.user.value?.id)), + queryFn: can_current_user_use_shared_instances, + enabled: () => !!auth.session_token.value && !!auth.user.value?.id, + retry: false, + staleTime: Infinity, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }) + const currentUserCanUseSharedInstances = computed( + () => !auth.session_token.value || eligibilityQuery.data.value !== false, + ) + + const updatePreviewQuery = useQuery({ + queryKey: computed(() => + instanceKeys.sharedUpdatePreview(instance.value?.id ?? '', auth.user.value?.id), + ), + queryFn: () => install_get_shared_instance_update_preview(instance.value!.id), + enabled: computed( + () => + !!instance.value?.id && + instance.value.install_stage === 'installed' && + !!instance.value.shared_instance && + !actionsLocked.value && + !offline.value && + (auth.isReady?.value ?? true) && + !!auth.session_token.value && + !!auth.user.value?.id, + ), + retry: false, + staleTime: 30_000, + refetchOnWindowFocus: false, + }) + + watch(updatePreviewQuery.data, (preview) => { + if (preview !== undefined) forcedUnavailableReason.value = null + }) + watch(updatePreviewQuery.error, (error) => { + if (!error) return + if (isSharedInstanceUnavailableError(error)) { + forcedUnavailableReason.value = getSharedInstanceUnavailableReason(error) + } else { + notifyError(error) + } + }) + + const unavailableReason = computed(() => forcedUnavailableReason.value) + const shareActionsLocked = computed(() => actionsLocked.value || unavailableReason.value !== null) + const updatePreview = computed(() => + unavailableReason.value ? null : (updatePreviewQuery.data.value ?? null), + ) + const lastUpdateCheckAt = computed(() => updatePreviewQuery.dataUpdatedAt.value || undefined) + + watch( + () => instance.value?.id, + () => { + forcedUnavailableReason.value = null + }, + ) + + async function refreshAvailability() { + forcedUnavailableReason.value = null + if (!instance.value?.id) return + await queryClient.invalidateQueries({ + queryKey: instanceKeys.sharedUpdatePreview(instance.value.id, auth.user.value?.id), + }) + } + + async function refreshUpdatePreview() { + forcedUnavailableReason.value = null + if (!instance.value?.id || !auth.user.value?.id) return null + const result = await updatePreviewQuery.refetch({ throwOnError: true }) + return result.data ?? null + } + + function setUnavailable(reason: SharedInstanceUnavailableReason | null) { + forcedUnavailableReason.value = reason + } + + return { + actionsLocked, + shareActionsLocked, + unavailableReason, + unavailableManager, + manager, + updatePreview, + lastUpdateCheckAt, + expectedUserId, + wrongAccount, + signedOut, + eligibilityQuery, + currentUserCanUseSharedInstances, + refreshAvailability, + refreshUpdatePreview, + setUnavailable, + } +} + +export type SharedInstanceContext = ReturnType + +export const [injectSharedInstance, provideSharedInstance] = createContext( + 'InstancePage', + 'sharedInstance', +) diff --git a/apps/app-frontend/src/pages/instance/use-shared-instance-state.ts b/apps/app-frontend/src/pages/instance/use-shared-instance-state.ts deleted file mode 100644 index 408bd3c2cc..0000000000 --- a/apps/app-frontend/src/pages/instance/use-shared-instance-state.ts +++ /dev/null @@ -1,228 +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, - offline: Ref, - notifyError: (error: unknown) => void, -) { - const auth = injectAuth() - const updatePreview = - ref>>(null) - const updatePreviewLoaded = ref(false) - const unavailableReason = ref(null) - const availabilityCheckKey = ref(null) - const availabilityRefresh = ref(0) - let availabilityRequestId = 0 - let availabilityRequest: { - key: string - promise: Promise<{ - preview: Awaited> - error: unknown | null - }> - } | null = null - - 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(() => { - 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++ - availabilityRequest = null - availabilityCheckKey.value = null - updatePreview.value = null - updatePreviewLoaded.value = false - unavailableReason.value = null - } - - function refreshAvailability() { - availabilityCheckKey.value = null - updatePreviewLoaded.value = false - availabilityRefresh.value++ - } - - function setUnavailable(reason: SharedInstanceUnavailableReason | null) { - availabilityRequestId++ - availabilityRequest = null - availabilityCheckKey.value = null - updatePreview.value = null - updatePreviewLoaded.value = false - unavailableReason.value = reason - } - - async function checkAvailability(instanceId: string, key: string, throwError = false) { - const requestId = ++availabilityRequestId - let request = availabilityRequest - if (!request || request.key !== key) { - const promise = install_get_shared_instance_update_preview(instanceId).then( - (preview) => ({ preview, error: null }), - (error: unknown) => ({ preview: null, error }), - ) - request = { key, promise } - availabilityRequest = request - void promise.finally(() => { - if (availabilityRequest?.promise === promise) availabilityRequest = null - }) - } - - const result = await request.promise - if (!isCurrentRequest(requestId, instanceId, key)) return null - - if (result.error !== null) { - updatePreviewLoaded.value = false - if (isSharedInstanceUnavailableError(result.error)) { - updatePreview.value = null - unavailableReason.value = getSharedInstanceUnavailableReason(result.error) - } else if (!throwError) { - notifyError(result.error) - } - - if (throwError) throw result.error - return null - } - - updatePreview.value = result.preview - updatePreviewLoaded.value = true - unavailableReason.value = null - return result.preview - } - - async function refreshUpdatePreview() { - const instanceId = instance.value?.id - const userId = auth.user.value?.id - if (!instanceId || !userId) return null - - const key = `${instanceId}:${userId}` - availabilityCheckKey.value = key - return await checkAvailability(instanceId, key, true) - } - - 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 || locked || offline || !authReady || !signedIn || !userId) { - availabilityRequestId++ - availabilityRequest = null - availabilityCheckKey.value = null - updatePreview.value = null - updatePreviewLoaded.value = false - 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, - refreshUpdatePreview, - setUnavailable, - } -} - -export type SharedInstanceState = ReturnType - -const sharedInstanceStateKey: InjectionKey = 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 -} diff --git a/apps/app-frontend/src/pages/instance/Worlds.vue b/apps/app-frontend/src/pages/instance/worlds/index.vue similarity index 86% rename from apps/app-frontend/src/pages/instance/Worlds.vue rename to apps/app-frontend/src/pages/instance/worlds/index.vue index 4a5bd6192d..3539b608ca 100644 --- a/apps/app-frontend/src/pages/instance/Worlds.vue +++ b/apps/app-frontend/src/pages/instance/worlds/index.vue @@ -35,23 +35,14 @@ " />
- - - - - - + +
@@ -72,16 +63,17 @@ {{ option.label }}
- - - +
diff --git a/apps/app-frontend/src/pages/library/Index.vue b/apps/app-frontend/src/pages/library/Index.vue index a8510edcd4..87a15405de 100644 --- a/apps/app-frontend/src/pages/library/Index.vue +++ b/apps/app-frontend/src/pages/library/Index.vue @@ -1,11 +1,11 @@ diff --git a/apps/frontend/src/components/ui/AuthorizationCard.vue b/apps/frontend/src/components/ui/AuthorizationCard.vue index 58eee3d8cb..37507e272b 100644 --- a/apps/frontend/src/components/ui/AuthorizationCard.vue +++ b/apps/frontend/src/components/ui/AuthorizationCard.vue @@ -40,12 +40,10 @@
- - - +
@@ -82,7 +80,7 @@ import type { Labrinth } from '@modrinth/api-client' import { BadgeCheckIcon, CheckIcon, IssuesIcon, XCircleIcon } from '@modrinth/assets' import { Avatar, - ButtonStyled, + Button, commonMessages, defineMessages, IntlFormatted, diff --git a/apps/frontend/src/components/ui/Chips.vue b/apps/frontend/src/components/ui/Chips.vue deleted file mode 100644 index 17905aa13c..0000000000 --- a/apps/frontend/src/components/ui/Chips.vue +++ /dev/null @@ -1,103 +0,0 @@ - - - - - diff --git a/apps/frontend/src/components/ui/ConfirmTransferOrgModal.vue b/apps/frontend/src/components/ui/ConfirmTransferOrgModal.vue index e4f62b43f0..606be33b05 100644 --- a/apps/frontend/src/components/ui/ConfirmTransferOrgModal.vue +++ b/apps/frontend/src/components/ui/ConfirmTransferOrgModal.vue @@ -57,18 +57,14 @@
@@ -76,7 +72,7 @@ diff --git a/apps/frontend/src/components/ui/NotificationItem.vue b/apps/frontend/src/components/ui/NotificationItem.vue index 1bbac8bf38..4f3cfa001b 100644 --- a/apps/frontend/src/components/ui/NotificationItem.vue +++ b/apps/frontend/src/components/ui/NotificationItem.vue @@ -46,18 +46,18 @@ class="flex flex-wrap items-center gap-3" :class="{ 'gap-2': compact }" > - - - - - - + +
+ + + +
+
+
+ - - - -
-
-
- - - - +
- - - - Open link - - - - - - - - + + + Open link + + +
@@ -390,10 +399,12 @@ import { } from '@modrinth/assets' import { Avatar, - ButtonStyled, + Button, + ButtonLink, Categories, CopyCode, DoubleIcon, + IconButton, injectModrinthClient, injectNotificationManager, ProjectStatusBadge, diff --git a/apps/frontend/src/components/ui/OptionGroup.vue b/apps/frontend/src/components/ui/OptionGroup.vue deleted file mode 100644 index 36313921ef..0000000000 --- a/apps/frontend/src/components/ui/OptionGroup.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - - - diff --git a/apps/frontend/src/components/ui/OrganizationPageHeader.vue b/apps/frontend/src/components/ui/OrganizationPageHeader.vue index c5f74542df..6063423a50 100644 --- a/apps/frontend/src/components/ui/OrganizationPageHeader.vue +++ b/apps/frontend/src/components/ui/OrganizationPageHeader.vue @@ -38,21 +38,19 @@ @@ -68,18 +66,17 @@ import { SettingsIcon, UsersIcon, } from '@modrinth/assets' +import { ButtonLink, TeleportOverflowMenu } from '@modrinth/ui' import { Avatar, - ButtonStyled, commonMessages, defineMessages, + type OverflowMenuOption, PageHeader, PageHeaderActions, PageHeaderBadgeItem, PageHeaderMetadata, PageHeaderMetadataNumberItem, - TeleportOverflowMenu, - type TeleportOverflowMenuItem, useFormatNumber, useVIntl, } from '@modrinth/ui' @@ -135,7 +132,7 @@ const emit = defineEmits<{ const { formatMessage } = useVIntl() const formatNumber = useFormatNumber() -const moreActions = computed(() => [ +const moreActions = computed(() => [ { id: 'manage-projects', label: formatMessage(messages.manageProjects), @@ -143,10 +140,7 @@ const moreActions = computed(() => [ action: () => emit('manageProjects'), shown: props.canManage, }, - { - divider: true, - shown: props.canManage, - }, + { type: 'divider', shown: props.canManage }, { id: 'copy-id', label: formatMessage(commonMessages.copyIdButton), diff --git a/apps/frontend/src/components/ui/OrganizationProjectTransferModal.vue b/apps/frontend/src/components/ui/OrganizationProjectTransferModal.vue index 6f66486fd0..46524dbff5 100644 --- a/apps/frontend/src/components/ui/OrganizationProjectTransferModal.vue +++ b/apps/frontend/src/components/ui/OrganizationProjectTransferModal.vue @@ -65,38 +65,37 @@
- - - +
+ + diff --git a/apps/frontend/src/components/ui/moderation/SharedInstanceReportContext.vue b/apps/frontend/src/components/ui/moderation/SharedInstanceReportContext.vue index 3f3b0d9ad5..e3839dd4a6 100644 --- a/apps/frontend/src/components/ui/moderation/SharedInstanceReportContext.vue +++ b/apps/frontend/src/components/ui/moderation/SharedInstanceReportContext.vue @@ -11,13 +11,13 @@ import { UsersIcon, VersionIcon, } from '@modrinth/assets' +import { Button, IconButton } from '@modrinth/ui' import { Avatar, - ButtonStyled, ConfirmLeaveModal, type ContentItem, injectModrinthClient, - ModpackContentModal, + ManagedContentModal, Table, type TableColumn, useFormatDateTime, @@ -76,7 +76,7 @@ const emit = defineEmits<{ contentError: [error: unknown] }>() -const contentModal = ref | null>(null) +const contentModal = ref | null>(null) const banModal = ref | null>(null) const client = injectModrinthClient() const contentByVersion = new Map() @@ -322,12 +322,14 @@ function formattedLoader(version: SharedInstanceReportVersion) { - - - + @@ -363,15 +365,14 @@ function formattedLoader(version: SharedInstanceReportVersion) { {{ instance.member_count === 1 ? 'member' : 'members' }} - - - + + + @@ -392,20 +393,24 @@ function formattedLoader(version: SharedInstanceReportVersion) { launching them. - - - + - {{ checklistTitleText }} - - diff --git a/apps/frontend/src/components/ui/moderation/checklist/checklist-context.ts b/apps/frontend/src/components/ui/moderation/checklist/checklist-context.ts index e5271651d6..b3d40f8d62 100644 --- a/apps/frontend/src/components/ui/moderation/checklist/checklist-context.ts +++ b/apps/frontend/src/components/ui/moderation/checklist/checklist-context.ts @@ -1,11 +1,5 @@ -import type { IdentifiedNodeBuilder, NodeState } from '@modrinth/moderation' -import type { ComputedRef, InjectionKey, Ref } from 'vue' - -export interface ActiveAction { - node: IdentifiedNodeBuilder - state: Record - statePath: string[] -} +import type { ActiveAction, NodeState } from '@modrinth/moderation/src/types/node' +import type { InjectionKey, Ref } from 'vue' export interface LiveNode { isActive: boolean @@ -17,7 +11,5 @@ export interface LiveNode { activeActions: ActiveAction[] } -export const NODE_META_KEY: InjectionKey>> = - Symbol('nodeMeta') export const STATE_KEY: InjectionKey>>> = Symbol('checklistState') diff --git a/apps/frontend/src/components/ui/moderation/settings/ModerationKeybind.vue b/apps/frontend/src/components/ui/moderation/settings/ModerationKeybind.vue index 3f13325e88..377c658252 100644 --- a/apps/frontend/src/components/ui/moderation/settings/ModerationKeybind.vue +++ b/apps/frontend/src/components/ui/moderation/settings/ModerationKeybind.vue @@ -2,15 +2,24 @@
+ {{ props.title }} - - - + + +
+ + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/AiDisclosureCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/AiDisclosureCard.vue new file mode 100644 index 0000000000..118b45c5c5 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/AiDisclosureCard.vue @@ -0,0 +1,125 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/ArchivedDisclosureCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/ArchivedDisclosureCard.vue new file mode 100644 index 0000000000..feeb534347 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/ArchivedDisclosureCard.vue @@ -0,0 +1,86 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/DerivativeDisclosureCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/DerivativeDisclosureCard.vue new file mode 100644 index 0000000000..2ab6664a59 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/DerivativeDisclosureCard.vue @@ -0,0 +1,179 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/DisclosureToggleCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/DisclosureToggleCard.vue new file mode 100644 index 0000000000..feeb1f4a39 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/DisclosureToggleCard.vue @@ -0,0 +1,146 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/DisclosureUpdatedBy.vue b/apps/frontend/src/components/ui/project-settings/disclosures/DisclosureUpdatedBy.vue new file mode 100644 index 0000000000..cf1be3b624 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/DisclosureUpdatedBy.vue @@ -0,0 +1,74 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/PaidFeaturesDisclosureCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/PaidFeaturesDisclosureCard.vue new file mode 100644 index 0000000000..2fc186bea6 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/PaidFeaturesDisclosureCard.vue @@ -0,0 +1,100 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/PhotosensitivityDisclosureCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/PhotosensitivityDisclosureCard.vue new file mode 100644 index 0000000000..4224a04205 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/PhotosensitivityDisclosureCard.vue @@ -0,0 +1,68 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/SystemInteractionsDisclosureCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/SystemInteractionsDisclosureCard.vue new file mode 100644 index 0000000000..d3466a0a4c --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/SystemInteractionsDisclosureCard.vue @@ -0,0 +1,69 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/TelemetryDisclosureCard.vue b/apps/frontend/src/components/ui/project-settings/disclosures/TelemetryDisclosureCard.vue new file mode 100644 index 0000000000..d369f4217d --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/TelemetryDisclosureCard.vue @@ -0,0 +1,132 @@ + + + diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/form.ts b/apps/frontend/src/components/ui/project-settings/disclosures/form.ts new file mode 100644 index 0000000000..0e7d7324a9 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/form.ts @@ -0,0 +1,322 @@ +import type { Labrinth } from '@modrinth/api-client' +import { + isActiveDisclosure, + isDisclosureCompatibleWithProjectTypes, + PROJECT_DISCLOSURE_TYPES, +} from '@modrinth/ui' + +import type { + DisclosureFormState, + DisclosureLockStatus, + DisclosureOf, + DisclosureType, + NoteDisclosure, + ProjectDisclosure, + ProjectDisclosureData, +} from './types' + +function findDisclosure( + disclosures: ProjectDisclosureData[], + type: T, +): DisclosureOf | undefined { + return disclosures.find((disclosure): disclosure is DisclosureOf => disclosure.type === type) +} + +type NoteDisclosureType = 'advertisements' | 'epilepsy_triggers' | 'archived' + +function createNoteModel( + disclosures: ProjectDisclosureData[], + type: NoteDisclosureType, +): NoteDisclosure { + const disclosure = findDisclosure(disclosures, type) + return { + enabled: isActiveDisclosure(disclosure), + note: disclosure?.note ?? '', + } +} + +function nonemptyOrPlaceholder(values: string[]): string[] { + return values.length > 0 ? [...values] : [''] +} + +function createLockStatuses( + disclosures: ProjectDisclosureData[], +): Record { + const lockStatuses = Object.fromEntries( + PROJECT_DISCLOSURE_TYPES.map((type) => [type, 'unlocked']), + ) as Record + + for (const disclosure of disclosures) { + lockStatuses[disclosure.type] = disclosure.lock_status + } + + return lockStatuses +} + +export function disclosuresToForm(disclosures: ProjectDisclosureData[]): DisclosureFormState { + const ai = findDisclosure(disclosures, 'ai_content') + const paidFeatures = findDisclosure(disclosures, 'paid_features') + const telemetry = findDisclosure(disclosures, 'telemetry') + const derivative = findDisclosure(disclosures, 'derivative_work') + const systemInteractions = findDisclosure(disclosures, 'system_interactions') + + return { + ai: { + enabled: isActiveDisclosure(ai), + uses: ai ? [...(ai.uses ?? [])] : [], + note: ai?.note ?? '', + }, + advertising: createNoteModel(disclosures, 'advertisements'), + paidFeatures: { + enabled: isActiveDisclosure(paidFeatures), + features: paidFeatures ? nonemptyOrPlaceholder(paidFeatures.features) : [], + }, + telemetry: { + enabled: isActiveDisclosure(telemetry), + consent: telemetry?.consent ?? 'opt_in', + entries: telemetry ? nonemptyOrPlaceholder(telemetry.data_collected) : [], + }, + derivative: { + enabled: isActiveDisclosure(derivative), + sources: derivative ? derivative.sources.map((source) => ({ ...source })) : [], + }, + photosensitivity: createNoteModel(disclosures, 'epilepsy_triggers'), + systemInteractions: { + enabled: isActiveDisclosure(systemInteractions), + note: systemInteractions?.note ?? '', + interactions: systemInteractions ? [...systemInteractions.interactions] : [], + }, + archived: createNoteModel(disclosures, 'archived'), + lockStatuses: createLockStatuses(disclosures), + } +} + +export function findDisclosureData( + disclosures: ProjectDisclosureData[] | undefined, + type: T, +): DisclosureOf | undefined { + if (!disclosures) return undefined + return findDisclosure(disclosures, type) +} + +export function formToDisclosure( + form: DisclosureFormState, + type: DisclosureType, +): ProjectDisclosure { + switch (type) { + case 'ai_content': + return { + type: 'ai_content', + uses: [...form.ai.uses], + note: form.ai.note.trim() || null, + } + case 'advertisements': + return { type: 'advertisements', note: form.advertising.note.trim() || null } + case 'paid_features': + return { + type: 'paid_features', + features: form.paidFeatures.features.map((feature) => feature.trim()).filter(Boolean), + } + case 'telemetry': + return { + type: 'telemetry', + consent: form.telemetry.consent, + data_collected: form.telemetry.entries.map((entry) => entry.trim()).filter(Boolean), + } + case 'derivative_work': + return { + type: 'derivative_work', + sources: form.derivative.sources.map((source) => ({ + label: source.label.trim(), + link: source.link?.trim() || null, + note: source.note?.trim() || null, + })), + } + case 'epilepsy_triggers': + return { type: 'epilepsy_triggers', note: form.photosensitivity.note.trim() || null } + case 'system_interactions': + return { + type: 'system_interactions', + interactions: [...form.systemInteractions.interactions], + note: form.systemInteractions.note.trim() || null, + } + case 'archived': + return { type: 'archived', note: form.archived.note.trim() || null } + } +} + +export function formToDisclosures(form: DisclosureFormState): ProjectDisclosure[] { + const set: ProjectDisclosure[] = [] + + if (form.ai.enabled) { + set.push(formToDisclosure(form, 'ai_content')) + } + if (form.advertising.enabled) { + set.push(formToDisclosure(form, 'advertisements')) + } + if (form.paidFeatures.enabled) { + set.push(formToDisclosure(form, 'paid_features')) + } + if (form.telemetry.enabled) { + set.push(formToDisclosure(form, 'telemetry')) + } + if (form.derivative.enabled) { + set.push(formToDisclosure(form, 'derivative_work')) + } + if (form.photosensitivity.enabled) { + set.push(formToDisclosure(form, 'epilepsy_triggers')) + } + if (form.systemInteractions.enabled) { + set.push(formToDisclosure(form, 'system_interactions')) + } + if (form.archived.enabled) { + set.push(formToDisclosure(form, 'archived')) + } + + return set +} + +export function toModifyRequests( + form: DisclosureFormState, + previous: DisclosureFormState, +): Labrinth.Projects.v3.ModifyProjectDisclosures[] { + const next = formToDisclosures(form) + const previousDisclosures = formToDisclosures(previous) + const previousByType = new Map( + previousDisclosures.map((disclosure) => [disclosure.type, disclosure]), + ) + const nextTypes = new Set(next.map((disclosure) => disclosure.type)) + + const remove: DisclosureType[] = [] + const contentOnly: ProjectDisclosure[] = [] + const lockChangeGroups = new Map() + const disabledLockGroups = new Map() + + for (const disclosure of next) { + const existing = previousByType.get(disclosure.type) + const contentChanged = !existing || JSON.stringify(existing) !== JSON.stringify(disclosure) + const previousLock = previous.lockStatuses[disclosure.type] ?? 'unlocked' + const nextLock = form.lockStatuses[disclosure.type] ?? 'unlocked' + const lockChanged = previousLock !== nextLock + + if (!contentChanged && !lockChanged) { + continue + } + + if (lockChanged) { + const group = lockChangeGroups.get(nextLock) ?? [] + group.push(disclosure) + lockChangeGroups.set(nextLock, group) + } else { + contentOnly.push(disclosure) + } + } + + for (const type of PROJECT_DISCLOSURE_TYPES) { + if (nextTypes.has(type)) { + continue + } + + const previousLock = previous.lockStatuses[type] ?? 'unlocked' + const nextLock = form.lockStatuses[type] ?? 'unlocked' + const lockChanged = previousLock !== nextLock + const wasEnabled = previousByType.has(type) + + if (wasEnabled && !lockChanged) { + remove.push(type) + continue + } + + if (!lockChanged) { + continue + } + + const group = disabledLockGroups.get(nextLock) ?? [] + group.push(formToDisclosure(form, type)) + disabledLockGroups.set(nextLock, group) + } + + const requests: Labrinth.Projects.v3.ModifyProjectDisclosures[] = [] + + if (remove.length > 0) { + requests.push({ set: [], remove }) + } + + if (contentOnly.length > 0) { + requests.push({ set: contentOnly, remove: [] }) + } + + for (const [lockStatus, set] of lockChangeGroups) { + requests.push({ set, remove: [], lock_status: lockStatus }) + } + + for (const [lockStatus, set] of disabledLockGroups) { + requests.push({ set, remove: [], lock_status: lockStatus }) + requests.push({ set: [], remove: set.map((disclosure) => disclosure.type) }) + } + + return requests +} + +export function getDisclosureFormSnapshot(form: DisclosureFormState) { + return { + disclosures: formToDisclosures(form), + lockStatuses: { ...form.lockStatuses }, + } +} + +export type DisclosureFormIssue = + | 'advertising-note' + | 'paid-features-empty' + | 'telemetry-empty' + | 'derivative-empty' + | 'derivative-source-label' + | 'photosensitivity-note' + | 'system-interactions-note' + +export function getDisclosureFormIssues( + form: DisclosureFormState, + projectTypes?: readonly string[], +): DisclosureFormIssue[] { + const issues: DisclosureFormIssue[] = [] + const missingNote = (model: NoteDisclosure) => model.enabled && !model.note.trim() + const compatible = (type: DisclosureType) => + !projectTypes || isDisclosureCompatibleWithProjectTypes(type, projectTypes) + + if (compatible('advertisements') && missingNote(form.advertising)) { + issues.push('advertising-note') + } + if ( + compatible('paid_features') && + form.paidFeatures.enabled && + !form.paidFeatures.features.some((feature) => feature.trim()) + ) { + issues.push('paid-features-empty') + } + if ( + compatible('telemetry') && + form.telemetry.enabled && + !form.telemetry.entries.some((entry) => entry.trim()) + ) { + issues.push('telemetry-empty') + } + if (compatible('derivative_work') && form.derivative.enabled) { + if (form.derivative.sources.length === 0) { + issues.push('derivative-empty') + } else if (form.derivative.sources.some((source) => !source.label?.trim())) { + issues.push('derivative-source-label') + } + } + if (compatible('epilepsy_triggers') && missingNote(form.photosensitivity)) { + issues.push('photosensitivity-note') + } + if ( + compatible('system_interactions') && + form.systemInteractions.enabled && + !form.systemInteractions.note.trim() + ) { + issues.push('system-interactions-note') + } + + return issues +} diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/index.ts b/apps/frontend/src/components/ui/project-settings/disclosures/index.ts new file mode 100644 index 0000000000..085bf22204 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/index.ts @@ -0,0 +1,12 @@ +export { default as AdvertisingDisclosureCard } from './AdvertisingDisclosureCard.vue' +export { default as AiDisclosureCard } from './AiDisclosureCard.vue' +export { default as ArchivedDisclosureCard } from './ArchivedDisclosureCard.vue' +export { default as DerivativeDisclosureCard } from './DerivativeDisclosureCard.vue' +export { default as DisclosureToggleCard } from './DisclosureToggleCard.vue' +export { default as DisclosureUpdatedBy } from './DisclosureUpdatedBy.vue' +export * from './form' +export { default as PaidFeaturesDisclosureCard } from './PaidFeaturesDisclosureCard.vue' +export { default as PhotosensitivityDisclosureCard } from './PhotosensitivityDisclosureCard.vue' +export { default as SystemInteractionsDisclosureCard } from './SystemInteractionsDisclosureCard.vue' +export { default as TelemetryDisclosureCard } from './TelemetryDisclosureCard.vue' +export * from './types' diff --git a/apps/frontend/src/components/ui/project-settings/disclosures/types.ts b/apps/frontend/src/components/ui/project-settings/disclosures/types.ts new file mode 100644 index 0000000000..6983314a98 --- /dev/null +++ b/apps/frontend/src/components/ui/project-settings/disclosures/types.ts @@ -0,0 +1,71 @@ +import type { Labrinth } from '@modrinth/api-client' + +export type TelemetryConsent = Labrinth.Projects.v3.TelemetryConsent +export type AiUsage = Labrinth.Projects.v3.AiUsage +export type DerivativeSource = Labrinth.Projects.v3.DerivativeSource +export type DisclosureLockStatus = Labrinth.Projects.v3.DisclosureLockStatus +export type ProjectDisclosure = Labrinth.Projects.v3.ProjectDisclosure +export type ProjectDisclosureData = Labrinth.Projects.v3.ProjectDisclosureData +export type DisclosureType = Labrinth.Projects.v3.ProjectDisclosureType +export type DisclosureOf = Labrinth.Projects.v3.ProjectDisclosureOf + +export type NoteDisclosure = { + enabled: boolean + note: string +} + +export type SystemInteractionsDisclosure = { + enabled: boolean + note: string + interactions: string[] +} + +export type AiDisclosure = { + enabled: boolean + uses: AiUsage[] + note: string +} + +export type PaidFeaturesDisclosure = { + enabled: boolean + features: string[] +} + +export type TelemetryDisclosure = { + enabled: boolean + consent: TelemetryConsent + entries: string[] +} + +export type DerivativeDisclosure = { + enabled: boolean + sources: DerivativeSource[] +} + +export type DisclosureFormState = { + ai: AiDisclosure + advertising: NoteDisclosure + paidFeatures: PaidFeaturesDisclosure + telemetry: TelemetryDisclosure + derivative: DerivativeDisclosure + photosensitivity: NoteDisclosure + systemInteractions: SystemInteractionsDisclosure + archived: NoteDisclosure + lockStatuses: Record +} + +export type DisclosureUpdatedByUser = { + id: string + username: string + avatar_url?: string | null +} + +export type DisclosureCardMetaProps = { + disabled?: boolean + toggleDisabled?: boolean + updatedAt?: string | null + updatedBy?: DisclosureUpdatedByUser | null + setByModerator?: boolean + lockStatus?: DisclosureLockStatus | null + showLockControls?: boolean +} diff --git a/apps/frontend/src/components/ui/report/ReportInfo.vue b/apps/frontend/src/components/ui/report/ReportInfo.vue index 0d5ccfec21..1de7dfb119 100644 --- a/apps/frontend/src/components/ui/report/ReportInfo.vue +++ b/apps/frontend/src/components/ui/report/ReportInfo.vue @@ -90,7 +90,14 @@
- +
import { BoxesIcon, ReportIcon, UnknownIcon, VersionIcon } from '@modrinth/assets' -import { Avatar, Badge, CopyCode, useFormatDateTime, useRelativeTime } from '@modrinth/ui' +import { + Avatar, + Badge, + CopyCode, + defineMessages, + formatReportType, + useFormatDateTime, + useRelativeTime, + useVIntl, +} from '@modrinth/ui' import { formatProjectType, renderHighlightedString } from '@modrinth/utils' import ThreadSummary from '~/components/ui/thread/ThreadSummary.vue' import { getProjectTypeForUrl } from '~/helpers/projects.js' +const { formatMessage } = useVIntl() const formatRelativeTime = useRelativeTime() const formatDateTime = useFormatDateTime({ timeStyle: 'short', @@ -165,6 +182,13 @@ defineProps({ }) const flags = useFeatureFlags() + +const messages = defineMessages({ + reportedFor: { + id: 'report.reported-for', + defaultMessage: 'Reported for {type}', + }, +}) diff --git a/apps/frontend/src/pages/[type]/[project]/gallery.vue b/apps/frontend/src/pages/[type]/[project]/gallery.vue index 801a86017d..c4e3f0c677 100644 --- a/apps/frontend/src/pages/[type]/[project]/gallery.vue +++ b/apps/frontend/src/pages/[type]/[project]/gallery.vue @@ -1,5 +1,6 @@ diff --git a/apps/frontend/src/pages/[type]/[project]/settings/description.vue b/apps/frontend/src/pages/[type]/[project]/settings/description.vue index ef168ec53f..6cd1c44bef 100644 --- a/apps/frontend/src/pages/[type]/[project]/settings/description.vue +++ b/apps/frontend/src/pages/[type]/[project]/settings/description.vue @@ -1,5 +1,6 @@ @@ -27,7 +27,8 @@ diff --git a/apps/frontend/src/pages/[type]/[project]/settings/license.vue b/apps/frontend/src/pages/[type]/[project]/settings/license.vue index 34e2f3564d..fea81bc4ff 100644 --- a/apps/frontend/src/pages/[type]/[project]/settings/license.vue +++ b/apps/frontend/src/pages/[type]/[project]/settings/license.vue @@ -28,12 +28,13 @@
-
@@ -155,24 +156,28 @@ + diff --git a/apps/frontend/src/pages/[type]/[project]/settings/versions.vue b/apps/frontend/src/pages/[type]/[project]/settings/versions.vue index a0f385a639..c6e29f821b 100644 --- a/apps/frontend/src/pages/[type]/[project]/settings/versions.vue +++ b/apps/frontend/src/pages/[type]/[project]/settings/versions.vue @@ -35,16 +35,16 @@ > @@ -67,180 +67,189 @@ :open-modal="currentMember ? () => handleOpenCreateVersionModal() : undefined" > @@ -304,11 +313,13 @@
No versions created
Create your first project version.

- - - +
@@ -335,7 +346,8 @@ import { } from '@modrinth/assets' import { Admonition, - ButtonStyled, + Button, + ButtonLink, commonMessages, commonProjectSettingsMessages, ConfirmModal, @@ -343,8 +355,8 @@ import { injectModrinthClient, injectNotificationManager, injectProjectPageContext, - OverflowMenu, ProjectPageVersions, + TeleportOverflowMenu, useVIntl, } from '@modrinth/ui' import { useTemplateRef, watch } from 'vue' @@ -369,6 +381,8 @@ const { cdnDownloadReason, } = injectProjectPageContext() +useProjectSettingsHeadTitle(commonProjectSettingsMessages.versions) + // Load versions on mount (client-side) onMounted(() => { loadVersions() diff --git a/apps/frontend/src/pages/[type]/[project]/version/[version].vue b/apps/frontend/src/pages/[type]/[project]/version/[version].vue index 5facef220d..193aeb89f7 100644 --- a/apps/frontend/src/pages/[type]/[project]/version/[version].vue +++ b/apps/frontend/src/pages/[type]/[project]/version/[version].vue @@ -65,18 +65,19 @@
- - - - - - + +
@@ -104,16 +105,16 @@ > @@ -127,23 +128,39 @@ class="mb-4" > @@ -445,7 +460,6 @@ import { } from '@modrinth/assets' import { AutoLink, - ButtonStyled, Pagination, SmartClickable, Table, @@ -457,11 +471,17 @@ import { VersionChannelIndicator, VersionFilterControl, } from '@modrinth/ui' -import { formatVersionsForDisplay, type GameVersionTag, type Version } from '@modrinth/utils' +import { + type GameVersionTag, + getVersionGroupsForDisplay, + type VersionDisplayGroup, +} from '@modrinth/utils' import { Menu } from 'floating-vue' import { computed, type Ref, ref } from 'vue' import { useRoute, useRouter } from 'vue-router' +import { Button } from '#ui/components/base/buttons' + import { useRelativeTime } from '../../composables' import { defineMessages, useVIntl } from '../../composables/i18n' import { formatTag } from '../../utils/tag-messages' @@ -479,15 +499,12 @@ const formatBytes = useFormatBytes() const MAX_GAME_VERSION_TAGS = 5 const MAX_PLATFORM_TAGS = 3 -type VersionWithDisplayUrlEnding = Version & { +type VersionWithDisplayUrlEnding = Labrinth.Versions.v3.Version & { displayUrlEnding: string - environment?: Labrinth.Projects.v3.Environment - mrpack_loaders?: string[] } type DisplayVersion = VersionWithDisplayUrlEnding & { noModLoader: boolean - files_missing_attribution?: boolean } type VersionTableColumn = @@ -515,7 +532,7 @@ const props = withDefaults( currentMember?: boolean loaders: Labrinth.Tags.v2.Loader[] gameVersions: GameVersionTag[] - versionLink?: (version: Version) => string + versionLink?: (version: Labrinth.Versions.v3.Version) => string openModal?: () => void createVersionButtonSecondary?: boolean }>(), @@ -616,8 +633,8 @@ function hasNoModLoader(loaders: string[]): boolean { ) } -function getDisplayGameVersions(version: DisplayVersion): string[] { - return formatVersionsForDisplay(version.game_versions, props.gameVersions) +function getDisplayGameVersions(version: DisplayVersion): VersionDisplayGroup[] { + return getVersionGroupsForDisplay(version.game_versions, props.gameVersions) } function getFilterTooltip(filter: string): string { diff --git a/packages/ui/src/components/project/ProjectSidebarCreators.vue b/packages/ui/src/components/project/ProjectSidebarCreators.vue index 0e58d1b997..1eab4a2d36 100644 --- a/packages/ui/src/components/project/ProjectSidebarCreators.vue +++ b/packages/ui/src/components/project/ProjectSidebarCreators.vue @@ -2,45 +2,59 @@

{{ formatMessage(messages.title) }}

- @@ -80,6 +94,7 @@ const props = defineProps<{ userLink: (username: string) => string linkTarget?: string userLinkTarget?: string | null + loading?: boolean }>() function resolveLinkTarget(target: string | null | undefined): string | null { @@ -113,6 +128,8 @@ const sortedMembers = computed(() => { return owner ? [owner, ...rest] : rest }) +const isEmpty = computed(() => !props.organization && sortedMembers.value.length === 0) + const messages = defineMessages({ title: { id: 'project.about.creators.title', diff --git a/packages/ui/src/components/project/ProjectSidebarDetails.vue b/packages/ui/src/components/project/ProjectSidebarDetails.vue index bfe45a68c3..8be4b125e9 100644 --- a/packages/ui/src/components/project/ProjectSidebarDetails.vue +++ b/packages/ui/src/components/project/ProjectSidebarDetails.vue @@ -13,7 +13,89 @@

{{ formatMessage(commonMessages.detailsLabel) }}

-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- - - + + +
diff --git a/packages/ui/src/layouts/shared/server-settings/pages/installation.vue b/packages/ui/src/layouts/shared/server-settings/pages/installation.vue index 3d943bd823..21275870a7 100644 --- a/packages/ui/src/layouts/shared/server-settings/pages/installation.vue +++ b/packages/ui/src/layouts/shared/server-settings/pages/installation.vue @@ -22,17 +22,16 @@ formatMessage(messages.resetServerTitle) }}
- - - +
{{ formatMessage(messages.resetServerDescription) }} @@ -59,17 +58,16 @@ {{ formatMessage(messages.supportOptionsTitle) }}
- - - +
@@ -79,7 +77,6 @@ import type { Archon } from '@modrinth/api-client' import { RotateCounterClockwiseIcon } from '@modrinth/assets' import { - ButtonStyled, commonMessages, ConfirmModal, defineMessages, @@ -103,6 +100,7 @@ import { import { useQuery, useQueryClient } from '@tanstack/vue-query' import { computed, ref, useTemplateRef, watch } from 'vue' +import { Button } from '#ui/components/base/buttons' import { injectFilePicker } from '#ui/providers/file-picker' const debug = useDebugLogger('LoaderPage') diff --git a/packages/ui/src/layouts/shared/server-settings/pages/network.vue b/packages/ui/src/layouts/shared/server-settings/pages/network.vue index dd8091b289..9a91d08000 100644 --- a/packages/ui/src/layouts/shared/server-settings/pages/network.vue +++ b/packages/ui/src/layouts/shared/server-settings/pages/network.vue @@ -16,18 +16,16 @@ placeholder="e.g. Secondary allocation" />
- - - - - - + +
@@ -61,9 +59,14 @@ allocationsError?.message ?? 'Unknown error' }}

- - - +
@@ -83,16 +86,16 @@ placeholder="e.g. Secondary allocation" /> - - - + @@ -105,30 +108,33 @@ @@ -153,16 +159,14 @@ :placeholder="exampleDomain" /> - - - +
@@ -223,8 +227,9 @@ import { import { useQuery, useQueryClient } from '@tanstack/vue-query' import { computed, nextTick, ref } from 'vue' -import { ButtonStyled, ConfirmModal, NewModal, StyledInput, Table, TagItem } from '#ui/components' +import { ConfirmModal, NewModal, StyledInput, Table, TagItem } from '#ui/components' import type { TableColumn } from '#ui/components/base' +import { Button, IconButton } from '#ui/components/base/buttons' import { useServerPermissions } from '#ui/composables/server-permissions' import { injectModrinthClient, diff --git a/packages/ui/src/layouts/shared/user-profile/components/edit-user-modal.vue b/packages/ui/src/layouts/shared/user-profile/components/edit-user-modal.vue new file mode 100644 index 0000000000..64e3e27043 --- /dev/null +++ b/packages/ui/src/layouts/shared/user-profile/components/edit-user-modal.vue @@ -0,0 +1,310 @@ + + + diff --git a/packages/ui/src/layouts/shared/user-profile/layout.vue b/packages/ui/src/layouts/shared/user-profile/layout.vue index 9c3b008a6b..8ffe648c35 100644 --- a/packages/ui/src/layouts/shared/user-profile/layout.vue +++ b/packages/ui/src/layouts/shared/user-profile/layout.vue @@ -13,60 +13,31 @@ - -
- -
- - - - - - -
-
-
+ - + @@ -112,11 +110,9 @@
{{ formatMessage(messages.loadError) }} - - - +
{{ formatMessage(messages.noBlockedUsers) }} @@ -145,25 +141,24 @@
@@ -195,7 +190,7 @@ import { useQuery, useQueryClient } from '@tanstack/vue-query' import { computed, ref } from 'vue' import Avatar from '#ui/components/base/Avatar.vue' -import ButtonStyled from '#ui/components/base/ButtonStyled.vue' +import { Button } from '#ui/components/base/buttons' import Chips from '#ui/components/base/Chips.vue' import EmptyState from '#ui/components/base/EmptyState.vue' import Table, { type TableColumn } from '#ui/components/base/Table.vue' diff --git a/packages/ui/src/layouts/wrapped/hosting/manage/[id]/access/access.vue b/packages/ui/src/layouts/wrapped/hosting/manage/[id]/access/access.vue index 96cc63944a..b85f8d8fe3 100644 --- a/packages/ui/src/layouts/wrapped/hosting/manage/[id]/access/access.vue +++ b/packages/ui/src/layouts/wrapped/hosting/manage/[id]/access/access.vue @@ -14,23 +14,25 @@ v-model="roleFilter" :options="roleFilterOptions" :display-value="selectedRoleFilterLabel" - trigger-class="min-w-[225px] !h-10 !min-h-10 !py-0" + trigger-size="lg" + trigger-class="min-w-[225px]" > - - - + @@ -113,7 +115,7 @@ import { FilterIcon, SearchIcon, UserPlusIcon } from '@modrinth/assets' import { useQuery, useQueryClient } from '@tanstack/vue-query' import { computed, ref, watch } from 'vue' -import ButtonStyled from '#ui/components/base/ButtonStyled.vue' +import { Button } from '#ui/components/base/buttons' import Combobox, { type ComboboxOption } from '#ui/components/base/Combobox.vue' import DropdownFilterBar from '#ui/components/base/DropdownFilterBar.vue' import StyledInput from '#ui/components/base/StyledInput.vue' diff --git a/packages/ui/src/layouts/wrapped/hosting/manage/[id]/onboarding.vue b/packages/ui/src/layouts/wrapped/hosting/manage/[id]/onboarding.vue index bcdebf6392..f231ba7956 100644 --- a/packages/ui/src/layouts/wrapped/hosting/manage/[id]/onboarding.vue +++ b/packages/ui/src/layouts/wrapped/hosting/manage/[id]/onboarding.vue @@ -42,22 +42,22 @@
- - - - - - + +
{{ error.message }}

- - - + @@ -71,16 +71,16 @@ - - - +
@@ -95,17 +95,17 @@ :description="formatMessage(messages.emptyDescription)" >
@@ -198,30 +196,30 @@ }}
- - - +
- - - +
@@ -236,7 +234,9 @@ role="progressbar" :aria-valuemin="0" :aria-valuemax="bulkTotal" - style="box-shadow: 0px -2px 4px 0px rgba(27, 217, 106, 0.1)" + style=" + box-shadow: 0px -2px 4px 0px color-mix(in srgb, var(--color-brand) 10%, transparent); + " />
@@ -273,7 +273,7 @@ import type { Component } from 'vue' import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue' import { useRoute } from 'vue-router' -import ButtonStyled from '#ui/components/base/ButtonStyled.vue' +import { Button } from '#ui/components/base/buttons' import Checkbox from '#ui/components/base/Checkbox.vue' import EmptyState from '#ui/components/base/EmptyState.vue' import FilterPills, { type FilterPillOption } from '#ui/components/base/FilterPills.vue' diff --git a/packages/ui/src/layouts/wrapped/hosting/manage/content.vue b/packages/ui/src/layouts/wrapped/hosting/manage/content.vue index bcfd4afc38..a08df7dd64 100644 --- a/packages/ui/src/layouts/wrapped/hosting/manage/content.vue +++ b/packages/ui/src/layouts/wrapped/hosting/manage/content.vue @@ -33,19 +33,15 @@ import { getStoredServerAddonInstallQueue, getTargetInstallPreferences, } from '../../../shared/browse-tab/composables/install-logic' +import ManagedContentModal from '../../../shared/content-tab/components/managed-content-modal/index.vue' import ConfirmModpackUpdateModal from '../../../shared/content-tab/components/modals/ConfirmModpackUpdateModal.vue' import ConfirmUnlinkModal from '../../../shared/content-tab/components/modals/ConfirmUnlinkModal.vue' import ContentUpdaterModal from '../../../shared/content-tab/components/modals/content-updater-modal/index.vue' -import ModpackContentModal from '../../../shared/content-tab/components/modals/ModpackContentModal.vue' import ContentPageLayout from '../../../shared/content-tab/layout.vue' -import type { ContentModpackData } from '../../../shared/content-tab/providers/content-manager' +import type { ManagedContentData } from '../../../shared/content-tab/providers/content-manager' import { provideContentManager } from '../../../shared/content-tab/providers/content-manager' -import type { - ContentItem, - ContentModpackCardCategory, - ContentModpackCardProject, - ContentModpackCardVersion, -} from '../../../shared/content-tab/types' +import type { ContentItem } from '../../../shared/content-tab/types' +import { summarizeManagedContent } from '../../../shared/content-tab/utils/managed-content' type AddonWithUiState = Archon.Content.v1.Addon & { installing?: boolean } type ContentOwnerAvatarSource = { @@ -65,6 +61,10 @@ const props = withDefaults( const { formatMessage } = useVIntl() const messages = defineMessages({ + modpackContent: { + id: 'hosting.content.managed-content.modpack-header', + defaultMessage: 'Modpack content', + }, failedToRemoveContent: { id: 'hosting.content.failed-to-remove', defaultMessage: 'Failed to remove content', @@ -172,19 +172,21 @@ const modpackContentQuery = useQuery({ }) const setupActionDisabled = computed(() => !canSetup.value || busyReasons.value.length > 0) -const setupActionBusyMessage = computed(() => { - if (!canSetup.value) return permissionDeniedMessage.value - - const bannerCoversInstalling = +const isInstallingContent = computed( + () => server.value?.status === 'installing' || isSyncingContent.value || busyReasons.value.some( (r) => r.reason.id === 'servers.busy.installing' || r.reason.id === 'servers.busy.syncing-content', - ) + ), +) +const setupActionBusyMessage = computed(() => { + if (!canSetup.value) return permissionDeniedMessage.value + const filteredReasons = busyReasons.value.filter((r) => { if ( - bannerCoversInstalling && + isInstallingContent.value && (r.reason.id === 'servers.busy.installing' || r.reason.id === 'servers.busy.syncing-content') ) return false @@ -256,54 +258,38 @@ const newestModpackUpdateVersion = computed(() => { ) }) -const modpack = computed(() => { +const managedContent = computed(() => { const mp = contentQuery.data.value?.modpack if (!mp) return null const isLocal = mp.spec.platform === 'local_file' const project = projectQuery.data.value const projectId = isLocal ? null : mp.spec.project_id - return { - project: { - id: projectId ?? mp.title ?? '', - slug: project?.slug ?? projectId ?? '', - title: mp.title ?? (isLocal ? mp.spec.name : projectId) ?? '', - icon_url: mp.icon_url ?? undefined, - description: mp.description ?? '', - downloads: mp.downloads, - followers: mp.followers, - filename: isLocal ? mp.spec.filename : undefined, - } as ContentModpackCardProject, - projectLink: projectId ? `/project/${project?.slug ?? projectId}` : undefined, - version: isLocal + const addons = modpackContentQuery.data.value?.addons + const summary = addons + ? summarizeManagedContent(addons.map(addonToContentItem)) + : modpackContentQuery.isLoading.value ? undefined - : ({ - id: mp.spec.version_id, - version_number: mp.version_number ?? '', - date_published: mp.date_published ?? '', - } as ContentModpackCardVersion), - versionLink: - projectId && !isLocal - ? `/project/${project?.slug ?? projectId}/version/${mp.spec.version_id}` - : undefined, - owner: mp.owner - ? { - id: mp.owner.id, - name: mp.owner.name, - type: mp.owner.type, - avatar_url: getContentOwnerAvatarUrl(mp.owner), - link: - mp.owner.type === 'organization' - ? `/organization/${mp.owner.id}` - : `/user/${mp.owner.id}`, - } - : undefined, - categories: (project?.categories ?? []).map((name) => ({ - name, - icon: name, - project_type: 'modpack', - header: 'categories', - })) as ContentModpackCardCategory[], - hasUpdate: !!mp.has_update || !!newestModpackUpdateVersion.value, + : [] + const title = isLocal + ? (mp.title ?? mp.spec.name) + : (project?.title ?? mp.title ?? projectId ?? '') + return { + card: { + kind: 'modpack', + installing: isInstallingContent.value, + manager: { + name: title, + iconUrl: (isLocal ? mp.icon_url : (project?.icon_url ?? mp.icon_url)) ?? undefined, + link: projectId ? `/project/${project?.slug ?? projectId}` : undefined, + }, + summary, + versionNumber: isLocal ? undefined : (mp.version_number ?? undefined), + versionLink: + projectId && mp.spec.platform === 'modrinth' + ? `/project/${project?.slug ?? projectId}/version/${mp.spec.version_id}` + : undefined, + updatedAt: isLocal ? undefined : (mp.date_published ?? undefined), + }, } }) @@ -329,6 +315,31 @@ const addonLookup = computed(() => { }) const pendingServerContentInstalls = ref([]) +const projectMetadataBatchSize = 800 +const contentProjectIds = computed(() => + [...(contentQuery.data.value?.addons ?? []), ...modpackAddons.value] + .map((addon) => addon.project_id) + .concat(pendingServerContentInstalls.value.map((item) => item.projectId)) + .filter((id): id is string => !!id) + .filter((id, index, ids) => ids.indexOf(id) === index) + .sort(), +) +const contentProjectsQuery = useQuery({ + queryKey: computed(() => ['labrinth', 'projects', 'v2', contentProjectIds.value]), + queryFn: async () => { + const batches = [] + for (let index = 0; index < contentProjectIds.value.length; index += projectMetadataBatchSize) { + batches.push(contentProjectIds.value.slice(index, index + projectMetadataBatchSize)) + } + return ( + await Promise.all(batches.map((ids) => client.labrinth.projects_v2.getMultiple(ids))) + ).flat() + }, + enabled: computed(() => contentProjectIds.value.length > 0), +}) +const contentProjectsById = computed( + () => new Map((contentProjectsQuery.data.value ?? []).map((project) => [project.id, project])), +) const lastStableContentKeys = ref>(new Set()) const contentInstallBaselineKeys = ref | null>(null) const contentInstallAddedKeys = ref>(new Set()) @@ -506,12 +517,14 @@ async function flushStoredServerInstalls() { } function pendingInstallToContentItem(item: PendingServerContentInstall): ContentItem { + const projectMetadata = contentProjectsById.value.get(item.projectId) return { project: { + ...(projectMetadata ?? {}), id: item.projectId, - slug: item.slug ?? item.projectId, - title: item.title, - icon_url: item.iconUrl ?? undefined, + slug: item.slug ?? projectMetadata?.slug ?? item.projectId, + title: projectMetadata?.title ?? item.title, + icon_url: item.iconUrl ?? projectMetadata?.icon_url ?? undefined, }, version: { id: item.versionId, @@ -854,7 +867,7 @@ async function handleBulkDisable(items: ContentItem[]) { } const modpackUnlinkModal = ref>() -const modpackContentModal = ref>() +const modpackContentModal = ref>() const contentUpdaterModal = ref>() const updatingProject = ref(null) @@ -1002,12 +1015,16 @@ function handleUnknownFileContinue(dontShowAgain: boolean) { } function addonToContentItem(addon: AddonWithUiState): ContentItem { + const projectMetadata = addon.project_id + ? contentProjectsById.value.get(addon.project_id) + : undefined return { project: { + ...(projectMetadata ?? {}), id: addon.project_id ?? addon.filename, - slug: addon.project_id ?? addon.filename, - title: friendlyAddonName(addon), - icon_url: addon.icon_url ?? undefined, + slug: projectMetadata?.slug ?? addon.project_id ?? addon.filename, + title: projectMetadata?.title ?? friendlyAddonName(addon), + icon_url: addon.icon_url ?? projectMetadata?.icon_url ?? undefined, }, version: { id: addon.version?.id ?? addon.filename, @@ -1378,7 +1395,7 @@ provideContentManager({ items: contentItems, loading: computed(() => contentQuery.isLoading.value), error: computed(() => contentQuery.error.value ?? null), - modpack, + managedContent, isPackLocked: ref(false), isBusy: setupActionDisabled, busyMessage: setupActionBusyMessage, @@ -1396,13 +1413,14 @@ provideContentManager({ browse: handleBrowseContent, uploadFiles: handleUploadFiles, deletionContext: 'server', + showEnvironmentWarnings: true, hasUpdateSupport: true, updateItem: handleUpdateItem, bulkUpdateItems: handleBulkUpdate, - updateModpack: handleModpackUpdate, - viewModpackContent: handleViewModpackContent, + runManagedContentPrimaryAction: handleModpackUpdate, + viewManagedContent: handleViewModpackContent, unlinkModpack: handleModpackUnlink, - openSettings: () => openServerSettings({ tabId: 'installation' }), + openManagedContentSettings: () => openServerSettings({ tabId: 'installation' }), switchVersion: handleSwitchVersion, getOverflowOptions, getItemId: getContentItemId, @@ -1423,6 +1441,7 @@ provideContentManager({ owner: item.owner ? { ...item.owner, link: item.owner.link ?? `/${item.owner.type}/${item.owner.id}` } : undefined, + external: item.external ?? !hasModrinthProject, enabled: item.enabled, } }, @@ -1448,11 +1467,13 @@ provideContentManager({ :action-disabled-tooltip="setupActionBusyMessage ?? undefined" @unlink="handleModpackUnlinkConfirm" /> - - - {{ - formatMessage(messages.contactSupportButton) - }} - - - - + {{ formatMessage(messages.contactSupportButton) }} + @@ -106,12 +109,10 @@ :placeholder="formatMessage(messages.searchPlaceholder, { count: filteredData.length })" wrapper-class="w-full md:w-72" /> - - - + @@ -231,8 +232,6 @@ import type { Archon, Labrinth } from '@modrinth/api-client' import { HammerIcon, LoaderCircleIcon, PlusIcon, SearchIcon } from '@modrinth/assets' import { - AutoLink, - ButtonStyled, CopyCode, defineMessages, injectAuth, @@ -255,6 +254,7 @@ import type Stripe from 'stripe' import { type ComponentPublicInstance, computed, ref, watch } from 'vue' import { useRoute, useRouter } from 'vue-router' +import { Button, ButtonLink } from '#ui/components/base/buttons' import ServersUpgradeModalWrapper from '#ui/components/billing/ServersUpgradeModalWrapper.vue' import type { ServerListingOwner } from '#ui/components/servers/access' import MedalServerListing from '#ui/components/servers/marketing/MedalServerListing.vue' diff --git a/packages/ui/src/layouts/wrapped/hosting/manage/root.vue b/packages/ui/src/layouts/wrapped/hosting/manage/root.vue index c781570242..978b6b6c49 100644 --- a/packages/ui/src/layouts/wrapped/hosting/manage/root.vue +++ b/packages/ui/src/layouts/wrapped/hosting/manage/root.vue @@ -142,8 +142,8 @@ @@ -284,13 +283,11 @@ If you're stuck, please contact Modrinth Support with the information below: - - - +
An internal error occurred while installing your server. Don't fret — try @@ -310,25 +307,23 @@ v-if="errorTitle === 'Installation error'" class="mt-2 flex flex-col gap-4 sm:flex-row" > - - - - - - - - - + + +
@@ -430,7 +425,7 @@ import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, watch import { onBeforeRouteLeave, useRoute, useRouter } from 'vue-router' import Avatar from '#ui/components/base/Avatar.vue' -import ButtonStyled from '#ui/components/base/ButtonStyled.vue' +import { Button, IconButton, TeleportOverflowMenu } from '#ui/components/base/buttons' import ErrorInformationCard from '#ui/components/base/ErrorInformationCard.vue' import NavTabs from '#ui/components/base/NavTabs.vue' import PageHeader from '#ui/components/base/page-header/index.vue' @@ -438,10 +433,9 @@ import PageHeaderMetadata from '#ui/components/base/page-header/metadata/index.v import PageHeaderMetadataItem from '#ui/components/base/page-header/metadata/page-header-metadata-item.vue' import PageHeaderActions from '#ui/components/base/page-header/page-header-actions.vue' import ServerNotice from '#ui/components/base/ServerNotice.vue' -import TeleportOverflowMenu from '#ui/components/base/TeleportOverflowMenu.vue' +import TagIcon from '#ui/components/base/TagIcon.vue' import ConfirmLeaveModal from '#ui/components/modal/ConfirmLeaveModal.vue' import ServerPanelAdmonitions from '#ui/components/servers/admonitions/ServerPanelAdmonitions.vue' -import LoaderIcon from '#ui/components/servers/icons/LoaderIcon.vue' import ServerIcon from '#ui/components/servers/icons/ServerIcon.vue' import MedalServerCountdown from '#ui/components/servers/marketing/MedalServerCountdown.vue' import { PanelServerActionButton } from '#ui/components/servers/server-header' diff --git a/packages/ui/src/locales/cs-CZ/index.json b/packages/ui/src/locales/cs-CZ/index.json index 3ca7ba4115..be61453f5d 100644 --- a/packages/ui/src/locales/cs-CZ/index.json +++ b/packages/ui/src/locales/cs-CZ/index.json @@ -548,18 +548,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Názvy projektů" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Abecedně" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Od nejnovějších" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Od nejstarších" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Seřadit {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Aktualizovat vše" }, @@ -1130,9 +1118,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Soubor uložen" }, - "files.editor.find-close": { - "defaultMessage": "Zavřít" - }, "files.editor.find-in-file": { "defaultMessage": "Najít" }, @@ -1835,18 +1820,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Vybrat ikonu" }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nebyl nalezen obsah" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Obsah modpacku" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Načítání obsahu..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Žádné projekty neodpovídají tvému vyhledávání." - }, "instances.updater-modal.badge.current": { "defaultMessage": "Mometálně" }, diff --git a/packages/ui/src/locales/da-DK/index.json b/packages/ui/src/locales/da-DK/index.json index 3277f89162..257dba321b 100644 --- a/packages/ui/src/locales/da-DK/index.json +++ b/packages/ui/src/locales/da-DK/index.json @@ -161,6 +161,9 @@ "button.enable": { "defaultMessage": "Aktiver" }, + "button.extract": { + "defaultMessage": "Pak ud" + }, "button.follow": { "defaultMessage": "Følg" }, @@ -272,12 +275,24 @@ "changelog.product.hosting": { "defaultMessage": "Hosting" }, + "changelog.product.web": { + "defaultMessage": "Platform" + }, "collection-widget.loading-projects": { "defaultMessage": "Indlæser projekter..." }, + "collection-widget.search-placeholder": { + "defaultMessage": "Søg efter projekter" + }, "collections.label.private": { "defaultMessage": "Privat" }, + "content-type.content.lowercase": { + "defaultMessage": "indhold" + }, + "content-type.item.lowercase": { + "defaultMessage": "{count, plural, one {genstand} other {genstande}}" + }, "content.card.select-project": { "defaultMessage": "Vælg {project}" }, @@ -380,12 +395,6 @@ "content.page-layout.share.label": { "defaultMessage": "Del" }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Ældst først" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sorter efter {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Opdater alle" }, @@ -542,9 +551,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Fil gemt" }, - "files.editor.find-close": { - "defaultMessage": "Luk" - }, "files.editor.find-in-file": { "defaultMessage": "Find" }, @@ -794,9 +800,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Vælg ikon" }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Ekstern" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Nuværrende" }, diff --git a/packages/ui/src/locales/de-CH/index.json b/packages/ui/src/locales/de-CH/index.json index bb3ed6010b..6999a0c627 100644 --- a/packages/ui/src/locales/de-CH/index.json +++ b/packages/ui/src/locales/de-CH/index.json @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Projektnamen" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alphabetisch" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Neuste zuerst" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Älteste zuerst" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sortieren nach {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Alle aktualisieren" }, @@ -1301,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Datei gespeichert" }, - "files.editor.find-close": { - "defaultMessage": "Schliessen" - }, "files.editor.find-in-file": { "defaultMessage": "Finden" }, @@ -2081,33 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Icon auswählen" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Dieses Modpack enthält keine zusätzlichen inhalte." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Keine Inhalte gefunden" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Extern" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Diese Datei ist nicht auf Modrinth veröffentlicht." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Modpack Inhalt" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Lade Inhalte..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Keine Projekte entsprechen deiner Suche." - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "In Slicer öffnen" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Durchsuche {count, number} {count, plural, one {Projekt} other {Projekte}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Aktuell" }, @@ -2240,6 +2198,9 @@ "label.details": { "defaultMessage": "Details" }, + "label.discover-content": { + "defaultMessage": "Inhalte erkunden" + }, "label.done": { "defaultMessage": "Fertig" }, @@ -2318,6 +2279,9 @@ "label.password": { "defaultMessage": "Passwort" }, + "label.permissions": { + "defaultMessage": "Berechtigungen" + }, "label.plan-custom": { "defaultMessage": "Benutzerdefiniert" }, @@ -2849,9 +2813,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Ein Modrinth-Ersteller." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Ein Modrinth-Nutzer." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} wird dir keine Freundschaftsanfragen mehr senden können, dich nicht zu geteilten Instanzen einladen können und dich nicht mehr zu Modrinth-Hosting Servern einladen können." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Bist du dir sicher, dass du diesen Nutzer blockieren willst?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Beim Blockieren dieses Nutzers ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "profile.block-user.error-title": { + "defaultMessage": "Blockierung fehlgeschlagen" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} wurde blockiert." + }, + "profile.block-user.success-title": { + "defaultMessage": "Nutzer blockiert" + }, + "profile.block-user.title": { + "defaultMessage": "Blockiere {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Benutzeranalysen anzeigen" + }, + "profile.button.billing": { + "defaultMessage": "Benutzerabrechnung verwalten" + }, + "profile.button.block": { + "defaultMessage": "Blockieren" + }, + "profile.button.create-collection": { + "defaultMessage": "Sammlung erstellen" + }, + "profile.button.create-project": { + "defaultMessage": "Projekt erstellen" + }, + "profile.button.info": { + "defaultMessage": "Nutzerdetails anzeigen" + }, + "profile.button.manage-projects": { + "defaultMessage": "Projekte verwalten" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Als Partner entfernen" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Als Partner festlegen" + }, + "profile.button.unblock": { + "defaultMessage": "Freigeben" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# Projekt} other {# Projekte}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Erlaube Pop-Ups für Modrinth und versuche es erneut." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Das GitHub-Profil konnte nicht abgerufen werden. Bitte versuche es erneut." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Das GitHub-Profil konnte nicht geöffnet werden" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Authentifizierungsanbieter" + }, + "profile.details.label.email-verified": { + "defaultMessage": "E-Mail verifiziert" + }, + "profile.details.label.has-password": { + "defaultMessage": "Hat Passwort" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Hat TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Wird geladen..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Zahlungsmethoden" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Profil anzeigen" + }, + "profile.details.title": { + "defaultMessage": "Nutzerdetails" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "E-Mail nicht verifiziert" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "E-Mail verifiziert" + }, + "profile.error.load-description": { + "defaultMessage": "Das Nutzerprofil konnte nicht geladen werden." + }, + "profile.error.not-found": { + "defaultMessage": "Nutzer nicht gefunden" + }, + "profile.label.affiliate": { + "defaultMessage": "Partner" + }, "profile.label.badges": { "defaultMessage": "Abzeichen" }, + "profile.label.collection": { + "defaultMessage": "Kollektion" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {Download} other {Downloads}}" + }, + "profile.label.joined": { + "defaultMessage": "Beigetreten" + }, + "profile.label.no-collections": { + "defaultMessage": "Dieser Nutzer hat keine Kollektionen!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Du hast noch keine Kollektionen." + }, + "profile.label.no-projects": { + "defaultMessage": "Dieser Nutzer hat keine Projekte!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Du hast noch keine Projekte." + }, + "profile.label.organizations": { + "defaultMessage": "Organisationen" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {Projekt} other {Projekte}}" + }, + "profile.official-account": { + "defaultMessage": "Offizielles Modrinth-Konto" + }, + "profile.official-account.bio": { + "defaultMessage": "Das offizielle Benutzerkonto von Modrinth. Erhalte Hilfe unter oder per E-Mail unter " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Beim Freigeben dieses Nutzers ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Nutzer konnte nicht freigegeben werden" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} wurde freigegeben." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Benutzer freigegeben" + }, "project-card.date.published.tooltip": { "defaultMessage": "Veröffentlicht {date}" }, @@ -2879,6 +2996,9 @@ "project-type.all": { "defaultMessage": "Alle" }, + "project-type.collection.plural": { + "defaultMessage": "Kollektionen" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Datenpaket} other {Datenpakete}}" }, @@ -3671,15 +3791,6 @@ "search.filter_type.advanced": { "defaultMessage": "Erweitert" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Datenpakete ausschließen" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Mods ausschließen" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Plugins ausschließen" - }, "search.filter_type.environment": { "defaultMessage": "Umgebung" }, @@ -5105,9 +5216,120 @@ "settings.pats.title": { "defaultMessage": "Persöhnlich Zugangstoken" }, + "settings.profile.bio.description": { + "defaultMessage": "Eine kurze Beschreibung um allen ein bisschen von dir zu erzählen." + }, + "settings.profile.bio.title": { + "defaultMessage": "Bio" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Profilbild" + }, + "settings.profile.public-information.description": { + "defaultMessage": "Deine Profilinformationen sind öffentlich auf Modrinth und über die Modrinth-API sichtbar." + }, + "settings.profile.save-error": { + "defaultMessage": "Profil konnte nicht aktualisiert werden" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Beim Aktualisieren deines Profils ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Melde dich mit einem Modrinth-Konto an, um dein öffentliches Profil anzupassen." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Modrinth-Konto benötigt" + }, + "settings.profile.username.description": { + "defaultMessage": "Ein eindeutiger Name für dein Profil, bei dem Groß- und Kleinschreibung nicht unterschieden wird." + }, "settings.sessions.title": { "defaultMessage": "Sitzungen" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Aktionen" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Nutzer" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Dies sind die Benutzer, die du auf Modrinth blockiert hast. Diese können nicht:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Du hast niemanden blockiert." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Blockierte Nutzer konnten nicht geladen werden." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Blockierte Nutzer werden geladen…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Dir Freundschaftsanfragen senden" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Dich zu einem Modrinth-Hosting Server einladen." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Dich zu geteilten Instanzen einladen" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Blockierte Nutzer" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Freigeben" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Benutzer konnte nicht freigegeben werden" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Beim Freigeben dieses Nutzers ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "{username} freigeben" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Avatar von {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Lege fest, wer dir auf Modrinth Freundschaftsanfragen senden kann." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Freundschaftsanfragen" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Bald verfügbar!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Jeder" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Freunde" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Freunde von Freunden" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Niemand" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Steuere, wer dir Einladungen zu geteilten Instanzen und Modrinth-Hosting-Panels senden kann." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Einladungen" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Mit einem Modrinth-Konto kannst du festlegen, wer mit dir interagieren kann, und blockierte Nutzer verwalten" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Modrinth-Konto benötigt" + }, + "settings.social.title": { + "defaultMessage": "Sozial" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Hinzufügen" }, @@ -5117,14 +5339,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Dieser Benutzer wurde bereits eingeladen." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Anwenden" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Avatar von {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Abbrechen" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Benutzerdefiniert..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Abbrechen" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Benutzerdefiniert: {date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Einladungslink bearbeiten." @@ -5132,6 +5357,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "Einladungslink bearbeiten" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "In 1 Tag" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "In 1 Stunde" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "In 7 Tagen" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "In 6 Stunden" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "In 3 Tagen" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "In 12 Stunden" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Ablaufdatum" }, diff --git a/packages/ui/src/locales/de-DE/index.json b/packages/ui/src/locales/de-DE/index.json index c6f62eb559..b94986963e 100644 --- a/packages/ui/src/locales/de-DE/index.json +++ b/packages/ui/src/locales/de-DE/index.json @@ -291,7 +291,7 @@ "defaultMessage": "Registrieren" }, "button.stop": { - "defaultMessage": "Stopp" + "defaultMessage": "Stoppen" }, "button.switch-to-version": { "defaultMessage": "Zur Version wechseln" @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Projektnamen" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alphabetisch" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Neuste zuerst" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Älteste zuerst" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sortieren nach {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Alle aktualisieren" }, @@ -1301,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Datei gespeichert" }, - "files.editor.find-close": { - "defaultMessage": "Schließen" - }, "files.editor.find-in-file": { "defaultMessage": "Finden" }, @@ -2081,33 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Icon auswählen" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Dieses Modpack enthält keine zusätzlichen Inhalte." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Keine Inhalte gefunden" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Extern" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Diese Datei ist nicht auf Modrinth veröffentlicht." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Modpack-Inhalt" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Lade Inhalte..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Keine Projekte entsprechen deiner Suche." - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "In Slicer öffnen" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Durchsuche {count, number} {count, plural, one {Projekt} other {Projekte}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Aktuell" }, @@ -2240,6 +2198,9 @@ "label.details": { "defaultMessage": "Details" }, + "label.discover-content": { + "defaultMessage": "Inhalte erkunden" + }, "label.done": { "defaultMessage": "Fertig" }, @@ -2292,7 +2253,7 @@ "defaultMessage": "Inhalt wird installiert" }, "label.loading": { - "defaultMessage": "Lädt..." + "defaultMessage": "Wird geladen..." }, "label.moderation": { "defaultMessage": "Moderation" @@ -2318,6 +2279,9 @@ "label.password": { "defaultMessage": "Passwort" }, + "label.permissions": { + "defaultMessage": "Berechtigungen" + }, "label.plan-custom": { "defaultMessage": "Benutzerdefiniert" }, @@ -2849,9 +2813,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Ein Modrinth-Ersteller." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Ein Modrinth-Nutzer." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} wird dir keine Freundschaftsanfragen mehr senden können, dich nicht zu geteilten Instanzen einladen können und dich nicht mehr zu Modrinth-Hosting Servern einladen können." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Bist du dir sicher, dass du diesen Nutzer blockieren willst?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Beim Blockieren dieses Nutzers ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "profile.block-user.error-title": { + "defaultMessage": "Blockierung fehlgeschlagen" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} wurde blockiert." + }, + "profile.block-user.success-title": { + "defaultMessage": "Nutzer blockiert" + }, + "profile.block-user.title": { + "defaultMessage": "Blockiere {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Benutzeranalysen anzeigen" + }, + "profile.button.billing": { + "defaultMessage": "Benutzerabrechnung verwalten" + }, + "profile.button.block": { + "defaultMessage": "Blockieren" + }, + "profile.button.create-collection": { + "defaultMessage": "Sammlung erstellen" + }, + "profile.button.create-project": { + "defaultMessage": "Projekt erstellen" + }, + "profile.button.info": { + "defaultMessage": "Nutzerdetails anzeigen" + }, + "profile.button.manage-projects": { + "defaultMessage": "Projekte verwalten" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Als Partner entfernen" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Als Partner festlegen" + }, + "profile.button.unblock": { + "defaultMessage": "Freigeben" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# Projekt} other {# Projekte}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Erlaube Pop-Ups für Modrinth und versuche es erneut." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Das GitHub-Profil konnte nicht abgerufen werden. Bitte versuche es erneut." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Das GitHub-Profil konnte nicht geöffnet werden" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Authentifizierungsanbieter" + }, + "profile.details.label.email-verified": { + "defaultMessage": "E-Mail verifiziert" + }, + "profile.details.label.has-password": { + "defaultMessage": "Hat Passwort" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Hat TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Wird geladen..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Zahlungsmethoden" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Profil anzeigen" + }, + "profile.details.title": { + "defaultMessage": "Nutzerdetails" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "E-Mail nicht verifiziert" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "E-Mail verifiziert" + }, + "profile.error.load-description": { + "defaultMessage": "Das Nutzerprofil konnte nicht geladen werden." + }, + "profile.error.not-found": { + "defaultMessage": "Nutzer nicht gefunden" + }, + "profile.label.affiliate": { + "defaultMessage": "Partner" + }, "profile.label.badges": { "defaultMessage": "Abzeichen" }, + "profile.label.collection": { + "defaultMessage": "Kollektion" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {Download} other {Downloads}}" + }, + "profile.label.joined": { + "defaultMessage": "Beigetreten" + }, + "profile.label.no-collections": { + "defaultMessage": "Dieser Nutzer hat keine Kollektionen!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Du hast noch keine Kollektionen." + }, + "profile.label.no-projects": { + "defaultMessage": "Dieser Nutzer hat keine Projekte!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Du hast noch keine Projekte." + }, + "profile.label.organizations": { + "defaultMessage": "Organisationen" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {Projekt} other {Projekte}}" + }, + "profile.official-account": { + "defaultMessage": "Offizielles Modrinth-Konto" + }, + "profile.official-account.bio": { + "defaultMessage": "Das offizielle Benutzerkonto von Modrinth. Erhalte Hilfe unter oder per E-Mail unter " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Beim Freigeben dieses Nutzers ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Nutzer konnte nicht freigegeben werden" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} wurde freigegeben." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Benutzer freigegeben" + }, "project-card.date.published.tooltip": { "defaultMessage": "Veröffentlicht am {date}" }, @@ -2879,6 +2996,9 @@ "project-type.all": { "defaultMessage": "Alle" }, + "project-type.collection.plural": { + "defaultMessage": "Kollektionen" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Datenpaket} other {Datenpakete}}" }, @@ -3671,15 +3791,6 @@ "search.filter_type.advanced": { "defaultMessage": "Erweitert" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Datenpakete ausschließen" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Mods ausschließen" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Plugins ausschließen" - }, "search.filter_type.environment": { "defaultMessage": "Umgebung" }, @@ -5105,9 +5216,120 @@ "settings.pats.title": { "defaultMessage": "Persönliche Zugangstoken" }, + "settings.profile.bio.description": { + "defaultMessage": "Eine kurze Beschreibung um allen ein bisschen von dir zu erzählen." + }, + "settings.profile.bio.title": { + "defaultMessage": "Bio" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Profilbild" + }, + "settings.profile.public-information.description": { + "defaultMessage": "Deine Profilinformationen sind öffentlich auf Modrinth und über die Modrinth-API sichtbar." + }, + "settings.profile.save-error": { + "defaultMessage": "Profil konnte nicht aktualisiert werden" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Beim Aktualisieren deines Profils ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Melde dich mit einem Modrinth-Konto an, um dein öffentliches Profil anzupassen." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Modrinth-Konto benötigt" + }, + "settings.profile.username.description": { + "defaultMessage": "Ein eindeutiger Name für dein Profil, bei dem Groß- und Kleinschreibung nicht unterschieden wird." + }, "settings.sessions.title": { "defaultMessage": "Sitzungen" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Aktionen" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Nutzer" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Dies sind die Benutzer, die du auf Modrinth blockiert hast. Diese können nicht:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Du hast niemanden blockiert." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Blockierte Nutzer konnten nicht geladen werden." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Blockierte Nutzer werden geladen…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Dir Freundschaftsanfragen senden" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Dich zu einem Modrinth-Hosting Server einladen." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Dich zu geteilten Instanzen einladen" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Blockierte Nutzer" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Freigeben" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Benutzer konnte nicht freigegeben werden" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Beim Freigeben dieses Nutzers ist ein Fehler aufgetreten. Bitte versuche es erneut." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "{username} freigeben" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Avatar von {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Lege fest, wer dir auf Modrinth Freundschaftsanfragen senden kann." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Freundschaftsanfragen" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Bald verfügbar!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Jeder" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Freunde" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Freunde von Freunden" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Niemand" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Steuere, wer dir Einladungen zu geteilten Instanzen und Modrinth-Hosting-Panels senden kann." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Einladungen" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Mit einem Modrinth-Konto kannst du festlegen, wer mit dir interagieren kann, und blockierte Nutzer verwalten" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Modrinth-Konto benötigt" + }, + "settings.social.title": { + "defaultMessage": "Sozial" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Hinzufügen" }, @@ -5117,14 +5339,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Dieser Benutzer wurde bereits eingeladen." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Anwenden" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Avatar von {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Abbrechen" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Benutzerdefiniert..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Abbrechen" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Benutzerdefiniert: {date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Einladungslink bearbeiten." @@ -5132,6 +5357,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "Einladungslink bearbeiten" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "In 1 Tag" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "In 1 Stunde" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "In 7 Tagen" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "In 6 Stunden" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "In 3 Tagen" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "In 12 Stunden" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Ablaufdatum" }, diff --git a/packages/ui/src/locales/en-US/index.json b/packages/ui/src/locales/en-US/index.json index f842c47c3d..aaa994bd13 100644 --- a/packages/ui/src/locales/en-US/index.json +++ b/packages/ui/src/locales/en-US/index.json @@ -92,6 +92,15 @@ "billing.resubscribe-modal.title": { "defaultMessage": "Resubscribe to Server" }, + "browse.advanced-filters.apply-saved-preferences": { + "defaultMessage": "Apply saved preferences" + }, + "browse.advanced-filters.link-overriding-preferences": { + "defaultMessage": "This link's filters differ from your saved advanced exclusions" + }, + "browse.advanced-filters.persistence-note": { + "defaultMessage": "Advanced exclusions are saved across sessions. Opening a shared link with filters will override them." + }, "browse.filter-results": { "defaultMessage": "Filter results..." }, @@ -131,6 +140,9 @@ "button.accept": { "defaultMessage": "Accept" }, + "button.add-another": { + "defaultMessage": "Add another" + }, "button.add-server-to-instance": { "defaultMessage": "Add server to instance" }, @@ -203,6 +215,9 @@ "button.hide-snapshots": { "defaultMessage": "Hide snapshots" }, + "button.i-understand": { + "defaultMessage": "I understand" + }, "button.install": { "defaultMessage": "Install" }, @@ -347,9 +362,15 @@ "content-type.item.lowercase": { "defaultMessage": "{count, plural, one {item} other {items}}" }, + "content.card.frozen": { + "defaultMessage": "This project is locked to its current version until unfrozen." + }, "content.card.select-project": { "defaultMessage": "Select {project}" }, + "content.card.uploaded": { + "defaultMessage": "Uploaded" + }, "content.confirm-bulk-update.admonition-body": { "defaultMessage": "Are you sure you want to update {count, plural, one {# project} other {# projects}} to their latest compatible version? It's recommended to update content one-by-one." }, @@ -507,7 +528,7 @@ "defaultMessage": "{count} removed (disabled)" }, "content.diff-modal.reviewed-files": { - "defaultMessage": "A file is only reviewed if it’s published to Modrinth, regardless of its file format (including .mrpack)." + "defaultMessage": "Files that aren't published to Modrinth aren't reviewed." }, "content.diff-modal.unknown-content-body": { "defaultMessage": "Some content on your server could not be analyzed and may be affected by this change." @@ -566,9 +587,96 @@ "content.inline-backup.world-label": { "defaultMessage": "world" }, - "content.modpack-card.installation-settings": { + "content.managed-card.managed-by": { + "defaultMessage": "Managed by" + }, + "content.managed-card.modpack-content": { + "defaultMessage": "Modpack content" + }, + "content.managed-card.server-suffix": { + "defaultMessage": "server" + }, + "content.managed-card.settings": { "defaultMessage": "Installation settings" }, + "content.managed-card.shared-content": { + "defaultMessage": "Shared content" + }, + "content.managed-card.summary.empty": { + "defaultMessage": "No managed content" + }, + "content.managed-card.summary.installing": { + "defaultMessage": "Installing content..." + }, + "content.managed-card.summary.loading": { + "defaultMessage": "Loading managed content summary" + }, + "content.managed-card.switch-version": { + "defaultMessage": "Switch version" + }, + "content.managed-card.synced": { + "defaultMessage": "Synced {time}" + }, + "content.managed-card.update-available": { + "defaultMessage": "Update available" + }, + "content.managed-card.updated": { + "defaultMessage": "Updated {time}" + }, + "content.managed-card.updating": { + "defaultMessage": "Updating..." + }, + "content.managed-card.view-content": { + "defaultMessage": "View content" + }, + "content.metadata-filter.author": { + "defaultMessage": "Author" + }, + "content.metadata-filter.environment": { + "defaultMessage": "Environment" + }, + "content.metadata-filter.open-source": { + "defaultMessage": "Open source" + }, + "content.metadata-filter.shared-content": { + "defaultMessage": "Shared content" + }, + "content.metadata-filter.source.external": { + "defaultMessage": "External" + }, + "content.metadata-filter.state": { + "defaultMessage": "State" + }, + "content.metadata-filter.state.disabled": { + "defaultMessage": "Disabled" + }, + "content.metadata-filter.state.enabled": { + "defaultMessage": "Enabled" + }, + "content.metadata-filter.update.available": { + "defaultMessage": "Update available" + }, + "content.metadata-filter.update.up-to-date": { + "defaultMessage": "Up to date" + }, + "content.metadata-filter.updates": { + "defaultMessage": "Updates" + }, + "content.metadata-filter.warning.client-depends": { + "defaultMessage": "Client depends on file" + }, + "content.metadata-filter.warning.client-only": { + "defaultMessage": "Client-only content" + }, + "content.metadata-filter.warning.client-retained": { + "defaultMessage": "Client file retained" + }, + "content.metadata-filter.warning.none": { + "defaultMessage": "No warnings" + }, + "content.metadata-filter.warnings": { + "defaultMessage": "Warnings" + }, "content.page-layout.additional-content": { "defaultMessage": "Additional content" }, @@ -593,6 +701,12 @@ "content.page-layout.failed-to-load": { "defaultMessage": "Failed to load content" }, + "content.page-layout.filter.add": { + "defaultMessage": "Filter" + }, + "content.page-layout.filter.author-count": { + "defaultMessage": "{count, plural, one {# author} other {# authors}}" + }, "content.page-layout.loading": { "defaultMessage": "Loading content..." }, @@ -620,8 +734,11 @@ "content.page-layout.share.project-names": { "defaultMessage": "Project names" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alphabetical" + "content.page-layout.sort.alphabetical-ascending": { + "defaultMessage": "Name (A-Z)" + }, + "content.page-layout.sort.alphabetical-descending": { + "defaultMessage": "Name (Z-A)" }, "content.page-layout.sort.date-added-newest": { "defaultMessage": "Newest first" @@ -956,6 +1073,9 @@ "creation-flow.title.set-up-server": { "defaultMessage": "Set up server" }, + "empty-state.upload-versions.description": { + "defaultMessage": "Come back once you've uploaded your versions." + }, "external-files.permissions-card.add-files-modal.confirm": { "defaultMessage": "{count, plural, one {Add file} other {Add files}}" }, @@ -1304,9 +1424,6 @@ "files.editor.file-saved-title": { "defaultMessage": "File saved" }, - "files.editor.find-close": { - "defaultMessage": "Close" - }, "files.editor.find-in-file": { "defaultMessage": "Find" }, @@ -1775,6 +1892,9 @@ "hosting.content.failed-to-upload": { "defaultMessage": "Failed to upload file" }, + "hosting.content.managed-content.modpack-header": { + "defaultMessage": "Modpack content" + }, "hosting.loader.failed-to-change-version": { "defaultMessage": "Failed to change modpack version" }, @@ -2084,31 +2204,31 @@ "instances.content-install.select-icon": { "defaultMessage": "Select icon" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "This modpack does not include any additional content." + "instances.managed-content-modal.empty-description": { + "defaultMessage": "This source does not include any managed content." }, - "instances.modpack-content-modal.empty-title": { + "instances.managed-content-modal.empty-title": { "defaultMessage": "No content found" }, - "instances.modpack-content-modal.external-content": { + "instances.managed-content-modal.external-content": { "defaultMessage": "External" }, - "instances.modpack-content-modal.external-content-description": { + "instances.managed-content-modal.external-content-description": { "defaultMessage": "This file is not published on Modrinth." }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Modpack content" + "instances.managed-content-modal.header": { + "defaultMessage": "Managed content" }, - "instances.modpack-content-modal.loading": { + "instances.managed-content-modal.loading": { "defaultMessage": "Loading content..." }, - "instances.modpack-content-modal.no-results": { + "instances.managed-content-modal.no-results": { "defaultMessage": "No projects match your search." }, - "instances.modpack-content-modal.open-in-slicer": { + "instances.managed-content-modal.open-in-slicer": { "defaultMessage": "Open in Slicer" }, - "instances.modpack-content-modal.search-placeholder": { + "instances.managed-content-modal.search-placeholder": { "defaultMessage": "Search {count, number} {count, plural, one {project} other {projects}}" }, "instances.updater-modal.badge.current": { @@ -2261,6 +2381,9 @@ "label.error": { "defaultMessage": "Error" }, + "label.explanation": { + "defaultMessage": "Explanation" + }, "label.extract-failed": { "defaultMessage": "Extract failed" }, @@ -2900,9 +3023,6 @@ "profile.button.create-project": { "defaultMessage": "Create a project" }, - "profile.button.edit-role": { - "defaultMessage": "Edit role" - }, "profile.button.info": { "defaultMessage": "View user details" }, @@ -2999,24 +3119,12 @@ "profile.label.project-count": { "defaultMessage": "{count, plural, one {project} other {projects}}" }, - "profile.label.saving": { - "defaultMessage": "Saving..." - }, "profile.official-account": { "defaultMessage": "Official Modrinth account" }, "profile.official-account.bio": { "defaultMessage": "The official user account of Modrinth. Get support at or via email at " }, - "profile.role.select-placeholder": { - "defaultMessage": "Select a role" - }, - "profile.role.update-error-description": { - "defaultMessage": "An error occurred while updating the user role. Please try again." - }, - "profile.role.update-error-title": { - "defaultMessage": "Failed to update role" - }, "profile.unblock-user.error-description": { "defaultMessage": "An error occurred while unblocking this user. Please try again." }, @@ -3257,6 +3365,48 @@ "project.about.tags.title": { "defaultMessage": "Tags" }, + "project.disclosure.advertising.title": { + "defaultMessage": "Contains advertising" + }, + "project.disclosure.ai-generated-content.title": { + "defaultMessage": "Contains AI-generated {types}" + }, + "project.disclosure.ai-generated-content.use.assets": { + "defaultMessage": "assets" + }, + "project.disclosure.ai-generated-content.use.code": { + "defaultMessage": "code" + }, + "project.disclosure.ai-generated-content.use.content": { + "defaultMessage": "content" + }, + "project.disclosure.ai-generated-content.use.functionality": { + "defaultMessage": "functionality" + }, + "project.disclosure.ai-generated-content.use.text": { + "defaultMessage": "text" + }, + "project.disclosure.derivative-work.show-fewer": { + "defaultMessage": "Show fewer" + }, + "project.disclosure.derivative-work.show-more": { + "defaultMessage": "Show {count} more" + }, + "project.disclosure.derivative-work.title": { + "defaultMessage": "This is a derivative work of:" + }, + "project.disclosure.paid-features.title": { + "defaultMessage": "Contains paid features" + }, + "project.disclosure.photosensitivity.title": { + "defaultMessage": "Photosensitivity warning" + }, + "project.disclosure.system-interactions.title": { + "defaultMessage": "Contains external system interactions" + }, + "project.disclosure.telemetry.title": { + "defaultMessage": "Contains {consent, select, opt_in {opt-in telemetry} opt_out {opt-out telemetry} always_active {always-active telemetry} other {telemetry}}" + }, "project.download-count-tooltip": { "defaultMessage": "{count, number} {count, plural, one {download} other {downloads}}" }, @@ -3620,6 +3770,30 @@ "project.settings.description.title": { "defaultMessage": "Description" }, + "project.settings.disclosures.ai.types-assets": { + "defaultMessage": "Assets" + }, + "project.settings.disclosures.ai.types-code": { + "defaultMessage": "Code" + }, + "project.settings.disclosures.ai.types-functionality": { + "defaultMessage": "Functionality" + }, + "project.settings.disclosures.ai.types-text": { + "defaultMessage": "Text" + }, + "project.settings.disclosures.telemetry.consent-always-active": { + "defaultMessage": "Always active" + }, + "project.settings.disclosures.telemetry.consent-opt-in": { + "defaultMessage": "Opt-in" + }, + "project.settings.disclosures.telemetry.consent-opt-out": { + "defaultMessage": "Opt-out" + }, + "project.settings.disclosures.title": { + "defaultMessage": "Disclosures" + }, "project.settings.environment.client_and_server.description": { "defaultMessage": "Has some functionality on both the client and server, even if only partially." }, @@ -3749,6 +3923,12 @@ "project.stats.followers-label": { "defaultMessage": "{count, plural, one {follower} other {followers}}" }, + "project.status.archived.body": { + "defaultMessage": "{title} will not receive any further updates unless the author decides to unarchive the project." + }, + "project.status.archived.header": { + "defaultMessage": "{title} has been archived" + }, "project.versions.channel.alpha.symbol": { "defaultMessage": "A" }, @@ -3815,6 +3995,24 @@ "report.item-type.version": { "defaultMessage": "version" }, + "report.type.copyright": { + "defaultMessage": "Reuploaded work" + }, + "report.type.inappropriate": { + "defaultMessage": "Inappropriate" + }, + "report.type.malicious": { + "defaultMessage": "Malicious" + }, + "report.type.missing-disclosure": { + "defaultMessage": "Missing or incorrect disclosure" + }, + "report.type.name-squatting": { + "defaultMessage": "Name squatting" + }, + "report.type.spam": { + "defaultMessage": "Spam" + }, "s.bg": { "defaultMessage": "Background task running" }, @@ -3848,17 +4046,41 @@ "search.filter.option.show_more": { "defaultMessage": "Show more" }, + "search.filter.option.sub_options.collapse.tooltip": { + "defaultMessage": "Hide more options" + }, + "search.filter.option.sub_options.expand.tooltip": { + "defaultMessage": "Show more options" + }, "search.filter_type.advanced": { - "defaultMessage": "Advanced" + "defaultMessage": "Advanced exclusions" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Exclude data packs" + "search.filter_type.advanced.disclosure.advertisements": { + "defaultMessage": "Advertisements" }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Exclude mods" + "search.filter_type.advanced.disclosure.ai_content": { + "defaultMessage": "AI-generated content" }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Exclude plugins" + "search.filter_type.advanced.disclosure.ai_content.usage": { + "defaultMessage": "AI {usage}" + }, + "search.filter_type.advanced.disclosure.archived": { + "defaultMessage": "Archived" + }, + "search.filter_type.advanced.disclosure.derivative_work": { + "defaultMessage": "Derivative content" + }, + "search.filter_type.advanced.disclosure.epilepsy_triggers": { + "defaultMessage": "Photosensitivity triggers" + }, + "search.filter_type.advanced.disclosure.paid_features": { + "defaultMessage": "Paid features" + }, + "search.filter_type.advanced.disclosure.system_interactions": { + "defaultMessage": "External system interactions" + }, + "search.filter_type.advanced.disclosure.telemetry": { + "defaultMessage": "Telemetry" }, "search.filter_type.environment": { "defaultMessage": "Environment" @@ -3911,6 +4133,21 @@ "search.filter_type.shader_loader": { "defaultMessage": "Loader" }, + "search.photosensitivity-warning-modal.body.1": { + "defaultMessage": "We cannot guarantee that all content on Modrinth has been labeled appropriately." + }, + "search.photosensitivity-warning-modal.body.2": { + "defaultMessage": "Content labels for photosensitivity triggers are self-assigned by the creators who upload their content to Modrinth. These projects have not gone through any safety testing." + }, + "search.photosensitivity-warning-modal.body.3": { + "defaultMessage": "Using any content on Modrinth is at your own risk. Please stay safe! 💚" + }, + "search.photosensitivity-warning-modal.dont-show-again": { + "defaultMessage": "Don't show this again" + }, + "search.photosensitivity-warning-modal.title": { + "defaultMessage": "Results are not guaranteed to be safe" + }, "search.server_content_type.modpack": { "defaultMessage": "Modded" }, @@ -5252,6 +5489,9 @@ "settings.feature-flags.title": { "defaultMessage": "Feature flags" }, + "settings.form.group.optional": { + "defaultMessage": "(optional)" + }, "settings.language.categories.default": { "defaultMessage": "Standard languages" }, @@ -5414,12 +5654,6 @@ "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "{username}'s avatar" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Cancel" - }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Cancel" - }, "sharing.invite-players-modal.custom-expiry": { "defaultMessage": "Custom..." }, @@ -6063,7 +6297,7 @@ "defaultMessage": "Unknown files warning" }, "unknown-file-warning-modal.reviewed-files": { - "defaultMessage": "A file is only reviewed if it’s published to Modrinth, regardless of its file format (including .mrpack)." + "defaultMessage": "Files that aren't published to Modrinth aren't reviewed." }, "unknown-file-warning-modal.unrecognized-files": { "defaultMessage": "Unrecognized files" diff --git a/packages/ui/src/locales/es-419/index.json b/packages/ui/src/locales/es-419/index.json index 700b0fd3dd..f19710b8a4 100644 --- a/packages/ui/src/locales/es-419/index.json +++ b/packages/ui/src/locales/es-419/index.json @@ -39,7 +39,7 @@ "defaultMessage": "Error al cargar la configuración del servidor" }, "badge.alpha": { - "defaultMessage": "Alpha" + "defaultMessage": "Alfa" }, "badge.beta": { "defaultMessage": "Beta" @@ -377,6 +377,9 @@ "content.confirm-deletion.header": { "defaultMessage": "Eliminar {itemType}" }, + "content.confirm-disable.header": { + "defaultMessage": "Desactivar {itemType}" + }, "content.confirm-modpack-update.admonition-body": { "defaultMessage": "{action, select, downgrade {Bajar de versión} other {Actualizar}} puede causar problemas de compatibilidad. Los mods o contenido que agregaste sobre el modpack se mantendrán, pero podrían no ser compatibles con la nueva versión." }, @@ -446,33 +449,63 @@ "content.diff-modal.added-count": { "defaultMessage": "{count} añadido" }, + "content.diff-modal.config-files-updated": { + "defaultMessage": "Archivos de configuración cambiados" + }, "content.diff-modal.diff-type.added": { - "defaultMessage": "Añadido (dependencia)" + "defaultMessage": "Se añadió (dependencia)" }, "content.diff-modal.diff-type.removed": { - "defaultMessage": "Desactivado" + "defaultMessage": "Se desactivó" + }, + "content.diff-modal.diff-type.removed-disabled": { + "defaultMessage": "Se eliminó (desactivado)" }, "content.diff-modal.diff-type.updated": { - "defaultMessage": "Actualizado" + "defaultMessage": "Se actualizó" }, "content.diff-modal.dont-install": { "defaultMessage": "No instalar" }, "content.diff-modal.external-diff-type.added": { - "defaultMessage": "Agregado" + "defaultMessage": "Se añadió" }, "content.diff-modal.external-diff-type.removed": { - "defaultMessage": "Eliminado" + "defaultMessage": "Se eliminó" }, "content.diff-modal.external-diff-type.updated": { - "defaultMessage": "Actualizado" + "defaultMessage": "Se actualizó" + }, + "content.diff-modal.file-count": { + "defaultMessage": "{count, plural, one {# archivo} other {# archivos}}" + }, + "content.diff-modal.game-version-updated": { + "defaultMessage": "Versión del juego" }, "content.diff-modal.install-anyway": { "defaultMessage": "Instalar de todos modos" }, + "content.diff-modal.loader-updated": { + "defaultMessage": "Loader" + }, + "content.diff-modal.modpack-linked": { + "defaultMessage": "Modpack vinculado" + }, + "content.diff-modal.modpack-unlinked": { + "defaultMessage": "Modpack desvinculado" + }, + "content.diff-modal.modpack-updated": { + "defaultMessage": "Modpack actualizado" + }, + "content.diff-modal.no-content-changes": { + "defaultMessage": "Sin cambios al contenido" + }, "content.diff-modal.removed-count": { "defaultMessage": "{count} eliminados" }, + "content.diff-modal.removed-disabled-count": { + "defaultMessage": "{count} eliminados (desactivados)" + }, "content.diff-modal.reviewed-files": { "defaultMessage": "Un archivo solo se revisa si se publica en Modrinth, sin importar su formato (incluido el .mrpack)." }, @@ -584,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nombres de los proyectos" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Allfabético" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Más recientes primero" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Más antiguo primero" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Ordenar por {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Actualizar todo" }, @@ -921,7 +942,7 @@ "defaultMessage": "Configurar servidor" }, "external-files.permissions-card.add-files-modal.confirm": { - "defaultMessage": "{count, plural, one {Agregar archivo} other {Agregar archivos}}" + "defaultMessage": "{count, plural, one {Añadir archivo} other {Añadir archivos}}" }, "external-files.permissions-card.add-files-modal.description": { "defaultMessage": "Selecciona cualquier archivo que deba ser movido a este grupo." @@ -930,7 +951,7 @@ "defaultMessage": "No hay archivos en otros grupos que se puedan mover aquí." }, "external-files.permissions-card.add-files-modal.load-error.title": { - "defaultMessage": "No se pudieron cargar los archivos." + "defaultMessage": "No se pudieron cargar los archivos" }, "external-files.permissions-card.add-files-modal.no-search-results": { "defaultMessage": "No hay archivos que coincidan con tu búsqueda." @@ -945,10 +966,10 @@ "defaultMessage": "Añadir archivos a este grupo" }, "external-files.permissions-card.add-files-to-group": { - "defaultMessage": "Agregar archivos..." + "defaultMessage": "Añadir archivos..." }, "external-files.permissions-card.assign-files-error.title": { - "defaultMessage": "No se pudieron agregar los archivos" + "defaultMessage": "No se pudieron añadir los archivos" }, "external-files.permissions-card.attribution.moderation-status.content-not-allowed": { "defaultMessage": "Contenido no permitido" @@ -1077,7 +1098,7 @@ "defaultMessage": "Grupo de atribución {id}" }, "external-files.permissions-card.file-count": { - "defaultMessage": "{count, plural, one {Agregar archivo} other {Agregar archivos}}" + "defaultMessage": "{count, plural, one {Añadir archivo} other {Añadir archivos}}" }, "external-files.permissions-card.included-files": { "defaultMessage": "Archivos incluidos:" @@ -1101,7 +1122,7 @@ "defaultMessage": "Motivo" }, "external-files.permissions-card.moderation.error.title": { - "defaultMessage": "No se pudo guardar la revisión de moderación." + "defaultMessage": "No se pudo guardar la revisión de moderación" }, "external-files.permissions-card.not-used-in-versions": { "defaultMessage": "Estos archivos no están siendo utilizados actualmente por ninguna versión." @@ -1160,6 +1181,21 @@ "external-files.permissions-card.reason.special-permission.description": { "defaultMessage": "Has obtenido permiso especial para redistribuir este trabajo en tu modpack." }, + "external-files.permissions-card.remove-group": { + "defaultMessage": "Borrar grupo" + }, + "external-files.permissions-card.remove-group-confirmation.description": { + "defaultMessage": "Esto eliminará permanentemente este grupo de atribución y todos los archivos dentro. Esta acción no se puede deshacer." + }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "¿Borrar {title}?" + }, + "external-files.permissions-card.remove-group-error.title": { + "defaultMessage": "No se pudo borrar el grupo" + }, + "external-files.permissions-card.remove-group-shift-hint": { + "defaultMessage": "Mantén Shift al hacer clic para saltar la confirmación." + }, "external-files.permissions-card.split-file": { "defaultMessage": "Eliminar del grupo" }, @@ -1253,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Archivo guardado" }, - "files.editor.find-close": { - "defaultMessage": "Cerrar" - }, "files.editor.find-in-file": { "defaultMessage": "Buscar" }, @@ -1899,7 +1932,7 @@ "defaultMessage": "Reinstalando modpack" }, "installation-settings.removed-incompatible": { - "defaultMessage": "Eliminado (incompatible)" + "defaultMessage": "Se eliminó (incompatible)" }, "installation-settings.repair.instance-description": { "defaultMessage": "Reinstala las dependencias de Minecraft y verifica si hay archivos corruptos. Esto puede solucionar problemas si tu juego no se inicia debido a errores relacionados con el launcher." @@ -2033,24 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Seleccionar ícono" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Este modpack no incluye ningún contenido adicional." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "No se encontró contenido" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Contenido del modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Cargando contenido..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Ningún proyecto coincide con tu búsqueda." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Buscar en {count, number} {count, plural, one {proyecto} other {proyectos}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Actual" }, @@ -2183,6 +2198,9 @@ "label.details": { "defaultMessage": "Detalles" }, + "label.discover-content": { + "defaultMessage": "Descubrir contenido" + }, "label.done": { "defaultMessage": "Listo" }, @@ -2261,6 +2279,9 @@ "label.password": { "defaultMessage": "Contraseña" }, + "label.permissions": { + "defaultMessage": "Permisos" + }, "label.plan-custom": { "defaultMessage": "Personalizado" }, @@ -2616,7 +2637,7 @@ "defaultMessage": "URL del video de YouTube" }, "modal.add-payment-method.action": { - "defaultMessage": "Agregar método de pago" + "defaultMessage": "Añadir método de pago" }, "modal.add-payment-method.title": { "defaultMessage": "Añadiendo método de pago" @@ -2792,9 +2813,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Un creador de Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Un usuario de Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} no podrá enviarte solicitudes de amistad, invitarte a instancias compartidas o invitarte a servidores de Modrinth Hosting." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "¿Estás seguro de que quieres bloquear a este usuario?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Ocurrió un error al bloquear a este usuario. Por favor inténtalo otra vez." + }, + "profile.block-user.error-title": { + "defaultMessage": "Error al bloquear usuario" + }, + "profile.block-user.success-description": { + "defaultMessage": "Bloqueaste a {username}." + }, + "profile.block-user.success-title": { + "defaultMessage": "Usuario bloqueado" + }, + "profile.block-user.title": { + "defaultMessage": "Bloquear a {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Ver analíticas del usuario" + }, + "profile.button.billing": { + "defaultMessage": "Gestionar facturación del usuario" + }, + "profile.button.block": { + "defaultMessage": "Bloquear" + }, + "profile.button.create-collection": { + "defaultMessage": "Crear una colección" + }, + "profile.button.create-project": { + "defaultMessage": "Crear un proyecto" + }, + "profile.button.info": { + "defaultMessage": "Ver detalles del usuario" + }, + "profile.button.manage-projects": { + "defaultMessage": "Gestionar proyectos" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Remover como afiliado" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Configurar como afiliado" + }, + "profile.button.unblock": { + "defaultMessage": "Desbloquear" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# proyecto} other {# proyectos}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Permite las ventanas emergentes para Modrinth, y luego vuelve a intentarlo." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Este perfil de GitHub no pudo ser cargado. Por favor inténtalo otra vez." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Error al abrir el perfil de GitHub" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Proveedores de autenticación" + }, + "profile.details.label.email-verified": { + "defaultMessage": "Correo verificado" + }, + "profile.details.label.has-password": { + "defaultMessage": "Tiene contraseña" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Tiene TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Cargando..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Métodos de pago" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Ver perfil" + }, + "profile.details.title": { + "defaultMessage": "Detalles de usuario" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "Correo sin verificar" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "Correo verificado" + }, + "profile.error.load-description": { + "defaultMessage": "Este perfil de usuario no se pudo cargar." + }, + "profile.error.not-found": { + "defaultMessage": "Usuario no encontrado" + }, + "profile.label.affiliate": { + "defaultMessage": "Afiliado" + }, "profile.label.badges": { "defaultMessage": "Insignias" }, + "profile.label.collection": { + "defaultMessage": "Colección" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {descarga} other {descargas}}" + }, + "profile.label.joined": { + "defaultMessage": "Se unió" + }, + "profile.label.no-collections": { + "defaultMessage": "¡Este usuario no tiene colecciones!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Todavía no tienes ninguna colección." + }, + "profile.label.no-projects": { + "defaultMessage": "¡Este usuario no tiene proyectos!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Todavía no tienes ningún proyecto." + }, + "profile.label.organizations": { + "defaultMessage": "Organizaciones" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {proyecto} other {proyectos}}" + }, + "profile.official-account": { + "defaultMessage": "Cuenta oficial de Modrinth" + }, + "profile.official-account.bio": { + "defaultMessage": "La cuenta oficial de Modrinth. Consigue ayuda en o escríbenos por correo electrónico: " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Ocurrió un error al desbloquear a este usuario. Por favor inténtalo otra vez." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Error al desbloquear usuario" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "Desbloqueaste a {username}." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Usuario desbloqueado" + }, "project-card.date.published.tooltip": { "defaultMessage": "Publicado el {date}" }, @@ -2810,12 +2984,21 @@ "project-card.environment.client-or-server": { "defaultMessage": "Cliente o servidor" }, + "project-card.environment.dedicated-server": { + "defaultMessage": "Servidor dedicado" + }, "project-card.environment.server": { "defaultMessage": "Servidor" }, + "project-card.environment.singleplayer": { + "defaultMessage": "Un solo jugador" + }, "project-type.all": { "defaultMessage": "Todo" }, + "project-type.collection.plural": { + "defaultMessage": "Colecciones" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Data Pack} other {Data Packs}}" }, @@ -2943,7 +3126,7 @@ "defaultMessage": "Enviado {date}" }, "project.about.details.updated": { - "defaultMessage": "Actualizado {date}" + "defaultMessage": "Actualizado el {date}" }, "project.about.links.discord": { "defaultMessage": "Únete al servidor de Discord" @@ -3086,6 +3269,15 @@ "project.follower-count-tooltip": { "defaultMessage": "{count, number} {count, plural, one {seguidor} other {seguidores}}" }, + "project.license.error": { + "defaultMessage": "No se pudo conseguir el texto de la licencia." + }, + "project.license.loading": { + "defaultMessage": "Cargando el texto de la licencia..." + }, + "project.license.title": { + "defaultMessage": "Licencia" + }, "project.online-player-count": { "defaultMessage": "{count, number} en línea" }, @@ -3491,6 +3683,12 @@ "project.settings.view.title": { "defaultMessage": "Ver" }, + "project.stats.downloads-label": { + "defaultMessage": "{count, plural, one {descarga} other {descargas}}" + }, + "project.stats.followers-label": { + "defaultMessage": "{count, plural, one {seguidor} other {seguidores}}" + }, "project.versions.channel.alpha.symbol": { "defaultMessage": "A" }, @@ -3593,15 +3791,6 @@ "search.filter_type.advanced": { "defaultMessage": "Avanzado" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Excluir paquetes de datos" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Excluir mods" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Excluir complementos" - }, "search.filter_type.environment": { "defaultMessage": "Entorno" }, @@ -5022,14 +5211,221 @@ "defaultMessage": "Idioma" }, "settings.language.warning": { - "defaultMessage": "Cambiar el idioma de {platform} podría provocar que parte del contenido aparezca en inglés si no hay una traducción disponible. {platform} Aún no está completamente traducida, por lo que parte del contenido podría permanecer en inglés en ciertos idiomas." + "defaultMessage": "Cambiar el idioma de la {platform} podría provocar que parte del contenido aparezca en inglés si no hay una traducción disponible. La {platform} aún no está completamente traducida, por lo que parte del contenido podría permanecer en inglés en ciertos idiomas." }, "settings.pats.title": { "defaultMessage": "Tokens de acceso personal" }, + "settings.profile.bio.description": { + "defaultMessage": "Una descripción corta que le cuente a todos un poquito sobre tí." + }, + "settings.profile.bio.title": { + "defaultMessage": "Biografía" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Perfil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Foto de perfil" + }, + "settings.profile.public-information.description": { + "defaultMessage": "La información de tu perfil es visible públicamente en Modrinth y también a través de la Modrinth API." + }, + "settings.profile.save-error": { + "defaultMessage": "Error al actualizar perfil" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Ocurrió un error al actualizar tu perfil. Por favor inténtalo otra vez." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Regístrate con una cuenta Modrinth para personalizar tu perfil." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Cuenta Modrinth requerida" + }, + "settings.profile.username.description": { + "defaultMessage": "Un nombre único, sin distinción de mayúsculas y minúsculas, para identificar tu perfil." + }, "settings.sessions.title": { "defaultMessage": "Sesiones" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Acciones" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Usuario" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Estos son los usuarios que has bloqueado en Modrinth. Ellos no pueden:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "No has bloqueado a nadie." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "No se pudo cargar los usuarios bloqueados." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Cargando usuarios bloqueados…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Enviarte solicitudes de amistad" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Invitarte a gestionar un servidor de Modrinth Hosting." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Invitarte a instancias compartidas" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Usuarios bloqueados" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Desbloquear" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Error al desbloquear usuario" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Ocurrió un error al desbloquear a este usuario. Por favor inténtalo otra vez." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Desbloquear a {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Avatar de {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Controla quién puede enviarte solicitudes de amistad en Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Solicitudes de amistad" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "¡Próximamente!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Todos" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Amigos" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Amigos de amigos" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Nadie" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Controla quién te puede enviar invitaciones a instancias compartidas y paneles de Modrinth Hosting." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Invitaciones" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Puedes controlar quién puede interactuar contigo, y gestionar los usuarios bloqueados con una Cuenta Modrinth" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Cuenta Modrinth requerida" + }, + "settings.social.title": { + "defaultMessage": "Social" + }, + "sharing.invite-players-modal.add": { + "defaultMessage": "Añadir" + }, + "sharing.invite-players-modal.added": { + "defaultMessage": "Añadido" + }, + "sharing.invite-players-modal.already-invited": { + "defaultMessage": "Este usuario ya fue invitado." + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Aplicar" + }, + "sharing.invite-players-modal.avatar-alt": { + "defaultMessage": "Avatar de {username}" + }, + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Otro..." + }, + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Otro: {date}" + }, + "sharing.invite-players-modal.edit-invite-link": { + "defaultMessage": "Editar link de invitación." + }, + "sharing.invite-players-modal.edit-invite-link-title": { + "defaultMessage": "Editar link de invitación" + }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "En 1 día" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "En 1 hora" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "En 7 días" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "En 6 horas" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "En 3 días" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "En 12 horas" + }, + "sharing.invite-players-modal.expiry-label": { + "defaultMessage": "Fecha de expiración" + }, + "sharing.invite-players-modal.friends-heading": { + "defaultMessage": "Tus amigos - {count}" + }, + "sharing.invite-players-modal.invite": { + "defaultMessage": "Invitar" + }, + "sharing.invite-players-modal.invite-expiry-description": { + "defaultMessage": "Tu link de invitación expira en {duration}." + }, + "sharing.invite-players-modal.invite-link-heading": { + "defaultMessage": "O usa un link de invitación" + }, + "sharing.invite-players-modal.link-copied-text": { + "defaultMessage": "El link de invitación fue copiado a tu portapapeles." + }, + "sharing.invite-players-modal.link-copied-title": { + "defaultMessage": "Link copiado" + }, + "sharing.invite-players-modal.link-copy-failed-title": { + "defaultMessage": "Error al copiar link" + }, + "sharing.invite-players-modal.max-uses-label": { + "defaultMessage": "Usos máximos" + }, + "sharing.invite-players-modal.no-friends": { + "defaultMessage": "No tienes amigos." + }, + "sharing.invite-players-modal.no-search-results": { + "defaultMessage": "No se encontró ningún usuario coincidente." + }, + "sharing.invite-players-modal.requested": { + "defaultMessage": "Solicitud enviada" + }, + "sharing.invite-players-modal.requested-tooltip": { + "defaultMessage": "{username} debe aceptar tu solicitud de amistad primero" + }, + "sharing.invite-players-modal.save-button": { + "defaultMessage": "Guardar" + }, + "sharing.invite-players-modal.search-placeholder": { + "defaultMessage": "Introduce el nombre de usuario de Modrinth" + }, + "sharing.invite-players-modal.searching": { + "defaultMessage": "Buscando..." + }, + "sharing.invite-players-modal.update-invite-link-failed-title": { + "defaultMessage": "Error al actualizar link de invitación" + }, "tag.category.128x": { "defaultMessage": "128x" }, @@ -5181,7 +5577,7 @@ "defaultMessage": "Kit PvP" }, "tag.category.library": { - "defaultMessage": "Librería" + "defaultMessage": "Biblioteca" }, "tag.category.lifesteal": { "defaultMessage": "Lifesteal" @@ -5445,7 +5841,7 @@ "defaultMessage": "Sponge" }, "tag.loader.vanilla": { - "defaultMessage": "Shader vanilla" + "defaultMessage": "Shader Vanilla" }, "tag.loader.velocity": { "defaultMessage": "Velocity" diff --git a/packages/ui/src/locales/es-ES/index.json b/packages/ui/src/locales/es-ES/index.json index bfeabbbb50..0f497a9b33 100644 --- a/packages/ui/src/locales/es-ES/index.json +++ b/packages/ui/src/locales/es-ES/index.json @@ -221,6 +221,9 @@ "button.open-folder": { "defaultMessage": "Abrir carpeta" }, + "button.open-in-browser": { + "defaultMessage": "Abrir en el navegador" + }, "button.open-in-folder": { "defaultMessage": "Abrir en carpeta" }, @@ -236,6 +239,9 @@ "button.reinstall-modpack": { "defaultMessage": "Reinstalar modpack" }, + "button.remove": { + "defaultMessage": "Eliminar" + }, "button.remove-image": { "defaultMessage": "Eliminar imagen" }, @@ -287,6 +293,9 @@ "button.stop": { "defaultMessage": "Detener" }, + "button.switch-to-version": { + "defaultMessage": "Cambiar a la versión" + }, "button.switch-version": { "defaultMessage": "Cambiar versión" }, @@ -314,6 +323,21 @@ "changelog.product.web": { "defaultMessage": "Plataforma" }, + "collection-widget.empty-collection": { + "defaultMessage": "Esta colección está vacía." + }, + "collection-widget.loading-projects": { + "defaultMessage": "Cargando proyectos..." + }, + "collection-widget.no-search-results": { + "defaultMessage": "No proyectos coinciden con tu búsqueda." + }, + "collection-widget.project-count": { + "defaultMessage": "{count, plural, one {# proyecto} other {# proyectos}}" + }, + "collection-widget.search-placeholder": { + "defaultMessage": "Buscar proyectos" + }, "collections.label.private": { "defaultMessage": "Privado" }, @@ -353,6 +377,9 @@ "content.confirm-deletion.header": { "defaultMessage": "Borrar {itemType}" }, + "content.confirm-disable.header": { + "defaultMessage": "Desactivar {itemType}" + }, "content.confirm-modpack-update.admonition-body": { "defaultMessage": "{action, select,downgrade {Bajar de versión} other {Actualizar}} puede causar problemas de compatibilidad. Mods o contenido que tu has añandido encima del modpack se quedara, pero no podria ser compatible con la nueva version." }, @@ -422,21 +449,78 @@ "content.diff-modal.added-count": { "defaultMessage": "{count} añadido/s" }, + "content.diff-modal.config-files-updated": { + "defaultMessage": "Archivos de configuración modificados" + }, "content.diff-modal.diff-type.added": { "defaultMessage": "Añadido (dependencia)" }, "content.diff-modal.diff-type.removed": { "defaultMessage": "Desactivado" }, + "content.diff-modal.diff-type.removed-disabled": { + "defaultMessage": "Removido (desactivado)" + }, "content.diff-modal.diff-type.updated": { "defaultMessage": "Actualizado" }, + "content.diff-modal.dont-install": { + "defaultMessage": "No instalar" + }, + "content.diff-modal.external-diff-type.added": { + "defaultMessage": "Añadido" + }, + "content.diff-modal.external-diff-type.removed": { + "defaultMessage": "Eliminado" + }, + "content.diff-modal.external-diff-type.updated": { + "defaultMessage": "Actualizado" + }, + "content.diff-modal.file-count": { + "defaultMessage": "{count, plural, one {# archivo} other {# archivos}}" + }, + "content.diff-modal.game-version-updated": { + "defaultMessage": "Versión del juego" + }, + "content.diff-modal.install-anyway": { + "defaultMessage": "Instalar de todas formas" + }, + "content.diff-modal.loader-updated": { + "defaultMessage": "Cargador" + }, + "content.diff-modal.modpack-linked": { + "defaultMessage": "Modpack vinculado" + }, + "content.diff-modal.modpack-unlinked": { + "defaultMessage": "Modpack desvinculado" + }, + "content.diff-modal.modpack-updated": { + "defaultMessage": "Modpack actualizado" + }, + "content.diff-modal.no-content-changes": { + "defaultMessage": "No hay cambios en el contenido" + }, "content.diff-modal.removed-count": { "defaultMessage": "{count} eliminado" }, + "content.diff-modal.removed-disabled-count": { + "defaultMessage": "{count} removido (desactivado)" + }, + "content.diff-modal.reviewed-files": { + "defaultMessage": "Un archivo es revisado si es que está publicado en Modrinth, sin imputar su formato de archivo (Incluyendo .mrpack)." + }, "content.diff-modal.unknown-content-body": { "defaultMessage": "No se ha podido analizar parte del contenido de su servidor, por lo que podría verse afectado por este cambio." }, + "content.diff-modal.unknown-files-description": { + "defaultMessage": "Esta actualización contiene archivos que no están publicados en Modrinth. Te recomendamos instalar archivos de fuentes de confianza." + }, + "content.diff-modal.unknown-files-warning": { + "defaultMessage": "Advertencia de archivos desconocidos" + }, + "content.diff-modal.unknown-project": { + "defaultMessage": "Desconocido" + }, "content.diff-modal.updated-count": { "defaultMessage": "{count} actualizado/s" }, @@ -533,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nombres de los proyectos" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Por orden alfabético" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Más recientes primero" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Más antiguo primero" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Ordenar por {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Actualizar todo" }, @@ -560,24 +632,36 @@ "content.selection-bar.bulk.deleting": { "defaultMessage": "Eliminando {progress}/{total} {contentType}..." }, + "content.selection-bar.bulk.deleting-count": { + "defaultMessage": "Eliminando {count, number} {contentType}" + }, "content.selection-bar.bulk.deleting-waiting": { "defaultMessage": "Eliminando {contentType}..." }, "content.selection-bar.bulk.disabling": { "defaultMessage": "Desactivando {progress}/{total} {contentType}..." }, + "content.selection-bar.bulk.disabling-count": { + "defaultMessage": "Desactivando {count, number} {contentType}" + }, "content.selection-bar.bulk.disabling-waiting": { "defaultMessage": "Desactivando {contentType}..." }, "content.selection-bar.bulk.enabling": { "defaultMessage": "Activando {progress}/{total} {contentType}..." }, + "content.selection-bar.bulk.enabling-count": { + "defaultMessage": "Activando {count, number} {contentType}" + }, "content.selection-bar.bulk.enabling-waiting": { "defaultMessage": "Activando {contentType}..." }, "content.selection-bar.bulk.updating": { "defaultMessage": "Actualizando {progress}/{total} {contentType}..." }, + "content.selection-bar.bulk.updating-count": { + "defaultMessage": "Actualizando {count, number} {contentType}" + }, "content.selection-bar.bulk.updating-waiting": { "defaultMessage": "Actualizando {contentType}..." }, @@ -872,6 +956,9 @@ "external-files.permissions-card.add-files-modal.no-search-results": { "defaultMessage": "No hay archivos que coincidan con tu búsqueda." }, + "external-files.permissions-card.add-files-modal.search-placeholder": { + "defaultMessage": "Buscar archivos..." + }, "external-files.permissions-card.add-files-modal.selected-count": { "defaultMessage": "{count, plural, one {# archivo seleccionado} other {# archivos seleccionados}}" }, @@ -1094,6 +1181,21 @@ "external-files.permissions-card.reason.special-permission.description": { "defaultMessage": "Has obtenido permiso especial para redistribuir este trabajo en tu modpack." }, + "external-files.permissions-card.remove-group": { + "defaultMessage": "Eliminar grupo" + }, + "external-files.permissions-card.remove-group-confirmation.description": { + "defaultMessage": "Esto elimina permanentemente el grupo de atribución y todos los archivos dentro de ellos. Esta ación no se puede deshacer." + }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "¿Borrar {title}?" + }, + "external-files.permissions-card.remove-group-error.title": { + "defaultMessage": "No se pudo eliminar el grupo" + }, + "external-files.permissions-card.remove-group-shift-hint": { + "defaultMessage": "Mantén pulsada el Shift mientras haces clic para omitir la confirmación." + }, "external-files.permissions-card.split-file": { "defaultMessage": "Eliminar del grupo" }, @@ -1187,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Archivo guardado" }, - "files.editor.find-close": { - "defaultMessage": "Cerrar" - }, "files.editor.find-in-file": { "defaultMessage": "Encontrar" }, @@ -1379,6 +1478,9 @@ "files.row.item-count": { "defaultMessage": "{count, plural, one {# elemento} other {# elementos}}" }, + "files.row.parent-folder": { + "defaultMessage": "Carpeta principal" + }, "files.table-header.created": { "defaultMessage": "Creado" }, @@ -1964,24 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Seleccionar icono" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Este modpack no incluye contenido adicional." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "No se ha encontrado contenido" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Contenido del modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Cargando contenido..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "No hay proyectos que coincidan con tu búsqueda." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Buscar {count, number} {count, plural, one {proyecto} other {proyectos}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Actual" }, @@ -2111,6 +2195,9 @@ "label.details": { "defaultMessage": "Detalles" }, + "label.discover-content": { + "defaultMessage": "Descubrir contenido" + }, "label.done": { "defaultMessage": "Hecho" }, @@ -2141,6 +2228,9 @@ "label.game-version": { "defaultMessage": "Versión del juego" }, + "label.hide-installed-content": { + "defaultMessage": "Esconder contenido ya instalado" + }, "label.hide-selected-content": { "defaultMessage": "Ocultar contenido seleccionado" }, @@ -2186,6 +2276,9 @@ "label.password": { "defaultMessage": "Contraseña" }, + "label.permissions": { + "defaultMessage": "Permisos" + }, "label.plan-custom": { "defaultMessage": "Personalizado" }, @@ -2243,6 +2336,9 @@ "label.server": { "defaultMessage": "Servidor" }, + "label.server-only": { + "defaultMessage": "Solo servidor" + }, "label.servers": { "defaultMessage": "Servidores" }, @@ -2714,9 +2810,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Creador en Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Usuario de Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} no podrá enviarte solicitudes de amistad, invitarte a instancias compartidas o invítate a Servers en Modrinth." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "¿Estás seguro de que deseas bloquear este usuario?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Ocurrió un error al bloquear este usuario: Por favor intenta de nuevo." + }, + "profile.block-user.error-title": { + "defaultMessage": "No se pudo bloquear el usuario" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} fue bloqueado." + }, + "profile.block-user.success-title": { + "defaultMessage": "Usuario bloqueado" + }, + "profile.block-user.title": { + "defaultMessage": "Bloquear {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Ver analíticas del usuario" + }, + "profile.button.billing": { + "defaultMessage": "Gestionar la facturación de los usuarios" + }, + "profile.button.block": { + "defaultMessage": "Bloquear" + }, + "profile.button.create-collection": { + "defaultMessage": "Crear una colección" + }, + "profile.button.create-project": { + "defaultMessage": "Crear un proyecto" + }, + "profile.button.info": { + "defaultMessage": "Ver detalles del usuario" + }, + "profile.button.manage-projects": { + "defaultMessage": "Gestionar proyectos" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Borrar como afiliado" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Poner como afiliado" + }, + "profile.button.unblock": { + "defaultMessage": "Desbloquear" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# proyecto} other {# proyectos}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Permite las ventanas emergentes para Modrinth e inténtalo de nuevo." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "No se pudo mostrar el perfil de GitHub. Por favor intenta de nuevo." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "No se pudo abrir el perfil de GitHub" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Proveedores de autenticación" + }, + "profile.details.label.email-verified": { + "defaultMessage": "Correo verificado" + }, + "profile.details.label.has-password": { + "defaultMessage": "Tiene contraseña" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Tiene TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Cargando..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Métodos de pago" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Ver perfil" + }, + "profile.details.title": { + "defaultMessage": "Detalles de usuario" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "Correo no verificado" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "Correo verificado" + }, + "profile.error.load-description": { + "defaultMessage": "El perfil del usuario no pudo cargar." + }, + "profile.error.not-found": { + "defaultMessage": "Usuario no encontrado" + }, + "profile.label.affiliate": { + "defaultMessage": "Afiliado" + }, "profile.label.badges": { "defaultMessage": "Medallas" }, + "profile.label.collection": { + "defaultMessage": "Colección" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {descarga} other {descargas}}" + }, + "profile.label.joined": { + "defaultMessage": "Se unió hace" + }, + "profile.label.no-collections": { + "defaultMessage": "¡Este usuario no tiene colecciones!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "No tienes una colección aun." + }, + "profile.label.no-projects": { + "defaultMessage": "¡Este usuario no tiene proyectos!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "No tienes ningún proyecto aun." + }, + "profile.label.organizations": { + "defaultMessage": "Organizaciones" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {proyecto} other {proyectos}}" + }, + "profile.official-account": { + "defaultMessage": "Cuenta oficial de Modrinth" + }, + "profile.official-account.bio": { + "defaultMessage": "Cuenta oficial de Modrinth. Obtén soporte en o vía correo a " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Ocurrió un error al desbloquear este usuario. Por favor intenta de nuevo." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "No se pudo desbloquear el usuario" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} fue desbloqueado." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Usuario desbloqueado" + }, "project-card.date.published.tooltip": { "defaultMessage": "Publicado el {date}" }, @@ -2732,12 +2981,21 @@ "project-card.environment.client-or-server": { "defaultMessage": "Cliente o servidor" }, + "project-card.environment.dedicated-server": { + "defaultMessage": "Servidor dedicado" + }, "project-card.environment.server": { "defaultMessage": "Servidor" }, + "project-card.environment.singleplayer": { + "defaultMessage": "Un jugador" + }, "project-type.all": { "defaultMessage": "Todos" }, + "project-type.collection.plural": { + "defaultMessage": "Colecciones" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Paquete de Datos} other {Paquetes de Datos}}" }, @@ -3008,6 +3266,15 @@ "project.follower-count-tooltip": { "defaultMessage": "{count, number} {count, plural, one {seguidor} other {seguidores}}" }, + "project.license.error": { + "defaultMessage": "No se pudo coger el texto de la Licencia." + }, + "project.license.loading": { + "defaultMessage": "Cargando texto de la licencia..." + }, + "project.license.title": { + "defaultMessage": "Licencia" + }, "project.online-player-count": { "defaultMessage": "{count, number} en línea" }, @@ -3413,6 +3680,12 @@ "project.settings.view.title": { "defaultMessage": "Vista" }, + "project.stats.downloads-label": { + "defaultMessage": "{count, plural, one {descarga} other {descargas}}" + }, + "project.stats.followers-label": { + "defaultMessage": "{count, plural, one {seguidor} other {seguidores}}" + }, "project.versions.channel.alpha.symbol": { "defaultMessage": "A" }, @@ -3422,6 +3695,12 @@ "project.versions.channel.release.symbol": { "defaultMessage": "R" }, + "project.versions.filter.toggle-tooltip": { + "defaultMessage": "Alternar filtro para {filter}" + }, + "project.versions.platform.modloader.short": { + "defaultMessage": "Cargador de mod" + }, "project.versions.version.withheld": { "defaultMessage": "Retenido" }, @@ -3506,6 +3785,9 @@ "search.filter.option.show_more": { "defaultMessage": "Mostrar más" }, + "search.filter_type.advanced": { + "defaultMessage": "Avanzado" + }, "search.filter_type.environment": { "defaultMessage": "Entorno" }, @@ -4931,9 +5213,216 @@ "settings.pats.title": { "defaultMessage": "Tokens de acceso personal" }, + "settings.profile.bio.description": { + "defaultMessage": "Una breve descripción para contar a todos sobre ti." + }, + "settings.profile.bio.title": { + "defaultMessage": "Biografía" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Perfil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Foto de perfil" + }, + "settings.profile.public-information.description": { + "defaultMessage": "La información de tu perfil está visible públicamente en Modrinth y a la Modrinth API." + }, + "settings.profile.save-error": { + "defaultMessage": "No se pudo actualizar el perfil" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Ocurrió un error al actualizar tu perfil. Por favor intenta de nuevo." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Inicia sesión con una cuenta de Modrinth para editar tu perfil público." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Cuenta de Modrinth requerida" + }, + "settings.profile.username.description": { + "defaultMessage": "Un nombre que no distingue de mayúsculas o minúsculas para identificar tu perfil." + }, "settings.sessions.title": { "defaultMessage": "Sesiones" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Acciones" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Usuario" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Estos son los usuarios que bloqueaste en Modrinth. Ellos no pueden:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "No bloqueaste a nadie." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "No se pudo cargar los usuarios bloqueados." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Cargando usuarios bloqueados…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Enviar solicitudes de amistad" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Invitarte a administrar un Servidor en Modrinth." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Invitarte a instancias compartidas" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Usuarios bloqueados" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Desbloquear" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "No se pudo desbloquear el usuario" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Ocurrió un error al desbloquear este usuario. por favor intenta de nuevo." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Desbloquear {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Avatar de {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Controla quien puede enviarte solicitudes de amistad en Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Solicitudes de amistad" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "¡Próximamente!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Todos" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Amigos" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Amigos de amigos" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Ninguno" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Controla quien puede enviarte invitaciones a instancias compartidas y servidores en Modrinth." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Invitaciones" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Puedes controlar quien puede interactuar contigo, y gestionar los usuarios bloqueados con una cuenta de Modrinth" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Cuenta de Modrinth requerida" + }, + "settings.social.title": { + "defaultMessage": "Social" + }, + "sharing.invite-players-modal.add": { + "defaultMessage": "Añadir" + }, + "sharing.invite-players-modal.added": { + "defaultMessage": "Añadido" + }, + "sharing.invite-players-modal.already-invited": { + "defaultMessage": "Este usuario ya fue invitado." + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Aplicar" + }, + "sharing.invite-players-modal.avatar-alt": { + "defaultMessage": "Avatar de {username}" + }, + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Personalizado..." + }, + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Personalizado: {date}" + }, + "sharing.invite-players-modal.edit-invite-link": { + "defaultMessage": "Editar enlace de invitación." + }, + "sharing.invite-players-modal.edit-invite-link-title": { + "defaultMessage": "Editar enlace de invitación" + }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "En 1 día" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "En 1 hora" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "En 7 días" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "En 6 horas" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "En 3 días" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "En 12 horas" + }, + "sharing.invite-players-modal.expiry-label": { + "defaultMessage": "Día de caducidad" + }, + "sharing.invite-players-modal.friends-heading": { + "defaultMessage": "Tus amigos - {count}" + }, + "sharing.invite-players-modal.invite": { + "defaultMessage": "Invitar" + }, + "sharing.invite-players-modal.invite-expiry-description": { + "defaultMessage": "Tu link de invitación expira en {duration}." + }, + "sharing.invite-players-modal.invite-link-heading": { + "defaultMessage": "O usa un link de invitación" + }, + "sharing.invite-players-modal.link-copied-text": { + "defaultMessage": "La URL del link de invitación fue copiado al portapapeles." + }, + "sharing.invite-players-modal.link-copied-title": { + "defaultMessage": "Link Copiado" + }, + "sharing.invite-players-modal.link-copy-failed-title": { + "defaultMessage": "No se pudo copiar el link" + }, + "sharing.invite-players-modal.max-uses-label": { + "defaultMessage": "Usos máximos" + }, + "sharing.invite-players-modal.no-friends": { + "defaultMessage": "No tienes amigos." + }, + "sharing.invite-players-modal.no-search-results": { + "defaultMessage": "No se encontraron usuarios coincidentes." + }, + "sharing.invite-players-modal.requested": { + "defaultMessage": "Solicitud enviada" + }, + "sharing.invite-players-modal.requested-tooltip": { + "defaultMessage": "{username} debe de aceptar tu solicitud de amistad primero" + }, + "sharing.invite-players-modal.save-button": { + "defaultMessage": "Guardar" + }, + "sharing.invite-players-modal.search-placeholder": { + "defaultMessage": "Introduce el nombre de usuario de Modrinth" + }, + "sharing.invite-players-modal.searching": { + "defaultMessage": "Buscando..." + }, + "sharing.invite-players-modal.update-invite-link-failed-title": { + "defaultMessage": "No se pudo actualizar el enlace de invitación" + }, "tag.category.128x": { "defaultMessage": "128x" }, @@ -5468,6 +5957,39 @@ "ui.stacked-admonitions.dismiss-all": { "defaultMessage": "Descartar todas" }, + "unknown-file-warning-modal.dont-install": { + "defaultMessage": "No instalar" + }, + "unknown-file-warning-modal.dont-show-again": { + "defaultMessage": "No mostar esta advertencia de nuevo" + }, + "unknown-file-warning-modal.header": { + "defaultMessage": "Confirmar Instalación" + }, + "unknown-file-warning-modal.install-anyway": { + "defaultMessage": "Instalar de todas formas" + }, + "unknown-file-warning-modal.malware-warning": { + "defaultMessage": "Malware suele distribuir a través de archivos de mods compartidos en plataformas como Discord." + }, + "unknown-file-warning-modal.mod-warning-body": { + "defaultMessage": " no está publicado en Modrinth. Te recomendamos instalar archivos de fuentes de confianza." + }, + "unknown-file-warning-modal.mod-warning-title": { + "defaultMessage": "Advertencia de archivo desconocido" + }, + "unknown-file-warning-modal.modpack-warning-body": { + "defaultMessage": " contiene archivos que no están publicados en Modrinth. Te recomendamos instalar archivos de fuentes de confianza." + }, + "unknown-file-warning-modal.modpack-warning-title": { + "defaultMessage": "Advertencia de archivos desconocidos" + }, + "unknown-file-warning-modal.reviewed-files": { + "defaultMessage": "Un archivo es revisado si es que está publicado en Modrinth, sin importar su formato de archivo (Incluyendo .mrpack)." + }, + "unknown-file-warning-modal.unrecognized-files": { + "defaultMessage": "Archivos sin reconocer" + }, "user.profile.badge.alpha.about.1": { "defaultMessage": "Este usuario ha estado presente desde la Alpha de Modrinth, la cuál terminó en noviembre de 2020." }, diff --git a/packages/ui/src/locales/fi-FI/index.json b/packages/ui/src/locales/fi-FI/index.json index 0f53d3fe32..f7213394cc 100644 --- a/packages/ui/src/locales/fi-FI/index.json +++ b/packages/ui/src/locales/fi-FI/index.json @@ -567,3 +567,4 @@ "defaultMessage": "Sinulla on tallentamattomia muutoksia." } } + diff --git a/packages/ui/src/locales/fil-PH/index.json b/packages/ui/src/locales/fil-PH/index.json index 554ae942b3..9f07dfbca4 100644 --- a/packages/ui/src/locales/fil-PH/index.json +++ b/packages/ui/src/locales/fil-PH/index.json @@ -266,15 +266,6 @@ "content.page-layout.share.project-links": { "defaultMessage": "Mga link ng proyekto" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alpabetiko" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Pinakabago ang mauuna" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Pinakaluma ang mauuna" - }, "content.selection-bar.all-already-disabled": { "defaultMessage": "Nakapatay na ang lahat ng piniling konento" }, @@ -341,9 +332,6 @@ "external-project-license-status.yes": { "defaultMessage": "Oo" }, - "files.editor.find-close": { - "defaultMessage": "Isara" - }, "files.editor.find-in-file": { "defaultMessage": "Hahanapin" }, @@ -665,24 +653,6 @@ "instances.content-install.no-instances": { "defaultMessage": "Walang mahanap na magkatugmang instansiya" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Hindi naglalaman ng karagdagang kontento ang modpack na ito." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Walang mahanap na kontento" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Kontentong modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Inihahanda ang kontento..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Walang proyektong tumugma sa iyong paghanap." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Maghanap sa {count, number} {count, plural, one {proyekto} other {na proyekto}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Kasalukuyan" }, diff --git a/packages/ui/src/locales/fr-FR/index.json b/packages/ui/src/locales/fr-FR/index.json index 4d7ec28f42..f2807e196f 100644 --- a/packages/ui/src/locales/fr-FR/index.json +++ b/packages/ui/src/locales/fr-FR/index.json @@ -138,7 +138,7 @@ "defaultMessage": "Liens affiliés" }, "button.analytics": { - "defaultMessage": "Analyses" + "defaultMessage": "Statistiques" }, "button.back": { "defaultMessage": "Retour" @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Noms des projets" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alphabétique" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Plus récent en premier" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Plus ancien en premier" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Trier par {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Tout mettre à jour" }, @@ -1298,9 +1286,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Fichier sauvegardé" }, - "files.editor.find-close": { - "defaultMessage": "Fermer" - }, "files.editor.find-in-file": { "defaultMessage": "Trouver" }, @@ -2075,33 +2060,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Sélectionnez l'icône" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Aucun contenu supplémentaire n'est inclus dans ce modpack." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Aucun contenu trouvé" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Externe" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Ce fichier n'est pas publié sur Modrinth." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Contenu du modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Chargement du contenu..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Aucun projet correspond à votre recherche." - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "Ouvrir dans Slicer" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Rechercher {count, number} {count, plural, one {projet} other {projets}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Actuel" }, @@ -2234,6 +2192,9 @@ "label.details": { "defaultMessage": "Détails" }, + "label.discover-content": { + "defaultMessage": "Découvrir du contenu" + }, "label.done": { "defaultMessage": "Terminé" }, @@ -2312,6 +2273,9 @@ "label.password": { "defaultMessage": "Mot de passe" }, + "label.permissions": { + "defaultMessage": "Permissions" + }, "label.plan-custom": { "defaultMessage": "Personnalisé" }, @@ -2682,16 +2646,16 @@ "defaultMessage": "Garder les fichiers à jour quand le serveur change" }, "modal.open-in-app.get-app": { - "defaultMessage": "Obtenir l'application Modrinth" + "defaultMessage": "Obtenir Modrinth App" }, "modal.open-in-app.opening-automatically": { - "defaultMessage": "L'application Modrinth s'ouvrira automatiquement..." + "defaultMessage": "Modrinth App s'ouvrira automatiquement..." }, "modal.open-in-app.title": { "defaultMessage": "L'application Modrinth est en cours d'ouverture" }, "modal.open-in-app.why-use": { - "defaultMessage": "Pourquoi utiliser l'application Modrinth" + "defaultMessage": "Pourquoi utiliser Modrinth App" }, "notification.error.title": { "defaultMessage": "Une erreur est survenue" @@ -2843,9 +2807,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Un créateur Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Un utilisateur Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} ne va pas pouvoir vous envoyer de demande d'ami, vous inviter aux instances partagées ni à des serveurs Modrinth Hosting." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Êtes-vous sûr de vouloir bloquer cet utilisateur ?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Une erreur s'est produite pendant le blocage de cet utilisateur. Veuillez réessayer." + }, + "profile.block-user.error-title": { + "defaultMessage": "Impossible de bloquer l'utilisateur" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} a été bloqué." + }, + "profile.block-user.success-title": { + "defaultMessage": "Utilisateur bloqué" + }, + "profile.block-user.title": { + "defaultMessage": "Bloquer {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Voir les statistiques de l'utilisateur" + }, + "profile.button.billing": { + "defaultMessage": "Gérer la facturation de l’utilisateur" + }, + "profile.button.block": { + "defaultMessage": "Bloquer" + }, + "profile.button.create-collection": { + "defaultMessage": "Créer une collection" + }, + "profile.button.create-project": { + "defaultMessage": "Créer un projet" + }, + "profile.button.info": { + "defaultMessage": "Voir les détails de l'utilisateur" + }, + "profile.button.manage-projects": { + "defaultMessage": "Gérer les projets" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Retirer l'affiliation" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Se mettre comme affilié" + }, + "profile.button.unblock": { + "defaultMessage": "Débloquer" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural,one {# projet} other {# projets}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Autorisez les pop-ups pour Modrinth, puis réessayez." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Le profil GitHub n'a pas pu être récupéré. Veuillez réessayer." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Impossible d'ouvrir le profil GitHub" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Fournisseurs d’authentification" + }, + "profile.details.label.email-verified": { + "defaultMessage": "Adresse e-mail vérifiée" + }, + "profile.details.label.has-password": { + "defaultMessage": "Dispose d'un mot de passe" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Dispose d'un TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Chargement..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Moyens de paiements" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Voir le profil" + }, + "profile.details.title": { + "defaultMessage": "Détails de l'utilisateur" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "Adresse e-mail non vérifiée" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "Adresse e-mail vérifiée" + }, + "profile.error.load-description": { + "defaultMessage": "Impossible de charger le profil." + }, + "profile.error.not-found": { + "defaultMessage": "Utilisateur introuvable" + }, + "profile.label.affiliate": { + "defaultMessage": "Affilié" + }, "profile.label.badges": { "defaultMessage": "Badges" }, + "profile.label.collection": { + "defaultMessage": "Collection" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {téléchargement} other {téléchargements}}" + }, + "profile.label.joined": { + "defaultMessage": "Rejoint" + }, + "profile.label.no-collections": { + "defaultMessage": "Cet utilisateur n'a pas de collection !" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Vous n'avez pas encore de collection." + }, + "profile.label.no-projects": { + "defaultMessage": "Cet utilisateur n'a pas de projet !" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Vous n'avez pas encore de projet." + }, + "profile.label.organizations": { + "defaultMessage": "Organisations" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural,one {projet}other {projets}}" + }, + "profile.official-account": { + "defaultMessage": "Compte Modrinth officiel" + }, + "profile.official-account.bio": { + "defaultMessage": "Le compte utilisateur officiel de Modrinth. Obtenez de l’aide via ou par e-mail à " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Une erreur s'est produite pendant le déblocage de cet utilisateur. Veuillez réessayer." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Impossible de débloquer l'utilisateur" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} a été débloqué." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Utilisateur débloqué" + }, "project-card.date.published.tooltip": { "defaultMessage": "Publié {date}" }, @@ -2873,6 +2990,9 @@ "project-type.all": { "defaultMessage": "Tout" }, + "project-type.collection.plural": { + "defaultMessage": "Collections" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Data Pack} other {Data Packs}}" }, @@ -3665,15 +3785,6 @@ "search.filter_type.advanced": { "defaultMessage": "Avancé" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Exclure les data packs" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Exclure les mods" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Exclure les plugins" - }, "search.filter_type.environment": { "defaultMessage": "Environnement" }, @@ -4680,7 +4791,7 @@ "defaultMessage": "Détails de l'erreur :" }, "servers.manage.error.queue-notice": { - "defaultMessage": "Si vous avez acheté votre serveur Modrinth Hosting récemment, alors il fait actuellement la queue et apparaîtra ici dès qu'il est près. N'essayez pas d'acheter un nouveau serveur." + "defaultMessage": "Si vous avez acheté votre serveur Modrinth Hosting récemment, alors il fait actuellement la queue et apparaîtra ici dès qu'il est prêt. N'essayez pas d'acheter un nouveau serveur." }, "servers.manage.error.support-notice": { "defaultMessage": "Si vous avez besoin de soutien personnalisé à propos du status de votre serveur, veuillez contacter Modrinth Support." @@ -5099,9 +5210,117 @@ "settings.pats.title": { "defaultMessage": "Jetons d'accès personnel" }, + "settings.profile.bio.description": { + "defaultMessage": "Une courte description pour permettre à tout le monde d'en savoir un peu plus sur vous." + }, + "settings.profile.bio.title": { + "defaultMessage": "Biographie" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Photo de profil" + }, + "settings.profile.save-error": { + "defaultMessage": "Impossible de mettre à jour le profil" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Une erreur s'est produite en essayant de mettre à jour votre profil. Veuillez réessayer." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Connectez-vous avec votre compte Modrinth pour personnaliser votre profil public." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Compte Modrinth requis" + }, + "settings.profile.username.description": { + "defaultMessage": "Un nom unique, insensible à la casse, permettant d'identifier votre profil." + }, "settings.sessions.title": { "defaultMessage": "Sessions" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Actions" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Utilisateur" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Voici les utilisateurs que vous avez bloqués sur Modrinth. Ils ne peuvent pas :" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Vous n'avez bloqué personne." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Impossible de charger les utilisateurs bloqués." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Chargement des utilisateurs bloqués…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Vous envoyer des demandes d'ami" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Vous inviter à gérer un serveur Modrinth Hosting." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Vous inviter à des instances partagées" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Utilisateurs bloqués" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Débloquer" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Impossible de débloquer l'utilisateur" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Une erreur s'est produite en essayant de débloquer cet utilisateur. Veuillez réessayer." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Débloquer {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "avatar de {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Contrôlez qui peut vous envoyer des demandes d'ami sur Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Demandes d'ami" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "À venir !" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Tout le monde" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Amis" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Amis d'amis" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Personne" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Contrôlez qui peut vous inviter à des instances partagées et à des panneaux Modrinth Hosting." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Invitations" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Vous pouvez contrôler qui peut interagir avec vous, et gérer les utilisateurs bloqués avec un compte Modrinth" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Compte Modrinth requis" + }, + "settings.social.title": { + "defaultMessage": "Social" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Ajouter" }, @@ -5111,14 +5330,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Cet utilisateur a déjà été invité." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Appliquer" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Avatar de {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Annuler" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Personnaliser..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Annuler" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Personnalisé : {date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Modifier le lien d'invitation." @@ -5126,6 +5348,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "Modifier le lien d'invitation" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "Dans 1 jour" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "Dans 1 heure" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "Dans 7 jours" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "Dans 6 heures" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "Dans 3 jours" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "Dans 12 jours" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Date d'expiration" }, diff --git a/packages/ui/src/locales/fr-FR/meta.json b/packages/ui/src/locales/fr-FR/meta.json index 0d64aef5ba..29f12c6283 100644 --- a/packages/ui/src/locales/fr-FR/meta.json +++ b/packages/ui/src/locales/fr-FR/meta.json @@ -1,7 +1,7 @@ { "displayName": { "description": "Please enter the name of the language in its specific variant or regional form (e.g., English (US) for American English, not just English). If the language does not have any specific variant, simply enter the name of the language (e.g., Français, Deutsch).", - "message": "Français (France)" + "message": "Français" }, "searchTerms": { "description": "Please provide additional search terms associated with the language, if needed, to enhance the search functionality (e.g., American English, Deutschland). Each search term should be entered on a separate line. Translate as a hyphen (-) if no additional terms are needed.", diff --git a/packages/ui/src/locales/hu-HU/index.json b/packages/ui/src/locales/hu-HU/index.json index faa51d7f32..ab3def99e4 100644 --- a/packages/ui/src/locales/hu-HU/index.json +++ b/packages/ui/src/locales/hu-HU/index.json @@ -54,7 +54,7 @@ "defaultMessage": "Mégse" }, "billing.resubscribe-modal.cpus": { - "defaultMessage": "{sharedCpus} Megosztott CPU-k" + "defaultMessage": "{sharedCpus} megosztott CPU" }, "billing.resubscribe-modal.description": { "defaultMessage": "Ön újra elő fog fizetni {serverName} szerverre. Az előfizetése újra fog aktiválódni és a szervere kimaradás nélkül tovább fog működni." @@ -123,7 +123,7 @@ "defaultMessage": "Elfogadás" }, "button.add-server-to-instance": { - "defaultMessage": "Szerver hozzáadása a játékpéldányhoz" + "defaultMessage": "Szerver hozzáadása a játékprofilhoz" }, "button.affiliate-links": { "defaultMessage": "Társulati linkek" @@ -212,6 +212,9 @@ "button.open-folder": { "defaultMessage": "Mappa megnyitása" }, + "button.open-in-browser": { + "defaultMessage": "Megnyitás a böngészőben" + }, "button.open-in-folder": { "defaultMessage": "Megnyitás mappában" }, @@ -305,6 +308,9 @@ "changelog.product.web": { "defaultMessage": "Platform" }, + "collection-widget.loading-projects": { + "defaultMessage": "Projektek betöltése..." + }, "collection-widget.project-count": { "defaultMessage": "{count} projekt" }, @@ -378,7 +384,7 @@ "defaultMessage": "Néhány kijelölt projekt függőségként van telepítve. Ha törlöd őket, a {context} hibásan működhet, vagy a tőlük függő tartalmak nem fognak megfelelően betöltődni." }, "content.dependency-warning.context.instance": { - "defaultMessage": "játékpéldány" + "defaultMessage": "játékprofil" }, "content.dependency-warning.context.server": { "defaultMessage": "szerver" @@ -440,6 +446,9 @@ "content.diff-modal.unknown-files-warning": { "defaultMessage": "Ismeretlen fájlok" }, + "content.diff-modal.unknown-project": { + "defaultMessage": "Ismeretlen" + }, "content.diff-modal.updated-count": { "defaultMessage": "{count} frissítve" }, @@ -474,7 +483,7 @@ "defaultMessage": "Biztonsági mentés létrehozása" }, "content.inline-backup.instance-label": { - "defaultMessage": "játékpéldány" + "defaultMessage": "játékprofil" }, "content.inline-backup.shift-click-hint": { "defaultMessage": "A megerősítés kihagyásához tartsd lenyomva a Shift billentyűt a kattintás közben." @@ -536,18 +545,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Projektnevek" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Ábécé sorrendben" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Legújabbak elöl" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Legrégebbiek elöl" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Rendezés {mode} szerint" - }, "content.page-layout.update-all": { "defaultMessage": "Összes frissítése" }, @@ -588,7 +585,7 @@ "defaultMessage": "{count, number} kiválasztva" }, "creation-flow.button.create-instance": { - "defaultMessage": "Játékpéldány létrehozása" + "defaultMessage": "Játékprofil létrehozása" }, "creation-flow.button.create-world": { "defaultMessage": "Világ létrehozása" @@ -600,7 +597,7 @@ "defaultMessage": "Importálás" }, "creation-flow.button.import-instances": { - "defaultMessage": "{count} játékpéldány importálása" + "defaultMessage": "{count} játékprofil importálása" }, "creation-flow.button.setup-server": { "defaultMessage": "Szerver beállítása" @@ -654,7 +651,7 @@ "defaultMessage": "Név" }, "creation-flow.modal.custom-setup.name.placeholder": { - "defaultMessage": "Add meg a játékpéldány nevét" + "defaultMessage": "Add meg a játékprofil nevét" }, "creation-flow.modal.custom-setup.options.no-versions-available": { "defaultMessage": "Nincsenek elérhető verziók" @@ -698,6 +695,9 @@ "creation-flow.modal.final-config.generate-structures.label": { "defaultMessage": "Struktúrák generálása" }, + "creation-flow.modal.final-config.generator-settings-json.placeholder": { + "defaultMessage": "Add meg a generátor beállításait JSON formátumban" + }, "creation-flow.modal.final-config.generator-settings.custom": { "defaultMessage": "Egyéni" }, @@ -758,20 +758,26 @@ "creation-flow.modal.import-instance.custom-launcher.name": { "defaultMessage": "Egyéni ({pathName})" }, + "creation-flow.modal.import-instance.detecting-launcher-instances": { + "defaultMessage": "Indító-játékprofilok észlelése..." + }, "creation-flow.modal.import-instance.launcher-instances.title": { - "defaultMessage": "Más indítók játékpéldányai" + "defaultMessage": "Más indítók játékprofiljai" + }, + "creation-flow.modal.import-instance.launcher-path.add": { + "defaultMessage": "Add meg az elérési utat az indítóhoz" }, "creation-flow.modal.import-instance.launcher-path.placeholder": { "defaultMessage": "Elérési útvonal az indítóhoz..." }, "creation-flow.modal.import-instance.notification.no-instances-found.text": { - "defaultMessage": "Nem találtunk importálható játékpéldányokat a megadott útvonalon." + "defaultMessage": "Nem találtunk importálható játékprofilokat a megadott útvonalon." }, "creation-flow.modal.import-instance.notification.no-instances-found.title": { - "defaultMessage": "Nem található játékpéldány" + "defaultMessage": "Nem található játékprofil" }, "creation-flow.modal.import-instance.search.placeholder": { - "defaultMessage": "Játékpéldánynév keresése..." + "defaultMessage": "Játékprofilnév keresése..." }, "creation-flow.modal.import-instance.selection.clear-all": { "defaultMessage": "Összes törlése" @@ -792,7 +798,7 @@ "defaultMessage": "Modcsomag keresése" }, "creation-flow.modal.setup-type.instance.description": { - "defaultMessage": "A játékpéldány egy külön Minecraft-környezet egy adott modbetöltővel, verzióval és modokkal." + "defaultMessage": "A játékprofil egy külön Minecraft-környezet egy adott modbetöltővel, verzióval és modokkal." }, "creation-flow.modal.setup-type.option.custom-setup.description": { "defaultMessage": "Kezdés alapoktól: válassz betöltőt és játékverziót." @@ -801,10 +807,10 @@ "defaultMessage": "Egyedi beállítás" }, "creation-flow.modal.setup-type.option.import-instance.description": { - "defaultMessage": "Importálj egy játékpéldányt a Prismből, CurseForge-ból, vagy hasonló forrásból." + "defaultMessage": "Importálj egy játékprofilt a Prismből, CurseForge-ból, vagy hasonló forrásból." }, "creation-flow.modal.setup-type.option.import-instance.title": { - "defaultMessage": "Játékpéldány importálása" + "defaultMessage": "Játékprofil importálása" }, "creation-flow.modal.setup-type.option.modpack-base.description": { "defaultMessage": "Böngéssz modcsomagokat a Modrinthon, vagy tölts be egyet fájlból." @@ -822,7 +828,7 @@ "defaultMessage": "Telepítés típusa" }, "creation-flow.modal.setup-type.title.instance": { - "defaultMessage": "Játékpéldány típusa" + "defaultMessage": "Játékprofil típusa" }, "creation-flow.modal.setup-type.title.world": { "defaultMessage": "Világ típusa" @@ -831,13 +837,13 @@ "defaultMessage": "Modcsomag kiválasztása" }, "creation-flow.title.create-instance": { - "defaultMessage": "Játékpéldány létrehozása" + "defaultMessage": "Játékprofil létrehozása" }, "creation-flow.title.create-world": { "defaultMessage": "Világ létrehozása" }, "creation-flow.title.import-instance": { - "defaultMessage": "Játékpéldány importálása" + "defaultMessage": "Játékprofil importálása" }, "creation-flow.title.reset-server": { "defaultMessage": "Szerver visszaállítása" @@ -875,6 +881,9 @@ "external-files.permissions-card.custom-license-option": { "defaultMessage": "Egyéb" }, + "external-files.permissions-card.editor.add": { + "defaultMessage": "Hozzárendelés hozzáadása" + }, "external-files.permissions-card.editor.custom-license-label": { "defaultMessage": "Hivatkozás a lincenszhez" }, @@ -905,9 +914,15 @@ "external-files.permissions-card.editor.notes-placeholder": { "defaultMessage": "Írj valamit ide..." }, + "external-files.permissions-card.editor.save": { + "defaultMessage": "Hossárendelés mentése" + }, "external-files.permissions-card.editor.select-license-label": { "defaultMessage": "Válassz egy licenszt..." }, + "external-files.permissions-card.fallback-group-title": { + "defaultMessage": "A(z) {id} hozzárendelési csoport" + }, "external-files.permissions-card.file-count": { "defaultMessage": "{count} fájl" }, @@ -932,6 +947,9 @@ "external-files.permissions-card.reason.my-project": { "defaultMessage": "Az én projektem" }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "{title} törlése?" + }, "external-files.permissions-card.updated-by-moderator": { "defaultMessage": "Moderátor" }, @@ -995,9 +1013,6 @@ "files.editor.file-saved-title": { "defaultMessage": "A fájl mentve" }, - "files.editor.find-close": { - "defaultMessage": "Bezárás" - }, "files.editor.find-in-file": { "defaultMessage": "Keresés" }, @@ -1467,7 +1482,7 @@ "defaultMessage": "{storage} GB Tárhely" }, "hosting.specs.shared-cpus": { - "defaultMessage": "{cpus} Megosztott CPU-k" + "defaultMessage": "{cpus} megosztott CPU" }, "icon-select.edit": { "defaultMessage": "Ikon szerkesztése" @@ -1569,13 +1584,13 @@ "defaultMessage": "Modcsomag újratelepítése..." }, "installation-settings.removed-incompatible": { - "defaultMessage": "Eltávolítva (inkompatibilis)" + "defaultMessage": "Eltávolítva: (inkompatibilis)" }, "installation-settings.repair.instance-description": { "defaultMessage": "Újratelepíti a Minecraft függőségeit, és ellenőrzi, hogy nincsenek-e sérült fájlok. Ez megoldhatja azokat a problémákat, ha a játék az indítóval kapcsolatos hibák miatt nem indul el." }, "installation-settings.repair.instance-title": { - "defaultMessage": "Játékpéldány javítása" + "defaultMessage": "Játékprofil javítása" }, "installation-settings.repair.server-description": { "defaultMessage": "Újratelepíti a betöltőt és a Minecraft függőségeit anélkül, hogy törölné a tartalmaidat. Ez megoldhatja a problémákat, ha a szervered nem indul el megfelelően." @@ -1590,10 +1605,10 @@ "defaultMessage": "Játékverzió keresése..." }, "installation-settings.type.instance": { - "defaultMessage": "játékpéldány" + "defaultMessage": "játékprofil" }, "installation-settings.type.instance-possessive": { - "defaultMessage": "játékpéldány" + "defaultMessage": "játékprofil" }, "installation-settings.type.server": { "defaultMessage": "szerver" @@ -1632,7 +1647,7 @@ "defaultMessage": "{type} javítása" }, "instance.confirm-repair.instance-label": { - "defaultMessage": "Játékpéldány" + "defaultMessage": "Példány" }, "instance.confirm-repair.repair-button": { "defaultMessage": "Javítás" @@ -1656,10 +1671,10 @@ "defaultMessage": "Ismeretlen játékmód" }, "instances.content-install.compatible-count": { - "defaultMessage": "{count} kompatiblis játékpéldány" + "defaultMessage": "{count} kompatiblis játékprofil" }, "instances.content-install.existing-tab": { - "defaultMessage": "Meglévő játékpéldány" + "defaultMessage": "Meglévő játékprofil" }, "instances.content-install.game-version-placeholder": { "defaultMessage": "Játékverzió kiválasztása" @@ -1668,7 +1683,7 @@ "defaultMessage": "Projekt letöltése" }, "instances.content-install.incompatible-tooltip": { - "defaultMessage": "Ez a játékpéldány olyan betöltőt vagy játékverziót használ, amelyet ez a projekt nem támogat." + "defaultMessage": "Ez a játékprofil olyan betöltőt vagy játékverziót használ, amelyet ez a projekt nem támogat." }, "instances.content-install.install-button": { "defaultMessage": "Letöltés" @@ -1689,7 +1704,7 @@ "defaultMessage": "Add meg a profil nevét" }, "instances.content-install.new-tab": { - "defaultMessage": "Új profil" + "defaultMessage": "Új játékprofil" }, "instances.content-install.no-instances": { "defaultMessage": "Nem található kompatibilis profil" @@ -1703,24 +1718,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Ikon feltöltése" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Ez a modcsomag nem tartalmaz további tartalmakat." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nincsen tartalom" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Modcsomag tartalma" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Tartalmak betöltése..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Nincsen olyan projekt ami keresnél." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Keresés {count, number} projekt között" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Jelenlegi" }, @@ -1788,7 +1785,7 @@ "defaultMessage": "Frissítés a(z) {version} verzióra" }, "instances.updater-modal.warning-app": { - "defaultMessage": "A frissítés meghibásodást okozhat a játékpéldányban. Először nézd át a változásnaplót, és készíts biztonsági mentést." + "defaultMessage": "A frissítés meghibásodást okozhat a játékprofilban. Először nézd át a változásnaplót, és készíts biztonsági mentést." }, "instances.updater-modal.warning-web": { "defaultMessage": "A frissítés meghibásodást okozhat a világban. Először nézd át a változásnaplót, és készíts biztonsági mentést." @@ -1853,6 +1850,9 @@ "label.details": { "defaultMessage": "Részletek" }, + "label.discover-content": { + "defaultMessage": "Tartalom felfedezése" + }, "label.done": { "defaultMessage": "Kész" }, @@ -2298,7 +2298,7 @@ "defaultMessage": "Szerezd meg a Modrinth Appot" }, "modal.open-in-app.opening-automatically": { - "defaultMessage": "A Modrinth alkalmazás automatikusan megnyílik..." + "defaultMessage": "A Modrinth App automatikusan megnyílik..." }, "modal.open-in-app.title": { "defaultMessage": "A Modrinth App megnyitása" @@ -2453,9 +2453,135 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Egy Modrinth fejlesztő." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Egy Modrinth felhasználó." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} nem fog tudni neked barátkérelmet küldeni, meghívni téged megosztott játékprofilokba, illetve meghívni téged a Modrinth Hosting szervereire." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Biztosan le szeretnéd tiltani ezt a felhasználót?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Hiba történt a felhasználó letiltása közben. Kérlek próbáld meg újra." + }, + "profile.block-user.error-title": { + "defaultMessage": "A felhasználó letiltása nem sikerült" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} le lett tiltva" + }, + "profile.block-user.success-title": { + "defaultMessage": "Felhasználó letiltva" + }, + "profile.block-user.title": { + "defaultMessage": "{username} letiltása" + }, + "profile.button.analytics": { + "defaultMessage": "Felhasználói statisztikák megtekintése" + }, + "profile.button.block": { + "defaultMessage": "Letiltás" + }, + "profile.button.create-collection": { + "defaultMessage": "Gyűjtemény létrehozása" + }, + "profile.button.create-project": { + "defaultMessage": "Projekt létrehozása" + }, + "profile.button.info": { + "defaultMessage": "Felhasználói adatok megtekintése" + }, + "profile.button.manage-projects": { + "defaultMessage": "Projektek kezelése" + }, + "profile.button.unblock": { + "defaultMessage": "Letiltás feloldása" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count} projekt" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Hitelesítési szolgáltatók" + }, + "profile.details.label.email-verified": { + "defaultMessage": "E-mail cím hitelesítve" + }, + "profile.details.label.has-password": { + "defaultMessage": "Van jelszava" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Kétlépcsős hitelesítést használ" + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Fizetési módok" + }, + "profile.details.title": { + "defaultMessage": "Felhasználó adatai" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "Nem hitelesített e-mail cím" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "Hitelesített e-mail cím" + }, + "profile.error.load-description": { + "defaultMessage": "A felhasználói profil betöltése nem sikerült." + }, + "profile.error.not-found": { + "defaultMessage": "Felhasználó nem található" + }, "profile.label.badges": { "defaultMessage": "Jelvények" }, + "profile.label.collection": { + "defaultMessage": "Gyűjtemény" + }, + "profile.label.download-count": { + "defaultMessage": "letöltés" + }, + "profile.label.joined": { + "defaultMessage": "Csatlakozott" + }, + "profile.label.no-collections": { + "defaultMessage": "Ennek a felhasználónak nincsenek gyűjteményei!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Még nincs gyűjteményed." + }, + "profile.label.no-projects": { + "defaultMessage": "Ennek a felhasználónak nincsenek projektjei!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Még nincsenek projektjeid." + }, + "profile.label.organizations": { + "defaultMessage": "Szervezetek" + }, + "profile.label.project-count": { + "defaultMessage": "projekt" + }, + "profile.official-account": { + "defaultMessage": "Hivatalos Modrinth-fiók" + }, + "profile.official-account.bio": { + "defaultMessage": "A Modrinth hivatalos felhasználói fiókja. Támogatás a oldalon kaphatsz vagy e-mailben a címen." + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Hiba történt a felhasználó letiltásának feloldása közben. Kérlek próbáld meg újra." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "A felhasználó letiltásának feloldása nem sikerült" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} letiltása fel lett oldva" + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Felhasználó letiltása feloldva" + }, "project-card.date.published.tooltip": { "defaultMessage": "Közzététel: {date}" }, @@ -2477,8 +2603,11 @@ "project-type.all": { "defaultMessage": "Összes" }, + "project-type.collection.plural": { + "defaultMessage": "Gyűjtemények" + }, "project-type.datapack.capital": { - "defaultMessage": "{count, plural, one {Adatcsomag} other {Adatcsomagok}}" + "defaultMessage": "adatcsomag" }, "project-type.datapack.category": { "defaultMessage": "Adatcsomagok" @@ -2487,7 +2616,7 @@ "defaultMessage": "adatcsomag" }, "project-type.mod.capital": { - "defaultMessage": "{count, plural,one {Mod} other {Modok}}" + "defaultMessage": "mod" }, "project-type.mod.category": { "defaultMessage": "Modok" @@ -2505,7 +2634,7 @@ "defaultMessage": "modcsomag" }, "project-type.plugin.capital": { - "defaultMessage": "{count, plural,one {Bővítmény} other {Bővítmények}}" + "defaultMessage": "bővítmény" }, "project-type.plugin.category": { "defaultMessage": "Bővítmények" @@ -2523,7 +2652,7 @@ "defaultMessage": "projekt" }, "project-type.resourcepack.capital": { - "defaultMessage": "{count, plural,one {Forráscsomag} other {Forráscsomagok}}" + "defaultMessage": "forráscsomag" }, "project-type.resourcepack.category": { "defaultMessage": "Forráscsomagok" @@ -2541,7 +2670,7 @@ "defaultMessage": "szerver" }, "project-type.shader.capital": { - "defaultMessage": "{count, plural,one {Shader} other {Shaderek}}" + "defaultMessage": "shader" }, "project-type.shader.category": { "defaultMessage": "Shaderek" @@ -2735,6 +2864,9 @@ "project.follower-count-tooltip": { "defaultMessage": "{count, number} követő" }, + "project.license.title": { + "defaultMessage": "Licensz" + }, "project.online-player-count": { "defaultMessage": "{count, number} online" }, @@ -3053,6 +3185,9 @@ "project.settings.environment.notice.review-options.description": { "defaultMessage": "Nemrégiben átalakítottuk a Modrinth környezetrendszerét, és mostantól új beállítási lehetőségek állnak rendelkezésre. Kérjük, győződj meg arról, hogy az alábbiak közül a megfelelő opciót választottad ki, majd ha kész vagy, kattints az „Ellenőrzés” gombra!" }, + "project.settings.environment.notice.review-options.title": { + "defaultMessage": "Kérjük, tekintsd át az alábbi lehetőségeket" + }, "project.settings.environment.notice.wrong-project-type.description": { "defaultMessage": "Csak a mod- vagy modcsomag-projektek rendelkezhetnek környezeti metaadatokkal." }, @@ -3132,7 +3267,7 @@ "defaultMessage": "letöltés" }, "project.stats.followers-label": { - "defaultMessage": "{count} követő" + "defaultMessage": "követő" }, "project.versions.channel.alpha.symbol": { "defaultMessage": "A" @@ -3143,6 +3278,9 @@ "project.versions.channel.release.symbol": { "defaultMessage": "K" }, + "project.versions.platform.modloader.short": { + "defaultMessage": "ModLoader" + }, "project.visibility.archived": { "defaultMessage": "Archiválva" }, @@ -3354,7 +3492,7 @@ "defaultMessage": "Újraindított szerver" }, "servers.access-page.activity-log-filter.instances": { - "defaultMessage": "Játékpéldányok" + "defaultMessage": "Játékprofilok" }, "servers.access-page.activity-log-filter.server-scoped-instance": { "defaultMessage": "Szerver" @@ -3420,7 +3558,7 @@ "defaultMessage": "Szerkesztő" }, "servers.access-page.role.editor-description": { - "defaultMessage": "A játékpéldány tartalmának, fájljainak, biztonsági mentéseinek és egyéb beállításainak kezelése." + "defaultMessage": "A játékprofil tartalmának, fájljainak, biztonsági mentéseinek és egyéb beállításainak kezelése." }, "servers.access-page.role.owner": { "defaultMessage": "Tulajdonos" @@ -3498,7 +3636,7 @@ "defaultMessage": "Felhasználó" }, "servers.audit-log.column.world": { - "defaultMessage": "Játékpéldány" + "defaultMessage": "Játékprofil" }, "servers.audit-log.column.world.tooltip-title": { "defaultMessage": "Hamarosan érkezik!" @@ -3519,7 +3657,7 @@ "defaultMessage": "Leválasztott modcsomag-verzió " }, "servers.audit-log.event.server-plan.ram-mb": { - "defaultMessage": "{amount, number} MB RAM" + "defaultMessage": "{amount, number} MB memória" }, "servers.audit-log.event.server-plan.storage-gb": { "defaultMessage": "{amount, number} GB tárhely" @@ -3723,7 +3861,7 @@ "defaultMessage": "Szerkesztő" }, "servers.grant-access-modal.role.editor-description": { - "defaultMessage": "A játékpéldány tartalmának, fájljainak, biztonsági mentéseinek és egyéb beállításainak kezelése." + "defaultMessage": "A játékprofil tartalmának, fájljainak, biztonsági mentéseinek és egyéb beállításainak kezelése." }, "servers.grant-access-modal.role.label": { "defaultMessage": "Rang kiválasztása" @@ -3806,6 +3944,9 @@ "servers.list-empty.no-servers-title": { "defaultMessage": "Még nincsenek szerverek" }, + "servers.list-empty.one-click-mod-installs-description": { + "defaultMessage": "Válaszd ki a kedvenc modjaidat, a többit bízd ránk!" + }, "servers.list-empty.one-click-mod-installs-title": { "defaultMessage": "Modok telepítése egy kattintással" }, @@ -3899,6 +4040,9 @@ "servers.manage.no-servers-found": { "defaultMessage": "Nem található szerver." }, + "servers.manage.no-shared-servers-found": { + "defaultMessage": "Egy megosztott szerver sem egyezik a kereséssel." + }, "servers.manage.reload-button": { "defaultMessage": "Újra" }, @@ -3920,6 +4064,9 @@ "servers.manage.settings-hint.title": { "defaultMessage": "A szerver beállításait áthelyeztük" }, + "servers.manage.shared-servers-title": { + "defaultMessage": "Megosztott szerverek" + }, "servers.medal-listing.countdown.remaining": { "defaultMessage": "{days} nap {hours} óra {minutes} perc és {seconds} másodperc van hátra..." }, @@ -4017,7 +4164,7 @@ "defaultMessage": "Legnépszerűbb" }, "servers.purchase.step.plan.select": { - "defaultMessage": "Válasz előfizetést" + "defaultMessage": "Csomag kiválasztása" }, "servers.purchase.step.plan.small": { "defaultMessage": "Kicsi" @@ -4026,7 +4173,7 @@ "defaultMessage": "Tökéletes 1–5 barát számára, néhány kisebb moddal." }, "servers.purchase.step.plan.title": { - "defaultMessage": "Előfizetés" + "defaultMessage": "Csomag" }, "servers.purchase.step.plan.your-current-plan": { "defaultMessage": "Jelenlegi csomag" @@ -4046,6 +4193,15 @@ "servers.region.custom.prompt-ram-only": { "defaultMessage": "memória" }, + "servers.region.north-america-central": { + "defaultMessage": "Észak-Amerika középső része" + }, + "servers.region.north-america-east": { + "defaultMessage": "Észak-Amerika keleti része" + }, + "servers.region.north-america-west": { + "defaultMessage": "Észak-Amerika nyugati része" + }, "servers.region.prompt": { "defaultMessage": "Hol szeretnéd elhelyezni a szerveredet?" }, @@ -4166,6 +4322,9 @@ "settings.display.theme.title": { "defaultMessage": "Téma" }, + "settings.feature-flags.title": { + "defaultMessage": "Funkciójelzők" + }, "settings.language.categories.default": { "defaultMessage": "Alapértelmezett nyelvek" }, @@ -4199,9 +4358,120 @@ "settings.pats.title": { "defaultMessage": "Személyes hozzáférési tokenek" }, + "settings.profile.bio.description": { + "defaultMessage": "Egy rövid leírás, hogy mindenki megismerjen téged." + }, + "settings.profile.bio.title": { + "defaultMessage": "Bemutatkozás" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Profilkép" + }, + "settings.profile.public-information.description": { + "defaultMessage": "A profiladataid nyilvánosan megtekinthetők a Modrinthon és a Modrinth API-n keresztül." + }, + "settings.profile.save-error": { + "defaultMessage": "A profil frissítése nem sikerült" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Hiba történt a profilod frissítése közben. Kérlek, próbáld meg újra." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Jelentkezz be egy Modrinth-fiókkal, hogy személyre szabhasd a nyilvános profilodat." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Modrinth-fiók szükséges" + }, + "settings.profile.username.description": { + "defaultMessage": "Egyedi, kis- és nagybetűktől független név a profilod azonosításához." + }, "settings.sessions.title": { "defaultMessage": "Munkamenetek" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Műveletek" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Felhasználó" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Ezek azok a felhasználók, akiket a Modrinthon letiltottál. Ők nem tudnak:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Nem tiltottál le senkit." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "A letiltott felhasználók betöltése nem sikerült." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "A letiltott felhasználók betöltése…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Barátkérelmeket küldeni neked" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Meghívni téged, hogy kezelj egy Modrinth Hosting szervert." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Meghívni téged megosztott játékprofilokba" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Letiltott felhasználók" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Letiltás feloldása" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "A felhasználó letiltásának feloldása nem sikerült" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Hiba történt a felhasználó letiltásának feloldása közben. Kérlek próbáld meg újra." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "{username} letiltásának feloldása" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "{username} avatárja" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Állítsd be, hogy ki küldhet neked barátkérelmeket a Modrinthon." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Barátkérelmek" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Hamarosan érkezik!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Bárki" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Barátok" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "A barátok barátai" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Senki" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Állítsd be, hogy kik küldhetnek neked meghívókat a megosztott játékprofilokhoz és a Modrinth Hosting vezérlőpultjaihoz." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Meghívók" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "A Modrinth-fiókod segítségével beállíthatod, hogy kik léphetnek veled kapcsolatba, és kezelheted a letiltott felhasználókat" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Modrinth-fiók szükséges" + }, + "settings.social.title": { + "defaultMessage": "Közösségi" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Hozzáadás" }, @@ -4214,12 +4484,6 @@ "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "{username} avatárja" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Mégse" - }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Mégse" - }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Meghívólink szerkesztése." }, @@ -4247,6 +4511,15 @@ "sharing.invite-players-modal.link-copied-title": { "defaultMessage": "Link kimásolva" }, + "sharing.invite-players-modal.link-copy-failed-title": { + "defaultMessage": "A link másolása nem sikerült" + }, + "sharing.invite-players-modal.max-uses-label": { + "defaultMessage": "Maximális felhasználások száma" + }, + "sharing.invite-players-modal.no-friends": { + "defaultMessage": "Nem találhatók barátok." + }, "sharing.invite-players-modal.no-search-results": { "defaultMessage": "Nem található a keresésnek megfelelő felhasználó." }, @@ -4775,6 +5048,9 @@ "ui.stacked-admonitions.alert-count": { "defaultMessage": "{count} figyelmeztetés" }, + "unknown-file-warning-modal.malware-warning": { + "defaultMessage": "A rosszindulatú programokat gyakran modfájlokon keresztül terjesztik, például a Discordhoz hasonló platformokon történő megosztás révén." + }, "unknown-file-warning-modal.modpack-warning-title": { "defaultMessage": "Ismeretlen fájlok" }, @@ -4873,5 +5149,14 @@ }, "user.profile.badge.staff.name": { "defaultMessage": "A Modrinth-csapat" + }, + "version.section.content": { + "defaultMessage": "Tartalom" + }, + "version.section.content.search-placeholder": { + "defaultMessage": "Tartalom keresése..." + }, + "version.section.required-content": { + "defaultMessage": "Kötelező tartalom" } } diff --git a/packages/ui/src/locales/id-ID/index.json b/packages/ui/src/locales/id-ID/index.json index 8ad53fed3f..6235f9fe9a 100644 --- a/packages/ui/src/locales/id-ID/index.json +++ b/packages/ui/src/locales/id-ID/index.json @@ -503,18 +503,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nama proyek" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Menurut abjad" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Terbaru dahulu" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Tertua dahulu" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Urutkan berdasarkan {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Perbarui semua" }, @@ -824,9 +812,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Berkas disimpan" }, - "files.editor.find-close": { - "defaultMessage": "Tutup" - }, "files.editor.find-in-file": { "defaultMessage": "Cari" }, @@ -1175,24 +1160,6 @@ "instance.worlds.game_mode.unknown": { "defaultMessage": "Mode permainan tak dikenal" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Paket mod ini tidak termasuk konten tambahan." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Konten tidak ditemukan" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Konten paket mod" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Sedang memuat konten..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Tidak ada proyek yang cocok dengan pencarian Anda." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Cari {count, number} {count, plural, other {proyek}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Saat ini" }, diff --git a/packages/ui/src/locales/it-IT/index.json b/packages/ui/src/locales/it-IT/index.json index 8ff9e91298..28ce02f5c1 100644 --- a/packages/ui/src/locales/it-IT/index.json +++ b/packages/ui/src/locales/it-IT/index.json @@ -596,18 +596,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nomi dei progetti" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetico" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Più recenti prima" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Meno recenti prima" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Ordina per {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Aggiorna tutto" }, @@ -732,7 +720,7 @@ "defaultMessage": "Nessuna versione trovata" }, "creation-flow.modal.final-config.additional-settings.title": { - "defaultMessage": "Opzioni aggiuntive" + "defaultMessage": "Impostazioni aggiuntive" }, "creation-flow.modal.final-config.backup.before-reset-server.name": { "defaultMessage": "Prima della reimpostazione" @@ -1173,7 +1161,7 @@ "defaultMessage": "Elimina gruppo" }, "external-files.permissions-card.remove-group-confirmation.description": { - "defaultMessage": "Questo gruppo di attribuzione sarà rimosso per sempre. Quest'azione non può essere annullata." + "defaultMessage": "Il gruppo di attribuzione e i suoi contenuti saranno eliminati per sempre. Questa azione è irreversibile." }, "external-files.permissions-card.remove-group-confirmation.title": { "defaultMessage": "Eliminare {title}?" @@ -1248,10 +1236,10 @@ "defaultMessage": "Elimina file" }, "files.delete-modal.warning.file": { - "defaultMessage": "Questo file verrà eliminato permanentemente. Questa azione non può essere annullata." + "defaultMessage": "Il file sarà eliminato per sempre. Questa azione è irreversibile." }, "files.delete-modal.warning.folder": { - "defaultMessage": "Questa cartella e tutti i suoi contenuti verranno eliminati permanentemente. Questa azione non può essere annullata." + "defaultMessage": "La cartella e i suoi contenuti saranno eliminati per sempre. Questa azione è irreversibile." }, "files.editor.failed-to-open-text": { "defaultMessage": "Impossibile caricare i contenuti del file." @@ -1271,9 +1259,6 @@ "files.editor.file-saved-title": { "defaultMessage": "File salvato" }, - "files.editor.find-close": { - "defaultMessage": "Chiudi" - }, "files.editor.find-in-file": { "defaultMessage": "Trova" }, @@ -2039,33 +2024,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Scegli un'icona" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Questo pacchetto di mod non include alcun contenuto aggiuntivo." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nessun contenuto trovato" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Esterno" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Questo file non è su Modrinth." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Contenuto del pacchetto" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Caricamento contenuto..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Nessun progetto corrisponde alla tua ricerca." - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "Apri con Slicer" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Cerca tra {count, number} {count, plural, one {progetto} other {progetti}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Attuale" }, @@ -2198,6 +2156,9 @@ "label.details": { "defaultMessage": "Dettagli" }, + "label.discover-content": { + "defaultMessage": "Sfoglia i contenuti" + }, "label.done": { "defaultMessage": "Fatto" }, @@ -2276,6 +2237,9 @@ "label.password": { "defaultMessage": "Password" }, + "label.permissions": { + "defaultMessage": "Permessi" + }, "label.plan-custom": { "defaultMessage": "Ad hoc" }, @@ -2807,9 +2771,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Creatore su Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Utente di Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} non potrà inviarti richieste di amicizia, invitarti alle istanze condivise o invitarti ai server Modrinth Hosting." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Vuoi davvero bloccare quest'utente?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Sì è verificato un errore nel bloccare l'utente. Riprova più tardi." + }, + "profile.block-user.error-title": { + "defaultMessage": "Impossibile bloccare l'utente" + }, + "profile.block-user.success-description": { + "defaultMessage": "Utente {username} bloccato." + }, + "profile.block-user.success-title": { + "defaultMessage": "Utente bloccato" + }, + "profile.block-user.title": { + "defaultMessage": "Blocca {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Mostra analitiche utente" + }, + "profile.button.billing": { + "defaultMessage": "Gestisci fatturato utente" + }, + "profile.button.block": { + "defaultMessage": "Blocca" + }, + "profile.button.create-collection": { + "defaultMessage": "Crea una raccolta" + }, + "profile.button.create-project": { + "defaultMessage": "Crea un progetto" + }, + "profile.button.info": { + "defaultMessage": "Mostra info utente" + }, + "profile.button.manage-projects": { + "defaultMessage": "Gestisci progetti" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Rimuovi da affiliato" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Imposta come affiliato" + }, + "profile.button.unblock": { + "defaultMessage": "Sblocca" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# progetto} other {# progetti}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Consentì i pop-up per Modrinth, poi riprova." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Impossibile recuperare il profilo GitHub. Riprova più tardi." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Errore nell'apertura del profilo GitHub" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Fornitori d'autenticazione" + }, + "profile.details.label.email-verified": { + "defaultMessage": "Email verificata" + }, + "profile.details.label.has-password": { + "defaultMessage": "Usa una password" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Usa un TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Caricamento..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Metodi di pagamento" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Visita profilo" + }, + "profile.details.title": { + "defaultMessage": "Informazioni" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "Email non verificata" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "Email verificata" + }, + "profile.error.load-description": { + "defaultMessage": "Non è stato possibile caricare il profilo." + }, + "profile.error.not-found": { + "defaultMessage": "Utente non trovato" + }, + "profile.label.affiliate": { + "defaultMessage": "Affiliato" + }, "profile.label.badges": { "defaultMessage": "Distintivi" }, + "profile.label.collection": { + "defaultMessage": "Raccolta" + }, + "profile.label.download-count": { + "defaultMessage": "download" + }, + "profile.label.joined": { + "defaultMessage": "Iscrizione" + }, + "profile.label.no-collections": { + "defaultMessage": "Nessuna raccolta qui!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Ancora nessuna raccolta." + }, + "profile.label.no-projects": { + "defaultMessage": "Nessun progetto qui!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Ancora nessun progetto." + }, + "profile.label.organizations": { + "defaultMessage": "Organizzazioni" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {progetto} other {progetti}}" + }, + "profile.official-account": { + "defaultMessage": "Account Modrinth ufficiale" + }, + "profile.official-account.bio": { + "defaultMessage": "L'account ufficiale di Modrinth. Ricevi assistenza presso o tramite mail presso " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Sì è verificato un errore nello sbloccare l'utente. Riprova più tardi." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Impossibile sbloccare l'utente" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "Utente {username} sbloccato." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Utente sbloccato" + }, "project-card.date.published.tooltip": { "defaultMessage": "Pubblicato {date}" }, @@ -2837,6 +2954,9 @@ "project-type.all": { "defaultMessage": "Tutto" }, + "project-type.collection.plural": { + "defaultMessage": "Raccolte" + }, "project-type.datapack.capital": { "defaultMessage": "Pacchett{count, plural, one {o} other {i}} di dati" }, @@ -3629,15 +3749,6 @@ "search.filter_type.advanced": { "defaultMessage": "Avanzate" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Escludi pacchetti di dati" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Escludi mod" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Escludi plugin" - }, "search.filter_type.environment": { "defaultMessage": "Ambiente" }, @@ -4464,7 +4575,7 @@ "defaultMessage": "Installazione fallita" }, "servers.installing-banner.error.internal-platform": { - "defaultMessage": "Si è verificato un errore nell'installazione della piattaforma. Riprova più tardi." + "defaultMessage": "Si è verificato un errore durante l'installazione della piattaforma. Riprova più tardi." }, "servers.installing-banner.error.invalid-loader-version": { "defaultMessage": "Questa versione di Minecraft o del loader non è potuta essere installata. Potrebbe essere non valida o non supportata." @@ -5063,9 +5174,120 @@ "settings.pats.title": { "defaultMessage": "Token di accesso (PAT)" }, + "settings.profile.bio.description": { + "defaultMessage": "Una breve descrizione per raccontare a tutti qualcosa su di te." + }, + "settings.profile.bio.title": { + "defaultMessage": "Bio" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profilo" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Foto profilo" + }, + "settings.profile.public-information.description": { + "defaultMessage": "Le informazioni del tuo profilo sono visibili pubblicamente su Modrinth e tramite l''API di Modrinth." + }, + "settings.profile.save-error": { + "defaultMessage": "Impossibile salvare il profilo" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Si è verificato un errore nel salvataggio del profilo. Riprova più tardi." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Accedi con un account Modrinth per personalizzare il tuo profilo pubblico." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Account Modrinth richiesto" + }, + "settings.profile.username.description": { + "defaultMessage": "Un nome univoco per identificare il tuo profilo (maiuscole irrilevanti)." + }, "settings.sessions.title": { "defaultMessage": "Sessioni" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Azioni" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Utente" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Questi sono gli utenti che hai bloccato su Modrinth. Non potranno:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Non hai bloccato nessuno." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Impossibile caricare gli utenti bloccati." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Caricamento utenti bloccati…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Inviarti richieste di amicizia" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Invitarti a gestire un server Modrinth Hosting." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Invitarti nelle istanze condivise" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Utenti bloccati" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Sblocca" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Impossibile sbloccare l'utente" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Sì è verificato un errore nello sbloccare l'utente. Riprova più tardi." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Sblocca {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Foto profilo di {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Controlla chi può inviarti richieste d'amicizia su Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Richieste di amicizia" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "In arrivo!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Tutti" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Amici" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Amici di amici" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Nessuno" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Controlla chi può invitarti alle istanze condivise e pannelli di Modrinth Hosting." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Inviti" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Puoi controllare chi può interagire con te e gestire gli utenti bloccati con un account Modrinth" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Account Modrinth richiesto" + }, + "settings.social.title": { + "defaultMessage": "Interazioni" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Aggiungi" }, @@ -5075,14 +5297,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Quest'utente ha già ricevuto un invito." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Applica" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Foto profilo di {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Annulla" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Personalizzata..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Annulla" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Personalizzata: {date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Modifica link d'invito." @@ -5090,6 +5315,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "Modifica link di invito" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "In 1 giorno" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "In 1 ora" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "In 7 giorni" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "In 6 ore" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "In 3 giorni" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "In 12 ore" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Scadenza" }, @@ -5430,7 +5673,7 @@ "defaultMessage": "SMP" }, "tag.category.social": { - "defaultMessage": "Società" + "defaultMessage": "Interazione" }, "tag.category.storage": { "defaultMessage": "Immagazzinamento" diff --git a/packages/ui/src/locales/ja-JP/index.json b/packages/ui/src/locales/ja-JP/index.json index 10ed45ffbf..5ea12218d0 100644 --- a/packages/ui/src/locales/ja-JP/index.json +++ b/packages/ui/src/locales/ja-JP/index.json @@ -1,6 +1,6 @@ { "action.no-permission": { - "defaultMessage": "権限がありません" + "defaultMessage": "権限がありません。" }, "affiliate.create.button": { "defaultMessage": "アフィリエイトリンクを作成" @@ -449,12 +449,18 @@ "content.diff-modal.added-count": { "defaultMessage": "{count} 件追加されました" }, + "content.diff-modal.config-files-updated": { + "defaultMessage": "設定変更" + }, "content.diff-modal.diff-type.added": { "defaultMessage": "追加 (依存関係)" }, "content.diff-modal.diff-type.removed": { "defaultMessage": "無効化済み" }, + "content.diff-modal.diff-type.removed-disabled": { + "defaultMessage": "削除済み(無効)" + }, "content.diff-modal.diff-type.updated": { "defaultMessage": "アップデート済み" }, @@ -470,12 +476,33 @@ "content.diff-modal.external-diff-type.updated": { "defaultMessage": "更新されました" }, + "content.diff-modal.game-version-updated": { + "defaultMessage": "ゲームバージョン変更" + }, "content.diff-modal.install-anyway": { "defaultMessage": "それでもインストールする" }, + "content.diff-modal.loader-updated": { + "defaultMessage": "Modローダー変更" + }, + "content.diff-modal.modpack-linked": { + "defaultMessage": "リンク済みモッドパック" + }, + "content.diff-modal.modpack-unlinked": { + "defaultMessage": "未リンクのモッドパック" + }, + "content.diff-modal.modpack-updated": { + "defaultMessage": "Modパックのアップデート" + }, + "content.diff-modal.no-content-changes": { + "defaultMessage": "変更点なし" + }, "content.diff-modal.removed-count": { "defaultMessage": "{count} 件削除されました" }, + "content.diff-modal.removed-disabled-count": { + "defaultMessage": "{count}件 削除済み(無効)" + }, "content.diff-modal.reviewed-files": { "defaultMessage": "ファイルは、(.mrpackなどのファイル形式に関係なく)Modrinthに公開されたもののみ審査されます。" }, @@ -587,18 +614,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "プロジェクト名" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "名前順" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "新しい順" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "古い順" - }, - "content.page-layout.sort.label": { - "defaultMessage": "{mode}" - }, "content.page-layout.update-all": { "defaultMessage": "すべて更新" }, @@ -959,6 +974,9 @@ "external-files.permissions-card.attribution.moderation-status.passed": { "defaultMessage": "審査を通りました" }, + "external-files.permissions-card.attribution.moderation-status.rejected-proof": { + "defaultMessage": "証明が拒否されました" + }, "external-files.permissions-card.badge.attributed": { "defaultMessage": "完了しました" }, @@ -983,6 +1001,9 @@ "external-files.permissions-card.editor.all-rights-reserved": { "defaultMessage": "無断転載禁止/ライセンスなし" }, + "external-files.permissions-card.editor.custom-license-label": { + "defaultMessage": "ライセンスへのリンク" + }, "external-files.permissions-card.editor.custom-license-my-project-label": { "defaultMessage": "ライセンス名はSPDX識別子であることが望ましい" }, @@ -1019,9 +1040,36 @@ "external-files.permissions-card.editor.notes-placeholder": { "defaultMessage": "何かここに書いてください..." }, + "external-files.permissions-card.editor.proof-image-alt": { + "defaultMessage": "証明のスクリーンショット {n}" + }, + "external-files.permissions-card.editor.proof-image-remove": { + "defaultMessage": "画像を削除" + }, + "external-files.permissions-card.editor.proof-images-label": { + "defaultMessage": "証明画像" + }, + "external-files.permissions-card.editor.proof-images-upload-prompt": { + "defaultMessage": "ドラッグ&ドロップしてアップロード、またはクリックして画像を選択" + }, + "external-files.permissions-card.editor.proof-warning.body": { + "defaultMessage": "虚偽の申告や画像の改ざんが発覚した場合、プロジェクトの削除およびアカウントの停止措置が取られる可能性があります。" + }, + "external-files.permissions-card.editor.proof-warning.title": { + "defaultMessage": "Modrinthスタッフが提出された証明を確認・検証する場合があります" + }, + "external-files.permissions-card.editor.save": { + "defaultMessage": "帰属情報を保存" + }, "external-files.permissions-card.editor.select-license-label": { "defaultMessage": "ライセンスを選んでください…" }, + "external-files.permissions-card.editor.type-label": { + "defaultMessage": "パーミッションの理由" + }, + "external-files.permissions-card.error.custom-license-required": { + "defaultMessage": "ライセンスへのリンクを含めてください。ライセンスがない場合は、「All Rights Reserved / ライセンスなし」を選択することをお勧めします。" + }, "external-files.permissions-card.error.explanation-or-images-required": { "defaultMessage": "説明や根拠となる画像を少なくとも一枚提示してください。" }, @@ -1130,12 +1178,30 @@ "external-files.permissions-card.reason.special-permission.description": { "defaultMessage": "あなたは、自身のModパックでこの作品を再配布するための特別な許可を得ています。" }, + "external-files.permissions-card.remove-group": { + "defaultMessage": "グループを削除" + }, + "external-files.permissions-card.remove-group-confirmation.description": { + "defaultMessage": "この操作により、この帰属グループとグループ内のすべてのファイルが完全に削除されます。この操作を取り消すことはできません。" + }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "「{title}」を削除しますか?" + }, + "external-files.permissions-card.remove-group-error.title": { + "defaultMessage": "グループを削除できませんでした" + }, + "external-files.permissions-card.remove-group-shift-hint": { + "defaultMessage": "Shiftキーを押しながらクリックすると確認をスキップします" + }, "external-files.permissions-card.split-file": { "defaultMessage": "グループから削除する" }, "external-files.permissions-card.split-file-error.title": { "defaultMessage": "ファイルの分割に失敗" }, + "external-files.permissions-card.unnamed-multi-group-title": { + "defaultMessage": "{filename} ほか{count}件" + }, "external-files.permissions-card.updated-by-moderator": { "defaultMessage": "モデレーター" }, @@ -1220,9 +1286,6 @@ "files.editor.file-saved-title": { "defaultMessage": "保存済み" }, - "files.editor.find-close": { - "defaultMessage": "閉じる" - }, "files.editor.find-in-file": { "defaultMessage": "検索" }, @@ -2000,24 +2063,6 @@ "instances.content-install.select-icon": { "defaultMessage": "アイコンを選択" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "このModパックに追加コンテンツは一切含まれていません。" - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "コンテンツが見つかりません" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Modpackコンテンツ" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "コンテンツを読み込み中…" - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "該当するプロジェクトがありません。" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "{count, number}件のプロジェクトを検索" - }, "instances.updater-modal.badge.current": { "defaultMessage": "現在" }, @@ -2150,6 +2195,9 @@ "label.details": { "defaultMessage": "詳細" }, + "label.discover-content": { + "defaultMessage": "コンテンツを探す" + }, "label.done": { "defaultMessage": "完了" }, @@ -2228,6 +2276,9 @@ "label.password": { "defaultMessage": "パスワード" }, + "label.permissions": { + "defaultMessage": "権限" + }, "label.plan-custom": { "defaultMessage": "カスタム" }, @@ -2759,9 +2810,90 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Modrinth クリエイター" + }, + "profile.bio.fallback.user": { + "defaultMessage": "Modrinth ユーザー" + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} はあなたにフレンドリクエストの送信、共有インスタンスへの招待、および Modrinth Hosting サーバーへの招待ができなくなります。" + }, + "profile.block-user.admonition-title": { + "defaultMessage": "このユーザーをブロックしてもよろしいですか?" + }, + "profile.block-user.error-description": { + "defaultMessage": "このユーザーのブロック中にエラーが発生しました。もう一度お試しください。" + }, + "profile.block-user.error-title": { + "defaultMessage": "ユーザーのブロックに失敗しました" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} をブロックしました" + }, + "profile.block-user.success-title": { + "defaultMessage": "ユーザーをブロックしました" + }, + "profile.block-user.title": { + "defaultMessage": "{username} をブロック" + }, + "profile.button.analytics": { + "defaultMessage": "ユーザーアナリティクスを表示" + }, + "profile.button.billing": { + "defaultMessage": "ユーザーの請求情報を管理" + }, + "profile.button.block": { + "defaultMessage": "ブロック" + }, + "profile.button.create-collection": { + "defaultMessage": "コレクションを作成" + }, + "profile.button.create-project": { + "defaultMessage": "プロジェクトを作成" + }, + "profile.button.info": { + "defaultMessage": "ユーザーの詳細を表示" + }, + "profile.button.manage-projects": { + "defaultMessage": "プロジェクトを管理" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "アフィリエイトから削除" + }, + "profile.button.set-affiliate": { + "defaultMessage": "アフィリエイトに設定" + }, + "profile.button.unblock": { + "defaultMessage": "ブロック解除" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Modrinth でのポップアップを許可してから、もう一度お試しください。" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "読み込み中…" + }, + "profile.error.not-found": { + "defaultMessage": "ユーザーが見つかりません" + }, "profile.label.badges": { "defaultMessage": "バッジ" }, + "profile.label.no-projects": { + "defaultMessage": "このユーザーはまだプロジェクトがありません!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "まだプロジェクトを何も持っていないようです。" + }, + "profile.label.organizations": { + "defaultMessage": "組織" + }, + "profile.official-account": { + "defaultMessage": "Modrinth 公式アカウント" + }, + "profile.unblock-user.success-title": { + "defaultMessage": "ユーザーのブロックを解除しました" + }, "project-card.date.published.tooltip": { "defaultMessage": "{date}に公開済み" }, @@ -2780,9 +2912,15 @@ "project-card.environment.server": { "defaultMessage": "サーバー" }, + "project-card.environment.singleplayer": { + "defaultMessage": "シングルプレイヤー" + }, "project-type.all": { "defaultMessage": "すべて" }, + "project-type.collection.plural": { + "defaultMessage": "コレクション" + }, "project-type.datapack.capital": { "defaultMessage": "データパック" }, @@ -3572,9 +3710,6 @@ "search.filter_type.advanced": { "defaultMessage": "もっと見る" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "データパックを除く" - }, "search.filter_type.environment": { "defaultMessage": "環境" }, @@ -3641,9 +3776,54 @@ "servers.access-page.activity-log-filter.action-types": { "defaultMessage": "アクション" }, + "servers.access-page.activity-log-filter.action.addon-disabled": { + "defaultMessage": "無効化されたコンテンツ" + }, + "servers.access-page.activity-log-filter.action.addon-enabled": { + "defaultMessage": "有効化されたコンテンツ" + }, + "servers.access-page.activity-log-filter.action.addon-updated": { + "defaultMessage": "更新されたコンテンツ" + }, + "servers.access-page.activity-log-filter.action.addon-uploaded": { + "defaultMessage": "アップロードされたコンテンツ" + }, + "servers.access-page.activity-log-filter.action.backup-created": { + "defaultMessage": "バックアップを作成しました" + }, "servers.access-page.activity-log-filter.action.backup-deleted": { "defaultMessage": "削除されたバックアップ" }, + "servers.access-page.activity-log-filter.action.backup-renamed": { + "defaultMessage": "バックアップの名前を変更しました" + }, + "servers.access-page.activity-log-filter.action.backup-restored": { + "defaultMessage": "バックアップを復元しました" + }, + "servers.access-page.activity-log-filter.action.changed-server-name": { + "defaultMessage": "サーバー名を変更しました" + }, + "servers.access-page.activity-log-filter.action.changed-server-subdomain": { + "defaultMessage": "サーバーのサブドメインを変更しました" + }, + "servers.access-page.activity-log-filter.action.console-cleared": { + "defaultMessage": "コンソールをクリアしました" + }, + "servers.access-page.activity-log-filter.action.console-command-executed": { + "defaultMessage": "コンソールコマンドを実行しました" + }, + "servers.access-page.activity-log-filter.action.file-deleted": { + "defaultMessage": "ファイルを削除しました" + }, + "servers.access-page.activity-log-filter.action.file-edited": { + "defaultMessage": "ファイルを編集しました" + }, + "servers.access-page.activity-log-filter.action.file-renamed": { + "defaultMessage": "ファイル名を変更しました" + }, + "servers.access-page.activity-log-filter.action.file-uploaded": { + "defaultMessage": "ファイルをアップロードしました" + }, "servers.access-page.activity-log-filter.action.game-version-edited": { "defaultMessage": "Minecraftのバージョンを変更しました" }, @@ -3950,6 +4130,93 @@ "servers.audit-log.event.config-changed": { "defaultMessage": "サーバーの設定が変更されました" }, + "servers.audit-log.event.console-cleared": { + "defaultMessage": "コンソールをクリアしました" + }, + "servers.audit-log.event.console-command-executed": { + "defaultMessage": "コンソールコマンド「」を実行しました" + }, + "servers.audit-log.event.entity-list.hidden-count": { + "defaultMessage": "+{count, number}" + }, + "servers.audit-log.event.file-changed": { + "defaultMessage": "ファイル「」を変更しました" + }, + "servers.audit-log.event.file-deleted": { + "defaultMessage": "ファイル「」を削除しました" + }, + "servers.audit-log.event.file-edited": { + "defaultMessage": "ファイル「」を編集しました" + }, + "servers.audit-log.event.file-renamed": { + "defaultMessage": "「」の名前を「」に変更しました" + }, + "servers.audit-log.event.file-uploaded": { + "defaultMessage": "をアップロードしました" + }, + "servers.audit-log.event.game-version-changed": { + "defaultMessage": "Minecraftのバージョンを に変更しました" + }, + "servers.audit-log.event.java-runtime-modified": { + "defaultMessage": "Javaの実行環境を に変更しました" + }, + "servers.audit-log.event.java-version-modified": { + "defaultMessage": "Javaのバージョンを に変更しました" + }, + "servers.audit-log.event.loader-and-version-changed": { + "defaultMessage": "ローダーを に変更しました" + }, + "servers.audit-log.event.loader-changed": { + "defaultMessage": "ローダーを に変更しました" + }, + "servers.audit-log.event.loader-version-changed": { + "defaultMessage": "ローダーのバージョンを に変更しました" + }, + "servers.audit-log.event.loader-version-cleared": { + "defaultMessage": "ローダーのバージョン設定を消去しました" + }, + "servers.audit-log.event.modpack-changed": { + "defaultMessage": "モッドパックを変更しました" + }, + "servers.audit-log.event.modpack-changed-to-modpack": { + "defaultMessage": "モッドパックを に変更しました" + }, + "servers.audit-log.event.modpack-changed-to-version": { + "defaultMessage": "モッドパックのバージョンを に変更しました" + }, + "servers.audit-log.event.modpack-unlinked": { + "defaultMessage": "モッドパックの連携を解除しました" + }, + "servers.audit-log.event.modpack-unlinked-modpack": { + "defaultMessage": "モッドパック の連携を解除しました" + }, + "servers.audit-log.event.modpack-unlinked-version": { + "defaultMessage": "モッドパックのバージョン の連携を解除しました" + }, + "servers.audit-log.event.port-allocation-added": { + "defaultMessage": "ポート割り当て を追加しました" + }, + "servers.audit-log.event.port-allocation-removed": { + "defaultMessage": "ポート割り当て を削除しました" + }, + "servers.audit-log.event.server-created": { + "defaultMessage": "サーバーを作成しました" + }, + "servers.audit-log.event.server-killed": { + "defaultMessage": "サーバーを強制終了しました" + }, + "servers.audit-log.event.server-metadata-changed": { + "defaultMessage": "サーバーのメタデータを変更しました" + }, + "servers.audit-log.event.server-name-changed": { + "defaultMessage": "サーバー名を に変更しました" + }, + "servers.audit-log.event.server-plan-changed": { + "defaultMessage": "プランを に変更しました" + }, + "servers.audit-log.event.server-plan.new-plan": { + "defaultMessage": "新しいプラン" + }, "servers.audit-log.event.server-plan.ram-gb": { "defaultMessage": "メモリ {amount, number} GB" }, @@ -3962,6 +4229,21 @@ "servers.audit-log.event.server-plan.storage-mb": { "defaultMessage": "ストレージ {amount, number} MB" }, + "servers.audit-log.event.server-properties-modified": { + "defaultMessage": "サーバープロパティ を変更しました" + }, + "servers.audit-log.event.server-properties-modified-label": { + "defaultMessage": "サーバープロパティを変更しました" + }, + "servers.audit-log.event.server-reallocated": { + "defaultMessage": "サーバーの割り当てを変更しました" + }, + "servers.audit-log.event.server-repaired": { + "defaultMessage": "サーバーを修復しました" + }, + "servers.audit-log.event.server-reset": { + "defaultMessage": "サーバーをリセットしました" + }, "servers.audit-log.scope.server": { "defaultMessage": "サーバー" }, @@ -4292,15 +4574,66 @@ "servers.listing.notice.pending-change": { "defaultMessage": "あなたのサーバーは {formattedDate}に {planSize} へと {verb, select, downgrade {ダウングレード} other {アップグレード}} されます。" }, + "servers.listing.support-label": { + "defaultMessage": "サポート" + }, + "servers.manage.new-server-button": { + "defaultMessage": "新しいサーバー" + }, + "servers.manage.no-servers-found": { + "defaultMessage": "サーバーは見つかりませんでした。" + }, "servers.manage.reload-button": { "defaultMessage": "再読み込み" }, + "servers.manage.resubscribe-submitted.text": { + "defaultMessage": "現在サーバーがキャンセルされている場合、再課金の試行までに最大10分ほどかかることがあります。" + }, + "servers.manage.resubscribe-submitted.title": { + "defaultMessage": "再購読のリクエストを送信しました" + }, + "servers.manage.resubscribe-success.text": { + "defaultMessage": "サーバーのサブスクリプションが完了しました" + }, + "servers.manage.resubscribe-success.title": { + "defaultMessage": "成功" + }, + "servers.manage.servers-title": { + "defaultMessage": "Modrinth ホスティング" + }, + "servers.manage.settings-hint.description": { + "defaultMessage": "こちらに移動しました!" + }, + "servers.manage.settings-hint.dismiss": { + "defaultMessage": "次回から表示しない" + }, + "servers.manage.settings-hint.title": { + "defaultMessage": "サーバー設定の場所が移動しました" + }, + "servers.manage.shared-servers-title": { + "defaultMessage": "共有サーバー" + }, "servers.manage.your-servers-title": { "defaultMessage": "あなたのサーバー" }, "servers.medal-listing.new-server-label": { "defaultMessage": "新しいサーバー" }, + "servers.medal-listing.notice.medal-trial-ended": { + "defaultMessage": "Medalサーバーの試用期間が終了し、サーバーがサスペンド(停止)されました。サーバーを引き続き利用するにはアップグレードしてください。" + }, + "servers.medal-listing.notice.suspended": { + "defaultMessage": "サーバーがサスペンド(停止)されました。請求情報を更新するか、詳細は Modrinth サポートにお問い合わせください。" + }, + "servers.medal-listing.notice.suspended-with-reason": { + "defaultMessage": "サーバーがサスペンド(停止)されました: {reason}。請求情報を更新するか、詳細は Modrinth サポートにお問い合わせください。" + }, + "servers.medal-listing.notice.upgrading": { + "defaultMessage": "サーバーのハードウェアをアップグレード中です。まもなくオンラインに戻ります。" + }, + "servers.medal-listing.owner-avatar-alt": { + "defaultMessage": "{username} のアバター" + }, "servers.medal-listing.owner-tooltip": { "defaultMessage": "{username}によって所有されています" }, @@ -4355,9 +4688,15 @@ "servers.purchase.step.payment.title": { "defaultMessage": "支払い方法" }, + "servers.purchase.step.plan.billing-subtitle": { + "defaultMessage": "北米、ヨーロッパ、東南アジアでご利用いただけます。" + }, "servers.purchase.step.plan.custom.desc": { "defaultMessage": "必要な仕様だけのカスタマイズされたプランを選択。" }, + "servers.purchase.step.plan.custom.heading": { + "defaultMessage": "必要なものがお決まりですか?" + }, "servers.purchase.step.plan.get-started": { "defaultMessage": "始めましょう" }, @@ -4388,6 +4727,9 @@ "servers.purchase.step.plan.title": { "defaultMessage": "プラン" }, + "servers.purchase.step.plan.your-current-plan": { + "defaultMessage": "現在のプラン" + }, "servers.purchase.step.region.title": { "defaultMessage": "地域" }, @@ -4427,12 +4769,99 @@ "servers.region.western-europe": { "defaultMessage": "西ヨーロッパ" }, + "servers.remove-access-modal.added-label": { + "defaultMessage": "{time} に追加済み" + }, + "servers.remove-access-modal.cancel-button": { + "defaultMessage": "招待を取り消す" + }, + "servers.remove-access-modal.cancel-effect-access": { + "defaultMessage": "このサーバーには追加されません" + }, + "servers.remove-access-modal.cancel-effect-invite": { + "defaultMessage": "あとから再度招待を送ることもできます" + }, + "servers.remove-access-modal.cancel-header": { + "defaultMessage": "招待を取り消す" + }, + "servers.remove-access-modal.cancel-warning-body": { + "defaultMessage": "この招待を取り消すと、{username} がこのサーバーに参加するには新しい招待が必要になります。" + }, + "servers.remove-access-modal.header": { + "defaultMessage": "アクセス権を取り消す" + }, + "servers.remove-access-modal.invited-label": { + "defaultMessage": "{time} に招待済み" + }, + "servers.remove-access-modal.pending-invite-label": { + "defaultMessage": "保留中の招待" + }, + "servers.remove-access-modal.remove-button": { + "defaultMessage": "アクセス権を取り消す" + }, + "servers.remove-access-modal.remove-effect-access": { + "defaultMessage": "サーバーパネルへのアクセス権が即座に無効化され、コンテンツの編集ができなくなります" + }, + "servers.remove-access-modal.remove-effect-join": { + "defaultMessage": "個別に設定を変更しない限り、ユーザーは引き続きサーバーに参加してプレイすることができます" + }, + "servers.remove-access-modal.unknown-added-label": { + "defaultMessage": "追加日不明" + }, + "servers.remove-access-modal.user-avatar-alt": { + "defaultMessage": "{username} のアバター" + }, + "servers.remove-access-modal.warning-body": { + "defaultMessage": "ユーザーのサーバーアクセス権を取り消した場合、アクセスを復元するには再度招待し直す必要があります。" + }, + "servers.remove-access-modal.what-happens-label": { + "defaultMessage": "どうなるの?" + }, + "servers.setup.onboarding.installation-failed.text": { + "defaultMessage": "インストール中に予期しないエラーが発生しました。時間をおいて再度お試しください。" + }, + "servers.setup.onboarding.installation-failed.title": { + "defaultMessage": "インストールの失敗" + }, + "servers.setup.onboarding.modpack-upload-failed.text": { + "defaultMessage": "アップロード中に予期しないエラーが発生しました。時間をおいて再度お試しください。" + }, + "servers.setup.onboarding.modpack-upload-failed.title": { + "defaultMessage": "モッドパックのアップロード失敗" + }, "servers.setup.onboarding.setup-server.button": { "defaultMessage": "サーバーをセットアップ" }, + "servers.setup.onboarding.step.choose.description": { + "defaultMessage": "Modrinthからお気に入りのモッドパックを選ぶか、ローダーを選択して好きなModを追加してください" + }, + "servers.setup.onboarding.step.choose.title": { + "defaultMessage": "プレイするものを選ぶ" + }, + "servers.setup.onboarding.step.configure-world.description": { + "defaultMessage": "シングルプレイと同じようにワールドを設定できます。ゲームモードとワールドシード値を選択してください" + }, + "servers.setup.onboarding.step.configure-world.title": { + "defaultMessage": "ワールドを設定する" + }, + "servers.setup.onboarding.step.invite-friends.description": { + "defaultMessage": "アドレスをコピーして友達に共有し、参加に必要なModを教えてあげましょう" + }, "servers.setup.onboarding.step.invite-friends.title": { "defaultMessage": "フレンドを招待" }, + "servers.setup.onboarding.steps.heading": { + "defaultMessage": "サーバーをセットアップする(約2分)" + }, + "servers.setup.onboarding.uploading.progress": { + "defaultMessage": "アップロード中 ({percent, number}%)" + }, + "servers.setup.onboarding.welcome.description": { + "defaultMessage": "サーバーの準備が完了しました。プレイを開始する手順は以下の通りです!" + }, + "servers.setup.onboarding.welcome.title": { + "defaultMessage": "Modrinth ホスティングへようこそ" + }, "servers.setup.rate-limit.text": { "defaultMessage": "レート制限に達しました。時間をおいて再試行してください。" }, @@ -4493,6 +4922,9 @@ "settings.display.theme.title": { "defaultMessage": "カラーテーマ" }, + "settings.feature-flags.title": { + "defaultMessage": "機能フラグ" + }, "settings.language.categories.default": { "defaultMessage": "一般的な言語" }, @@ -4526,9 +4958,57 @@ "settings.pats.title": { "defaultMessage": "個人用アクセストークン" }, + "settings.profile.bio.title": { + "defaultMessage": "自己紹介" + }, + "settings.profile.navigation-title": { + "defaultMessage": "プロファイル" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "プロファイルアイコン" + }, "settings.sessions.title": { "defaultMessage": "セッション" }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "ブロックを解除" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "近日公開!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "全員" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "フレンド" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "フレンドのフレンド" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "なし" + }, + "sharing.invite-players-modal.add": { + "defaultMessage": "追加" + }, + "sharing.invite-players-modal.added": { + "defaultMessage": "追加済み" + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "適用" + }, + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "カスタム…" + }, + "sharing.invite-players-modal.friends-heading": { + "defaultMessage": "あなたのフレンド - {count} 人" + }, + "sharing.invite-players-modal.invite": { + "defaultMessage": "招待" + }, + "sharing.invite-players-modal.save-button": { + "defaultMessage": "保存" + }, "tag.category.128x": { "defaultMessage": "128x" }, @@ -4998,16 +5478,16 @@ "defaultMessage": "一般的にマルウェアは、Discord等のプラットフォーム上でModファイルを配布して拡散されます" }, "user.profile.badge.alpha.about.1": { - "defaultMessage": "2020年11月までのModrinthがAlpha版だった頃から活動しています" + "defaultMessage": "2020年11月までのModrinthがAlpha版の頃から活動しています" }, "user.profile.badge.alpha.name": { "defaultMessage": "Alpha Tester" }, "user.profile.badge.beta.about.1": { - "defaultMessage": "2022年2月までのModrinthがBeta版だった頃から活動しています" + "defaultMessage": "2022年2月までのModrinthがBeta版の頃から活動しています" }, "user.profile.badge.beta.link": { - "defaultMessage": "クリックすると、ModrinthのBeta版のリリース記事を読むことができます。" + "defaultMessage": "クリックするとModrinthのBeta版リリース記事を読むことができます" }, "user.profile.badge.beta.name": { "defaultMessage": "Beta Tester" @@ -5021,6 +5501,12 @@ "user.profile.badge.moderator.name": { "defaultMessage": "コンテンツモデレーター" }, + "user.profile.badge.plus.about.1": { + "defaultMessage": "Modrinthとクリエイターに特別なサポートを贈っています!" + }, + "user.profile.badge.plus.link": { + "defaultMessage": "クリックしてModrinth+のメンバーになる方法を知る" + }, "user.profile.badge.plus.name": { "defaultMessage": "Modrinth+ Member" }, @@ -5045,6 +5531,9 @@ "version.section.content.search-placeholder": { "defaultMessage": "コンテンツを検索…" }, + "version.section.dependencies.any-version": { + "defaultMessage": "すべてのバージョン" + }, "version.section.files": { "defaultMessage": "ファイル" }, diff --git a/packages/ui/src/locales/ko-KR/index.json b/packages/ui/src/locales/ko-KR/index.json index 33db6fadd9..15607e421c 100644 --- a/packages/ui/src/locales/ko-KR/index.json +++ b/packages/ui/src/locales/ko-KR/index.json @@ -377,6 +377,9 @@ "content.confirm-deletion.header": { "defaultMessage": "{itemType} 삭제" }, + "content.confirm-disable.header": { + "defaultMessage": "{itemType} 비활성화" + }, "content.confirm-modpack-update.admonition-body": { "defaultMessage": "{action, select, downgrade {다운그레이드 진행 중} other {업데이트 진행 중}}에는 호환성 문제가 발생할 수 있습니다. 모드팩에 추가한 모드나 콘텐츠는 유지되지만, 새 버전과 호환되지 않을 수 있습니다." }, @@ -446,12 +449,18 @@ "content.diff-modal.added-count": { "defaultMessage": "{count}개 추가됨" }, + "content.diff-modal.config-files-updated": { + "defaultMessage": "변경된 설정 파일" + }, "content.diff-modal.diff-type.added": { "defaultMessage": "추가됨 (종속성)" }, "content.diff-modal.diff-type.removed": { "defaultMessage": "비활성화" }, + "content.diff-modal.diff-type.removed-disabled": { + "defaultMessage": "제거됨 (비활성화됨)" + }, "content.diff-modal.diff-type.updated": { "defaultMessage": "업데이트됨" }, @@ -467,12 +476,36 @@ "content.diff-modal.external-diff-type.updated": { "defaultMessage": "업데이트됨" }, + "content.diff-modal.file-count": { + "defaultMessage": "{count, plural, one {#개 파일} other {#개 파일}}" + }, + "content.diff-modal.game-version-updated": { + "defaultMessage": "게임 버전" + }, "content.diff-modal.install-anyway": { "defaultMessage": "무시하고 설치" }, + "content.diff-modal.loader-updated": { + "defaultMessage": "로더" + }, + "content.diff-modal.modpack-linked": { + "defaultMessage": "연동된 모드팩" + }, + "content.diff-modal.modpack-unlinked": { + "defaultMessage": "연동 해제된 모드팩" + }, + "content.diff-modal.modpack-updated": { + "defaultMessage": "업데이트된 모드팩" + }, + "content.diff-modal.no-content-changes": { + "defaultMessage": "콘텐츠 변경 사항 없음" + }, "content.diff-modal.removed-count": { "defaultMessage": "{count}개 제거됨" }, + "content.diff-modal.removed-disabled-count": { + "defaultMessage": "{count} 제거됨 (비활성화됨)" + }, "content.diff-modal.reviewed-files": { "defaultMessage": "모든 파일은 형식(.mrpack 포함)에 무관하게 Modrinth에 게시되어야만 검수를 거칩니다." }, @@ -584,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "프로젝트 이름" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "알파벳순" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "최신순" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "오래된순" - }, - "content.page-layout.sort.label": { - "defaultMessage": "{mode}으로 정렬" - }, "content.page-layout.update-all": { "defaultMessage": "모두 업데이트" }, @@ -1160,6 +1181,21 @@ "external-files.permissions-card.reason.special-permission.description": { "defaultMessage": "이 작업물을 모드팩에 재배포할 수 있는 특별 허가를 받았습니다." }, + "external-files.permissions-card.remove-group": { + "defaultMessage": "그룹 삭제" + }, + "external-files.permissions-card.remove-group-confirmation.description": { + "defaultMessage": "이 작업은 해당 출처 표시 그룹 및 내부의 모든 파일을 영구 삭제합니다. 이 작업은 되돌릴 수 없습니다." + }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "{title}를 삭제하시겠습니까?" + }, + "external-files.permissions-card.remove-group-error.title": { + "defaultMessage": "그룹을 삭제할 수 없습니다" + }, + "external-files.permissions-card.remove-group-shift-hint": { + "defaultMessage": "Shift 키를 누른 채 클릭하면 확인 절차를 생략합니다." + }, "external-files.permissions-card.split-file": { "defaultMessage": "그룹에서 제거" }, @@ -1253,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "파일 저장됨" }, - "files.editor.find-close": { - "defaultMessage": "닫다" - }, "files.editor.find-in-file": { "defaultMessage": "찾다" }, @@ -2033,24 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "아이콘 선택" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "이 모드팩에는 추가 콘텐츠가 포함되어 있지 않습니다." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "콘텐츠를 찾을 수 없습니다" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "모드팩 콘텐츠" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "콘텐츠 불러오는 중..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "검색 결과와 일치하는 프로젝트가 없습니다." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "{count, number}개의 프로젝트 검색" - }, "instances.updater-modal.badge.current": { "defaultMessage": "현재" }, @@ -2183,6 +2198,9 @@ "label.details": { "defaultMessage": "세부 사항" }, + "label.discover-content": { + "defaultMessage": "콘텐츠 둘러보기" + }, "label.done": { "defaultMessage": "완료" }, @@ -2261,6 +2279,9 @@ "label.password": { "defaultMessage": "비밀번호" }, + "label.permissions": { + "defaultMessage": "권한" + }, "label.plan-custom": { "defaultMessage": "사용자 지정" }, @@ -2792,9 +2813,147 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Modrinth 크리에이터입니다." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Modrinth 사용자입니다." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} 님은 친구 요청을 보내거나, 공유 인스턴스 초대 및 Modrinth Hosting 서버 초대를 할 수 없게 됩니다." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "이 사용자를 차단하시겠습니까?" + }, + "profile.block-user.error-description": { + "defaultMessage": "이 사용자를 차단하는 중 오류가 발생했습니다. 다시 시도해 주세요." + }, + "profile.block-user.error-title": { + "defaultMessage": "사용자 차단 실패" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} 님을 차단했습니다." + }, + "profile.block-user.success-title": { + "defaultMessage": "사용자 차단됨" + }, + "profile.block-user.title": { + "defaultMessage": "{username} 차단" + }, + "profile.button.analytics": { + "defaultMessage": "사용자 분석 보기" + }, + "profile.button.billing": { + "defaultMessage": "사용자 결제 관리" + }, + "profile.button.block": { + "defaultMessage": "차단" + }, + "profile.button.create-collection": { + "defaultMessage": "컬렉션 만들기" + }, + "profile.button.create-project": { + "defaultMessage": "프로젝트 만들기" + }, + "profile.button.info": { + "defaultMessage": "사용자 상세 정보 보기" + }, + "profile.button.manage-projects": { + "defaultMessage": "프로젝트 관리" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "제휴 자격 해제" + }, + "profile.button.set-affiliate": { + "defaultMessage": "제휴 자격 부여" + }, + "profile.button.unblock": { + "defaultMessage": "차단 해제" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {프로젝트 #개} other {프로젝트 #개}}" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "인증 제공자" + }, + "profile.details.label.email-verified": { + "defaultMessage": "이메일 인증됨" + }, + "profile.details.label.has-password": { + "defaultMessage": "비밀번호 설정됨" + }, + "profile.details.label.has-totp": { + "defaultMessage": "TOTP 설정됨" + }, + "profile.details.label.payment-methods": { + "defaultMessage": "결제 수단" + }, + "profile.details.title": { + "defaultMessage": "사용자 상세 정보" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "이메일 미인증" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "이메일 인증됨" + }, + "profile.error.load-description": { + "defaultMessage": "사용자 프로필을 불러올 수 없습니다." + }, + "profile.error.not-found": { + "defaultMessage": "사용자를 찾을 수 없음" + }, + "profile.label.affiliate": { + "defaultMessage": "제휴 파트너" + }, "profile.label.badges": { "defaultMessage": "배지" }, + "profile.label.collection": { + "defaultMessage": "컬렉션" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, other {다운로드}}" + }, + "profile.label.joined": { + "defaultMessage": "가입일" + }, + "profile.label.no-collections": { + "defaultMessage": "이 사용자는 컬렉션이 없습니다!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "아직 컬렉션이 없습니다." + }, + "profile.label.no-projects": { + "defaultMessage": "이 사용자는 프로젝트가 없습니다!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "아직 프로젝트가 없습니다." + }, + "profile.label.organizations": { + "defaultMessage": "조직" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, other {프로젝트}}" + }, + "profile.official-account": { + "defaultMessage": "공식 Modrinth 계정" + }, + "profile.official-account.bio": { + "defaultMessage": "Modrinth의 공식 사용자 계정입니다. 또는 을 통해 문의해 주세요" + }, + "profile.unblock-user.error-description": { + "defaultMessage": "이 사용자의 차단을 해제하는 동안 오류가 발생했습니다. 다시 시도해 주세요." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "사용자 차단 해제 실패" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username}님의 차단이 해제되었습니다." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "사용자 차단 해제됨" + }, "project-card.date.published.tooltip": { "defaultMessage": "{date}에 게시됨" }, @@ -2810,12 +2969,21 @@ "project-card.environment.client-or-server": { "defaultMessage": "클라이언트 또는 서버" }, + "project-card.environment.dedicated-server": { + "defaultMessage": "전용 서버" + }, "project-card.environment.server": { "defaultMessage": "서버" }, + "project-card.environment.singleplayer": { + "defaultMessage": "싱글플레이어" + }, "project-type.all": { "defaultMessage": "모두" }, + "project-type.collection.plural": { + "defaultMessage": "컬렉션" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, other {데이터 팩}}" }, @@ -3608,15 +3776,6 @@ "search.filter_type.advanced": { "defaultMessage": "고급" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "데이터 팩 제외" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "모드 제외" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "플러그인 제외" - }, "search.filter_type.environment": { "defaultMessage": "실행 환경" }, @@ -5039,9 +5198,216 @@ "settings.pats.title": { "defaultMessage": "개인 액세스 토큰" }, + "settings.profile.bio.description": { + "defaultMessage": "자신을 알릴 수 있는 간단한 소개글입니다." + }, + "settings.profile.bio.title": { + "defaultMessage": "자기소개" + }, + "settings.profile.navigation-title": { + "defaultMessage": "프로필" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "프로필 사진" + }, + "settings.profile.public-information.description": { + "defaultMessage": "프로필 정보는 Modrinth에서 누구나 볼 수 있게 공개되며, Modrinth API를 통해서도 확인할 수 있습니다." + }, + "settings.profile.save-error": { + "defaultMessage": "프로필 업데이트 실패" + }, + "settings.profile.save-error-description": { + "defaultMessage": "프로필을 업데이트하는 동안 오류가 발생했습니다. 다시 시도해 주세요." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "공개 프로필을 맞춤 설정하려면 Modrinth 계정에 로그인하세요." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Modrinth 계정 필요" + }, + "settings.profile.username.description": { + "defaultMessage": "프로필을 식별하기 위한 대소문자 구분 없는 고유한 이름입니다." + }, "settings.sessions.title": { "defaultMessage": "세션" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "작업" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "사용자" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Modrinth에서 차단한 사용자 목록입니다. 해당 사용자는 다음 행위를 할 수 없습니다:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "차단한 사용자가 없습니다." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "차단된 사용자 목록을 불러올 수 없습니다." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "차단된 사용자 목록 불러오는 중…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "나에게 친구 요청 전송" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Modrinth 호스팅 서버 관리 초대." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "공유 인스턴스에 초대" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "차단된 사용자" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "차단 해제" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "사용자 차단 해제 실패" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "이 사용자의 차단을 해제하는 중 오류가 발생했습니다. 다시 시도해 주세요." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "{username} 차단 해제" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "{username} 님의 아바타" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Modrinth에서 본인에게 친구 요청을 보낼 수 있는 사람을 설정합니다." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "친구 요청" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "곧 제공할 예정입니다!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "모든 사람" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "친구" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "친구의 친구" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "아무도 없음" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "공유 인스턴스 및 Modrinth Hosting 패널 초대를 보낼 수 있는 사람을 설정합니다." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "초대" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Modrinth 계정이 있으면 본인과 소통 가능한 사람을 설정하고 차단된 사용자를 관리할 수 있습니다" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Modrinth 계정이 필요합니다" + }, + "settings.social.title": { + "defaultMessage": "소셜" + }, + "sharing.invite-players-modal.add": { + "defaultMessage": "추가" + }, + "sharing.invite-players-modal.added": { + "defaultMessage": "추가됨" + }, + "sharing.invite-players-modal.already-invited": { + "defaultMessage": "이 사용자는 이미 초대되었습니다." + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "선택" + }, + "sharing.invite-players-modal.avatar-alt": { + "defaultMessage": "{username} 님의 아바타" + }, + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "커스텀..." + }, + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "커스텀: {date}" + }, + "sharing.invite-players-modal.edit-invite-link": { + "defaultMessage": "초대 링크 수정." + }, + "sharing.invite-players-modal.edit-invite-link-title": { + "defaultMessage": "초대 링크 수정" + }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "1일 후" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "1시간 후" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "7일 후" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "6시간 후" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "3일 후" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "12시간 후" + }, + "sharing.invite-players-modal.expiry-label": { + "defaultMessage": "만료일" + }, + "sharing.invite-players-modal.friends-heading": { + "defaultMessage": "당신의 친구 - {count}" + }, + "sharing.invite-players-modal.invite": { + "defaultMessage": "초대" + }, + "sharing.invite-players-modal.invite-expiry-description": { + "defaultMessage": "초대 링크는 {duration} 후 만료됩니다." + }, + "sharing.invite-players-modal.invite-link-heading": { + "defaultMessage": "또는 초대 링크 사용" + }, + "sharing.invite-players-modal.link-copied-text": { + "defaultMessage": "초대 링크가 클립보드에 복사되었습니다." + }, + "sharing.invite-players-modal.link-copied-title": { + "defaultMessage": "링크 복사됨" + }, + "sharing.invite-players-modal.link-copy-failed-title": { + "defaultMessage": "링크 복사 실패" + }, + "sharing.invite-players-modal.max-uses-label": { + "defaultMessage": "최대 사용 횟수" + }, + "sharing.invite-players-modal.no-friends": { + "defaultMessage": "친구가 없습니다." + }, + "sharing.invite-players-modal.no-search-results": { + "defaultMessage": "일치하는 사용자를 찾을 수 없습니다." + }, + "sharing.invite-players-modal.requested": { + "defaultMessage": "요청 전송됨" + }, + "sharing.invite-players-modal.requested-tooltip": { + "defaultMessage": "{username}님이 먼저 친구 요청을 수락해야 합니다" + }, + "sharing.invite-players-modal.save-button": { + "defaultMessage": "저장" + }, + "sharing.invite-players-modal.search-placeholder": { + "defaultMessage": "Modrinth 사용자 이름 입력" + }, + "sharing.invite-players-modal.searching": { + "defaultMessage": "검색 중..." + }, + "sharing.invite-players-modal.update-invite-link-failed-title": { + "defaultMessage": "초대 링크 업데이트 실패" + }, "tag.category.128x": { "defaultMessage": "128x" }, diff --git a/packages/ui/src/locales/ms-MY/index.json b/packages/ui/src/locales/ms-MY/index.json index 26c129ef81..ae5c62cbf3 100644 --- a/packages/ui/src/locales/ms-MY/index.json +++ b/packages/ui/src/locales/ms-MY/index.json @@ -386,6 +386,9 @@ "content.diff-modal.diff-type.updated": { "defaultMessage": "Dikemas Kini" }, + "content.diff-modal.external-diff-type.added": { + "defaultMessage": "Ditambah" + }, "content.diff-modal.removed-count": { "defaultMessage": "{count} dialih keluar" }, @@ -485,18 +488,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nama projek" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Mengikut abjad" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Paling baharu dahulu" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Paling lama dahulu" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Isih mengikut {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Kemas kini semua" }, @@ -911,9 +902,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Fail disimpan" }, - "files.editor.find-close": { - "defaultMessage": "Tutup" - }, "files.editor.find-in-file": { "defaultMessage": "Cari" }, @@ -1679,24 +1667,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Pilih ikon" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Pek mod ini tidak menyertakan sebarang kandungan tambahan." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Tiada kandungan dijumpai" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Kandungan pek mod" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Sedang memuat kandungan..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Tiada projek yang sepadan dengan carian anda." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Cari {count, number} {count, plural, other {projek}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Semasa" }, @@ -2402,6 +2372,9 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.button.block": { + "defaultMessage": "Sekat" + }, "profile.label.badges": { "defaultMessage": "Lencana" }, @@ -4442,9 +4415,27 @@ "settings.pats.title": { "defaultMessage": "Token akses peribadi" }, + "settings.profile.bio.title": { + "defaultMessage": "Bio" + }, "settings.sessions.title": { "defaultMessage": "Sesi" }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Pengguna" + }, + "sharing.invite-players-modal.add": { + "defaultMessage": "Tambah" + }, + "sharing.invite-players-modal.added": { + "defaultMessage": "Ditambah" + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Terapkan" + }, + "sharing.invite-players-modal.save-button": { + "defaultMessage": "Simpan" + }, "tag.category.128x": { "defaultMessage": "128x" }, diff --git a/packages/ui/src/locales/nl-NL/index.json b/packages/ui/src/locales/nl-NL/index.json index 12973c623a..1773510c25 100644 --- a/packages/ui/src/locales/nl-NL/index.json +++ b/packages/ui/src/locales/nl-NL/index.json @@ -3,22 +3,22 @@ "defaultMessage": "Je hebt geen toestemming." }, "affiliate.create.button": { - "defaultMessage": "Maak een affiliatelink" + "defaultMessage": "Partnerlink aanmaken" }, "affiliate.create.header": { - "defaultMessage": "Nieuwe affiliate aanmaken" + "defaultMessage": "Nieuwe partnercode aanmaken" }, "affiliate.create.title.description": { - "defaultMessage": "Geef je affiliate-link een naam, zodat je weet waar mensen vandaan komen!" + "defaultMessage": "Geef je partnerlink een naam, zodat je weet waar mensen vandaan komen!" }, "affiliate.create.title.label": { - "defaultMessage": "Titel van affiliate-link" + "defaultMessage": "Titel van de partnerlink" }, "affiliate.create.title.placeholder": { - "defaultMessage": "bijvoorbeeld YouTube" + "defaultMessage": "bijv. YouTube" }, "affiliate.create.user.description": { - "defaultMessage": "De gebruikersnaam van de gebruiker voor wie de affiliatecode moet worden aangemaakt" + "defaultMessage": "De gebruikersnaam van de gebruiker voor wie de partnercode moet worden aangemaakt" }, "affiliate.create.user.placeholder": { "defaultMessage": "Voer gebruikersnaam in..." @@ -27,13 +27,13 @@ "defaultMessage": "Gemaakt door {user}" }, "affiliate.creating.button": { - "defaultMessage": "Affiliate-link maken..." + "defaultMessage": "Partnerlink maken..." }, "affiliate.revoke": { - "defaultMessage": "Affiliatie-link intrekken" + "defaultMessage": "Partnerlink intrekken" }, "affiliate.viewAnalytics": { - "defaultMessage": "Bekijk analyses" + "defaultMessage": "Statistieken bekijken" }, "app.server-settings.failed-to-load-server": { "defaultMessage": "Serverinstellingen konden niet worden geladen" @@ -135,7 +135,7 @@ "defaultMessage": "Voeg server toevoegen aan instantie" }, "button.affiliate-links": { - "defaultMessage": "Affiliatelinks" + "defaultMessage": "Partnerlinks" }, "button.analytics": { "defaultMessage": "Analytica" @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Projectnamen" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetisch" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Nieuwste eerst" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Oudste eerst" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sorteer op {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Werk alles bij" }, @@ -1301,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Bestand opgeslagen" }, - "files.editor.find-close": { - "defaultMessage": "Sluiten" - }, "files.editor.find-in-file": { "defaultMessage": "Vind" }, @@ -2078,33 +2063,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Selecteer pictogram" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Deze modpack bevat geen extra inhoud." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Geen inhoud gevonden" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Extern" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Dit bestand is niet gepubliceerd op Modrinth." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Inhoud van modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Inhoud aan het laden..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Geen projecten voldoen aan je zoekopdracht." - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "In Slicer openen" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Zoek naar {count, number} {count, plural, one {project} other {projecten}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Huidige" }, @@ -2231,6 +2189,9 @@ "label.details": { "defaultMessage": "Details" }, + "label.discover-content": { + "defaultMessage": "Ontdek inhoud" + }, "label.done": { "defaultMessage": "Klaar" }, @@ -2309,6 +2270,9 @@ "label.password": { "defaultMessage": "Wachtwoord" }, + "label.permissions": { + "defaultMessage": "Machtigingen" + }, "label.plan-custom": { "defaultMessage": "Op maat" }, @@ -2840,9 +2804,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Een maker op Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Een gebruiker van Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} zal je geen vriendschapsverzoeken kunnen sturen, je niet kunnen uitnodigen voor gedeelde instanties en je ook niet kunnen uitnodigen voor Modrinth Hosting-servers." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Weet je zeker dat je deze gebruiker wilt blokkeren?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Er is een fout opgetreden bij het blokkeren van deze gebruiker. Probeer het nog eens." + }, + "profile.block-user.error-title": { + "defaultMessage": "Gebruiker blokkeren mislukt" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} is geblokkeerd." + }, + "profile.block-user.success-title": { + "defaultMessage": "Gebruiker geblokkeerd" + }, + "profile.block-user.title": { + "defaultMessage": "{username} blokkeren" + }, + "profile.button.analytics": { + "defaultMessage": "Gebruikersstatistieken bekijken" + }, + "profile.button.billing": { + "defaultMessage": "Gebruikersfacturering beheren" + }, + "profile.button.block": { + "defaultMessage": "Blokkeren" + }, + "profile.button.create-collection": { + "defaultMessage": "Een collectie aanmaken" + }, + "profile.button.create-project": { + "defaultMessage": "Een project aanmaken" + }, + "profile.button.info": { + "defaultMessage": "Gebruikersgegevens bekijken" + }, + "profile.button.manage-projects": { + "defaultMessage": "Projecten beheren" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Als partner verwijderen" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Als partner instellen" + }, + "profile.button.unblock": { + "defaultMessage": "Deblokkeren" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# project} other {# projecten}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Schakel pop-ups voor Modrinth in en probeer het vervolgens opnieuw." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Het GitHub-profiel kon niet worden opgehaald. Probeer het nog eens." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Kan GitHub-profiel niet openen" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Authenticatieproviders" + }, + "profile.details.label.email-verified": { + "defaultMessage": "E-mailadres geverifieerd" + }, + "profile.details.label.has-password": { + "defaultMessage": "Heeft wachtwoord" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Heeft TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Laden..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Betaalmethoden" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Profiel bekijken" + }, + "profile.details.title": { + "defaultMessage": "Gebruikersgegevens" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "E-mailadres niet geverifieerd" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "E-mailadres geverifieerd" + }, + "profile.error.load-description": { + "defaultMessage": "Het profiel kon niet worden geladen." + }, + "profile.error.not-found": { + "defaultMessage": "Gebruiker niet gevonden" + }, + "profile.label.affiliate": { + "defaultMessage": "Partner" + }, "profile.label.badges": { "defaultMessage": "Badges" }, + "profile.label.collection": { + "defaultMessage": "Collectie" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {download} other {downloads}}" + }, + "profile.label.joined": { + "defaultMessage": "Lid sinds" + }, + "profile.label.no-collections": { + "defaultMessage": "Deze gebruiker heeft geen collecties!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Je hebt nog geen collecties." + }, + "profile.label.no-projects": { + "defaultMessage": "Deze gebruiker heeft geen projecten!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Je hebt nog geen projecten." + }, + "profile.label.organizations": { + "defaultMessage": "Organisaties" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {project} other {projecten}}" + }, + "profile.official-account": { + "defaultMessage": "Officieel Modrinth-account" + }, + "profile.official-account.bio": { + "defaultMessage": "Het officiële gebruikersaccount van Modrinth. Neem contact op met het Helpcentrum via of per e-mail via " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Er is een fout opgetreden bij het deblokkeren van deze gebruiker. Probeer het nog eens." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Kan gebruiker niet deblokkeren" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} is gedeblokkeerd." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Gebruiker gedeblokkeerd" + }, "project-card.date.published.tooltip": { "defaultMessage": "Gepubliceerd op {date}" }, @@ -2870,6 +2987,9 @@ "project-type.all": { "defaultMessage": "Alles" }, + "project-type.collection.plural": { + "defaultMessage": "Collecties" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Gegevenspakket} other {Gegevenspakketten}}" }, @@ -3546,7 +3666,7 @@ "defaultMessage": "Upload" }, "project.settings.versions.permissions": { - "defaultMessage": "Toestemmingen" + "defaultMessage": "Machtigingen" }, "project.settings.versions.title": { "defaultMessage": "Versies" @@ -3662,15 +3782,6 @@ "search.filter_type.advanced": { "defaultMessage": "Gevorderd" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Gegevenspakketten uitsluiten" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Mods uitsluiten" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Plug-ins uitsluiten" - }, "search.filter_type.environment": { "defaultMessage": "Omgeving" }, @@ -4632,7 +4743,7 @@ "defaultMessage": "Je abonnement wordt op {formattedDate} opgezegd. " }, "servers.listing.notice.suspended": { - "defaultMessage": "Je server is opgeschort. Neem contact op met de klantenservice van Modrinth voor meer informatie." + "defaultMessage": "Je server is opgeschort. Neem contact op met Modrinth-ondersteuning voor meer informatie." }, "servers.listing.notice.upgrading": { "defaultMessage": "De hardware van uw server wordt momenteel geüpgraded en zal binnenkort weer online zijn." @@ -4665,7 +4776,7 @@ "defaultMessage": "Bezig met uploaden" }, "servers.manage.contact-support-button": { - "defaultMessage": "Neem contact op met de klantenservice van Modrinth" + "defaultMessage": "Contact opnemen met Modrinth-ondersteuning" }, "servers.manage.error.alert-notice": { "defaultMessage": "Onze systemen waarschuwen ons team automatisch wanneer er een probleem is. We zijn al bezig om ze weer online te krijgen." @@ -4680,7 +4791,7 @@ "defaultMessage": "Als je kort geleden een Modrinth Hosting-server hebt gekocht, staat deze momenteel in de wachtrij en zal hij hier verschijnen zodra hij klaar is. Probeer geen nieuwe server aan te schaffen." }, "servers.manage.error.support-notice": { - "defaultMessage": "Als je persoonlijke ondersteuning nodig hebt met betrekking tot de status van uw server, neem dan contact op met Modrinth Support." + "defaultMessage": "Als je persoonlijke ondersteuning nodig hebt met de status van je server, neem dan contact op met Modrinth-ondersteuning." }, "servers.manage.error.title": { "defaultMessage": "De servers konden niet worden geladen" @@ -4758,10 +4869,10 @@ "defaultMessage": "De proefperiode van je Medal-server is afgelopen en je server is opgeschort. Voer een upgrade uit om je server te kunnen blijven gebruiken." }, "servers.medal-listing.notice.suspended": { - "defaultMessage": "Je server is opgeschort. Werk je factuurgegevens bij of neem contact op met de klantenservice van Modrinth voor meer informatie." + "defaultMessage": "Je server is opgeschort. Werk je factuurgegevens bij of neem contact op met Modrinth-ondersteuning voor meer informatie." }, "servers.medal-listing.notice.suspended-with-reason": { - "defaultMessage": "Je server is opgeschort met de reden: {reason}. Werk je factuurgegevens bij of neem contact op met de klantenservice van Modrinth voor meer informatie." + "defaultMessage": "Je server is opgeschort met de reden: {reason}. Werk je factuurgegevens bij of neem contact op met Modrinth-ondersteuning voor meer informatie." }, "servers.medal-listing.notice.upgrading": { "defaultMessage": "De hardware van je server wordt momenteel geüpgraded en zal binnenkort weer online zijn." @@ -5096,9 +5207,120 @@ "settings.pats.title": { "defaultMessage": "Persoonlijke toegangstokens" }, + "settings.profile.bio.description": { + "defaultMessage": "Een korte beschrijving om iedereen iets over jezelf te vertellen." + }, + "settings.profile.bio.title": { + "defaultMessage": "Bio" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profiel" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Profielfoto" + }, + "settings.profile.public-information.description": { + "defaultMessage": "Je profielgegevens zijn openbaar te bekijken op Modrinth en via de Modrinth API." + }, + "settings.profile.save-error": { + "defaultMessage": "Het bijwerken van het profiel is mislukt" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Er is een fout opgetreden bij het bijwerken van je profiel. Probeer het nog eens." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Log in met een Modrinth-account om je openbare profiel aan te passen." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Modrinth-account vereist" + }, + "settings.profile.username.description": { + "defaultMessage": "Een unieke, hoofdletterongevoelige naam waarmee je profiel wordt geïdentificeerd." + }, "settings.sessions.title": { "defaultMessage": "Sessies" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Acties" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Gebruiker" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Dit zijn de gebruikers die je op Modrinth hebt geblokkeerd. Zij kunnen jou niet:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Je hebt niemand geblokkeerd." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "De geblokkeerde gebruikers konden niet worden geladen." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Geblokkeerde gebruikers laden…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Een vriendschapsverzoek sturen" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Uitnodigen om een Modrinth Hosting-server te beheren." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Uitnodigen voor gedeelde instanties" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Geblokkeerde gebruikers" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Deblokkeren" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Kan gebruiker niet deblokkeren" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Er is een fout opgetreden bij het deblokkeren van deze gebruiker. Probeer het nog eens." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "{username} deblokkeren" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Avatar van {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Bepaal zelf wie je vriendschapsverzoeken kan sturen op Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Vriendschapsverzoeken" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Binnenkort beschikbaar!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Iedereen" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Vrienden" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Vrienden van vrienden" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Niemand" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Bepaal zelf wie je uitnodigingen kan sturen voor gedeelde instanties en Modrinth Hosting-panelen." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Uitnodigingen" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Met een Modrinth-account kun je bepalen wie er contact met je kan opnemen en kun je geblokkeerde gebruikers beheren" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Modrinth-account vereist" + }, + "settings.social.title": { + "defaultMessage": "Sociaal" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Toevoegen" }, @@ -5108,14 +5330,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Deze gebruiker is al uitgenodigd." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Toepassen" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Avatar van {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Annuleren" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Aangepast..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Annuleren" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Aangepast: {date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Uitnodigingslink bewerken." @@ -5123,6 +5348,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "Uitnodigingslink bewerken" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "Over 1 dag" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "Over 1 uur" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "Over 7 dagen" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "Over 6 uur" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "Over 3 dagen" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "Over 12 uur" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Vervaldatum" }, diff --git a/packages/ui/src/locales/no-NO/index.json b/packages/ui/src/locales/no-NO/index.json index 0d28108348..b770cb83a2 100644 --- a/packages/ui/src/locales/no-NO/index.json +++ b/packages/ui/src/locales/no-NO/index.json @@ -413,18 +413,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Prosjektnavn" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetisk" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Nyeste først" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Eldste først" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sorter etter {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Oppdater alle" }, @@ -872,18 +860,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Velg ikon" }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Ingen innhold funnet" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Laster inn innhold..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Ingen prosjekter samsvarte med søket ditt." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Søk etter {count, number} {count, plural, one {prosjekt} other {prosjekter}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Nåværende" }, diff --git a/packages/ui/src/locales/pl-PL/index.json b/packages/ui/src/locales/pl-PL/index.json index 6b58310342..ff4f04dfe0 100644 --- a/packages/ui/src/locales/pl-PL/index.json +++ b/packages/ui/src/locales/pl-PL/index.json @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nazwy projektów" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetycznie" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Od najnowszych" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Od najstarszych" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sortuj według: {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Zaktualizuj wszystko" }, @@ -1196,6 +1184,9 @@ "external-files.permissions-card.remove-group": { "defaultMessage": "Usuń grupę" }, + "external-files.permissions-card.remove-group-confirmation.description": { + "defaultMessage": "Trwale usunie to grupę atrybucji i wszystkie zawarte w niej pliki. Tej akcji nie można cofnąć." + }, "external-files.permissions-card.remove-group-confirmation.title": { "defaultMessage": "Usuń {title}?" }, @@ -1269,10 +1260,10 @@ "defaultMessage": "Usuń plik" }, "files.delete-modal.warning.file": { - "defaultMessage": "Ten plik zostanie trwale usunięty. Tej akcji nie będzie można cofnąć." + "defaultMessage": "Ten plik zostanie trwale usunięty. Tej akcji nie można cofnąć." }, "files.delete-modal.warning.folder": { - "defaultMessage": "Ten folder wraz z całą jego zawartością zostanie trwale usunięty. Tej akcji nie będzie można cofnąć." + "defaultMessage": "Ten folder wraz z całą jego zawartością zostanie trwale usunięty. Tej akcji nie można cofnąć." }, "files.editor.failed-to-open-text": { "defaultMessage": "Nie udało się odczytać danych z pliku." @@ -1292,9 +1283,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Plik zapisany" }, - "files.editor.find-close": { - "defaultMessage": "Zamknij" - }, "files.editor.find-in-file": { "defaultMessage": "Znajdź" }, @@ -2069,30 +2057,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Wybierz ikonę" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Ta paczka modów nie zawiera żadnych innych treści." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nie znaleziono treści" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Zewnętrzne" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Ten plik nie jest opublikowany na Modrinth." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Zawartość paczki modów" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Ładowanie treści..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Nie znaleziono żadnego projektu pasującego do Twojego wyszukiwania." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Szukaj wśród {count, number} {count, plural, one {projektu} other {projektów}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Aktualny" }, @@ -2225,6 +2189,9 @@ "label.details": { "defaultMessage": "Szczegóły" }, + "label.discover-content": { + "defaultMessage": "Odkrywaj zawartość" + }, "label.done": { "defaultMessage": "Gotowe" }, @@ -2303,6 +2270,9 @@ "label.password": { "defaultMessage": "Hasło" }, + "label.permissions": { + "defaultMessage": "Uprawnienia" + }, "label.plan-custom": { "defaultMessage": "Niestandardowy" }, @@ -2834,9 +2804,138 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Twórca na Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Użytkownik Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "Użytkownik {username} nie będzie mógł wysyłać ci zaproszeń do znajomych, zapraszać się do udostępnionych instancji lub zapraszać się do serwerów Modrinth Hosting." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Czy na pewno chcesz zablokować tego użytkownika?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Wystąpił błąd podczas blokowania tego użytkownika. Spróbuj ponownie później." + }, + "profile.block-user.error-title": { + "defaultMessage": "Nie udało się zablokować użytkownika" + }, + "profile.block-user.success-description": { + "defaultMessage": "Użytkownik {username} został zablokowany." + }, + "profile.block-user.success-title": { + "defaultMessage": "Zablokowano użytkownika" + }, + "profile.block-user.title": { + "defaultMessage": "Zablokuj {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Pokaż dane analityczne użytkownika" + }, + "profile.button.billing": { + "defaultMessage": "Zarządzaj rozliczaniem użytkownika" + }, + "profile.button.block": { + "defaultMessage": "Zablokuj" + }, + "profile.button.create-collection": { + "defaultMessage": "Utwórz kolekcję" + }, + "profile.button.create-project": { + "defaultMessage": "Utwórz projekt" + }, + "profile.button.info": { + "defaultMessage": "Otwórz szczegóły użytkownika" + }, + "profile.button.manage-projects": { + "defaultMessage": "Zarządzaj projektami" + }, + "profile.button.unblock": { + "defaultMessage": "Odblokuj" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# projekt} few {# projekty} other {# projektów}}" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Dostawcy uwierzytelniania" + }, + "profile.details.label.email-verified": { + "defaultMessage": "Zweryfikowano e-mail" + }, + "profile.details.label.has-password": { + "defaultMessage": "Ma hasło" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Ma TOTP" + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Metody płatności" + }, + "profile.details.title": { + "defaultMessage": "Szczegóły użytkownika" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "E-mail nie jest zweryfikowany" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "E-mail jest zweryfikowany" + }, + "profile.error.load-description": { + "defaultMessage": "Nie udało się załadować profilu tego użytkownika." + }, + "profile.error.not-found": { + "defaultMessage": "Nie znaleziono użytkownika" + }, "profile.label.badges": { "defaultMessage": "Odznaki" }, + "profile.label.collection": { + "defaultMessage": "Kolekcja" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {pobranie} few {pobrania} other {pobrań}}" + }, + "profile.label.joined": { + "defaultMessage": "Dołączył(-a)" + }, + "profile.label.no-collections": { + "defaultMessage": "Ten użytkownik nie ma żadnych kolekcji!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Nie masz jeszcze żadnych kolekcji." + }, + "profile.label.no-projects": { + "defaultMessage": "Ten użytkownik nie ma żadnych projektów!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Nie masz jeszcze żadnych projektów." + }, + "profile.label.organizations": { + "defaultMessage": "Organizacje" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {projekt} few {projekty} other {projektów}}" + }, + "profile.official-account": { + "defaultMessage": "Oficjalne konto Modrinth" + }, + "profile.official-account.bio": { + "defaultMessage": "Oficjalne konto Modrinth. Otrzymaj wsparcie na stronie lub poprzez e-mail " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Wystąpił błąd podczas odblokowywania tego użytkownika. Spróbuj ponownie później." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Nie udało się odblokować użytkownika" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "Użytkownik {username} został odblokowany." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Użytkownik odblokowany" + }, "project-card.date.published.tooltip": { "defaultMessage": "Opublikowany {date}" }, @@ -2864,6 +2963,9 @@ "project-type.all": { "defaultMessage": "Wszystko" }, + "project-type.collection.plural": { + "defaultMessage": "Kolekcje" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Paczka danych} few {Paczki danych} other {Paczek danych}}" }, @@ -3134,6 +3236,9 @@ "project.follower-count-tooltip": { "defaultMessage": "{count, number} {count, plural, one {obserwujący} other {obserwujących}}" }, + "project.license.error": { + "defaultMessage": "Nie można pobrać tekstu licencji." + }, "project.license.loading": { "defaultMessage": "Ładowanie treści licencji..." }, @@ -3653,15 +3758,6 @@ "search.filter_type.advanced": { "defaultMessage": "Zaawansowane" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Wyklucz paczki danych" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Wyklucz mody" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Wyklucz pluginy" - }, "search.filter_type.environment": { "defaultMessage": "Środowisko" }, @@ -5087,9 +5183,111 @@ "settings.pats.title": { "defaultMessage": "Klucze dostępu osobistego" }, + "settings.profile.bio.description": { + "defaultMessage": "Krótki opis, aby powiedzieć wszystkim trochę o Tobie." + }, + "settings.profile.bio.title": { + "defaultMessage": "O mnie" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Zdjęcie profilowe" + }, + "settings.profile.public-information.description": { + "defaultMessage": "Twoje informacje profilowe są publicznie dostępne na Modrinth i poprzez Modrinth API." + }, + "settings.profile.save-error": { + "defaultMessage": "Nie udało się zaktualizować profilu" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Wystąpił błąd podczas aktualizowania profilu. Spróbuj ponownie później." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Zaloguj się na konto Modrinth, by dostosować swój publiczny profil." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Wymagane jest konto Modrinth" + }, + "settings.profile.username.description": { + "defaultMessage": "Unikatowa bez uwzględniania wielkości liter nazwa identyfikująca Twój profil." + }, "settings.sessions.title": { "defaultMessage": "Sesje" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Akcje" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Użytkownik" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Lista użytkowników zablokowanych na Modrinth. Nie mogą oni:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Brak zablokowanych użytkowników." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Nie udała się załadować zablokowanych użytkowników." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Ładowanie zablokowanych użytkowników…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Wysyłać ci zaproszeń do znajomych" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Zapraszać cię do zarządzania serwerem Modrinth Hosting." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Zapraszać cię do udostępnionych instancji" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Zablokowani użytkownicy" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Odblokuj" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Nie udało się odblokować użytkownika" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Wystąpił błąd podczas odblokowywania tego użytkownika. Spróbuj ponownie później." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Odblokuj {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Awatar użytkownika {username}" + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Zaproszenia do znajomych" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Już wkrótce!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Wszyscy" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Znajomi" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Znajomi znajomych" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Nikt" + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Zaproszenia" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Wymagane jest konto Modrinth" + }, + "settings.social.title": { + "defaultMessage": "Społeczne" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Dodaj" }, @@ -5099,15 +5297,12 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Ten użytkownik został już zaproszony." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Zastosuj" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Awatar użytkownika {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Anuluj" - }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Anuluj" - }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Data wygaśnięcia" }, diff --git a/packages/ui/src/locales/pt-BR/index.json b/packages/ui/src/locales/pt-BR/index.json index 27fb435faf..f2b189a6a5 100644 --- a/packages/ui/src/locales/pt-BR/index.json +++ b/packages/ui/src/locales/pt-BR/index.json @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nomes dos projetos" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabético" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Mais recentes primeiro" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Mais antigos primeiro" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Ordenar por {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Atualizar tudo" }, @@ -1301,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Arquivo salvo" }, - "files.editor.find-close": { - "defaultMessage": "Fechar" - }, "files.editor.find-in-file": { "defaultMessage": "Localizar" }, @@ -2081,33 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Selecionar ícone" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Este pacote de mods não inclui nenhum conteúdo adicional." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nenhum conteúdo encontrado" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Externo" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Este arquivo não está publicado no Modrinth." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Conteúdo do pacote de mods" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Carregando conteúdo..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Nenhum projeto corresponde com sua busca." - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "Abrir no Slicer" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Busque {count, number} {count, plural, one {projeto} other {projetos}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Atual" }, @@ -2240,6 +2198,9 @@ "label.details": { "defaultMessage": "Detalhes" }, + "label.discover-content": { + "defaultMessage": "Descobrir conteúdo" + }, "label.done": { "defaultMessage": "Feito" }, @@ -2318,6 +2279,9 @@ "label.password": { "defaultMessage": "Senha" }, + "label.permissions": { + "defaultMessage": "Permissões" + }, "label.plan-custom": { "defaultMessage": "Personalizado" }, @@ -2849,9 +2813,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Um criador Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Um usuário do Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} não poderá enviar solicitações de amizade para você, convidar você para instâncias compartilhadas ou convidar você para servidores do Modrinth Hosting." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Deseja mesmo bloquear este usuário?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Ocorreu um erro ao bloquear este usuário. Tente novamente." + }, + "profile.block-user.error-title": { + "defaultMessage": "Falha ao bloquear usuário" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} bloqueado." + }, + "profile.block-user.success-title": { + "defaultMessage": "Usuário bloqueado" + }, + "profile.block-user.title": { + "defaultMessage": "Bloquear {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Ver estatísticas do usuário" + }, + "profile.button.billing": { + "defaultMessage": "Gerenciar cobrança do usuário" + }, + "profile.button.block": { + "defaultMessage": "Bloquear" + }, + "profile.button.create-collection": { + "defaultMessage": "Criar coleção" + }, + "profile.button.create-project": { + "defaultMessage": "Criar projeto" + }, + "profile.button.info": { + "defaultMessage": "Ver detalhes do usuário" + }, + "profile.button.manage-projects": { + "defaultMessage": "Gerenciar projetos" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Remover como afiliado" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Definir como afiliado" + }, + "profile.button.unblock": { + "defaultMessage": "Desbloquear" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# projeto} other {# projetos}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Permita pop-ups para o Modrinth e tente novamente." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "O perfil do GitHub não pode ser recuperado. Tente novamente." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Não foi possível abrir o perfil do GitHub" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Provedores de autenticação" + }, + "profile.details.label.email-verified": { + "defaultMessage": "E-mail verificado" + }, + "profile.details.label.has-password": { + "defaultMessage": "Possui senha" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Possui TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Carregando..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Métodos de pagamento" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Ver perfil" + }, + "profile.details.title": { + "defaultMessage": "Detalhes do usuário" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "E-mail não verificado" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "E-mail verificado" + }, + "profile.error.load-description": { + "defaultMessage": "O perfil do usuário não pôde ser carregado." + }, + "profile.error.not-found": { + "defaultMessage": "Usuário não encontrado" + }, + "profile.label.affiliate": { + "defaultMessage": "Afiliado" + }, "profile.label.badges": { "defaultMessage": "Emblemas" }, + "profile.label.collection": { + "defaultMessage": "Coleção" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {download} other {downloads}}" + }, + "profile.label.joined": { + "defaultMessage": "Entrou" + }, + "profile.label.no-collections": { + "defaultMessage": "Este usuário não tem coleções!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Você ainda não tem nenhuma coleção." + }, + "profile.label.no-projects": { + "defaultMessage": "Este usuário não tem projetos!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Você ainda não tem projetos." + }, + "profile.label.organizations": { + "defaultMessage": "Organizações" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {projeto} other {projetos}}" + }, + "profile.official-account": { + "defaultMessage": "Conta oficial do Modrinth" + }, + "profile.official-account.bio": { + "defaultMessage": "Conta oficial do Modrinth. Obtenha suporte em ou por e-mail via " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Ocorreu um erro ao desbloquear este usuário. Tente novamente." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Falha ao desbloquear usuário" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} desbloqueado." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Usuário desbloqueado" + }, "project-card.date.published.tooltip": { "defaultMessage": "Publicado {date}" }, @@ -2879,6 +2996,9 @@ "project-type.all": { "defaultMessage": "Todos" }, + "project-type.collection.plural": { + "defaultMessage": "Coleções" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Pacote de dados} other {Pacotes de dados}}" }, @@ -3159,7 +3279,10 @@ "defaultMessage": "Licença" }, "project.online-player-count": { - "defaultMessage": "{count, plural, =0 {Ninguém online} other {{count} online}}" + "defaultMessage": "{count, number} online" + }, + "project.online-player-count.tooltip": { + "defaultMessage": "{count} {countPlural, plural, one {jogador} other {jogadores}} online" }, "project.recent-plays": { "defaultMessage": "{countPlural, plural, =0 {Nenhuma entrada recente} one {{count} entrada recente} other {{count} entradas recentes}}" @@ -3668,15 +3791,6 @@ "search.filter_type.advanced": { "defaultMessage": "Avançado" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Excluir pacotes de dados" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Excluir mods" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Excluir plugins" - }, "search.filter_type.environment": { "defaultMessage": "Ambiente" }, @@ -5102,9 +5216,120 @@ "settings.pats.title": { "defaultMessage": "Token de acesso pessoal" }, + "settings.profile.bio.description": { + "defaultMessage": "Uma breve descrição para falar um pouco sobre você para todos." + }, + "settings.profile.bio.title": { + "defaultMessage": "Sobre" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Perfil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Foto de perfil" + }, + "settings.profile.public-information.description": { + "defaultMessage": "As informações do seu perfil são visíveis publicamente no Modrinth e através da API do Modrinth." + }, + "settings.profile.save-error": { + "defaultMessage": "Falha ao atualizar o perfil" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Ocorreu um erro ao atualizar seu perfil. Tente novamente." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Inicie sessão com uma conta Modrinth para personalizar seu perfil público." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Conta Modrinth necessária" + }, + "settings.profile.username.description": { + "defaultMessage": "Um nome único sem distinção de maiúsculas e minúsculas para identificar o seu perfil." + }, "settings.sessions.title": { "defaultMessage": "Sessões" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Ações" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Usuário" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Estes são os usuários que você bloqueou no Modrinth. Eles não poderão:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Você não bloqueou ninguém." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Os usuários bloqueados não puderam ser carregados." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Carregando usuários bloqueados…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Enviar solicitações de amizade" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Convidar você para gerenciar um servidor Modrinth Hosting." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Convidar você para instâncias compartilhadas" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Usuários bloqueados" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Desbloquear" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Falha ao desbloquear usuário" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Ocorreu um erro ao desbloquear este usuário. Tente novamente." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Desbloquear {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Foto de perfil de {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Controle quem pode enviá-lo solicitações de amizade no Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Solicitações de amizade" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Em breve!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Todos" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Amigos" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Amigos de amigos" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Ninguém" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Controle quem pode enviá-lo convites a instâncias compartilhadas e painéis do Modrinth Hosting." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Convites" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "Você pode controlar quem interagir com você e gerenciar usuários bloqueados com uma conta Modrinth" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Conta Modrinth necessária" + }, + "settings.social.title": { + "defaultMessage": "Social" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Adicionar" }, @@ -5114,14 +5339,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Este usuário já foi convidado." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Aplicar" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Avatar de {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Cancelar" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Personalizado..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Cancelar" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Personalizado: {date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Editar link de convite." @@ -5129,6 +5357,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "Editar link de convite" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "Em 1 dia" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "Em 1 hora" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "Em 7 dias" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "Em 6 horas" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "Em 3 dias" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "Em 12 horas" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Data de expiração" }, diff --git a/packages/ui/src/locales/pt-PT/index.json b/packages/ui/src/locales/pt-PT/index.json index f27ed83e44..99fa4888bf 100644 --- a/packages/ui/src/locales/pt-PT/index.json +++ b/packages/ui/src/locales/pt-PT/index.json @@ -398,18 +398,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nomes dos projetos" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabético" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Mais recentes primeiro" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Mais antigos primeiro" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Ordenar por {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Atualizar tudo" }, @@ -497,9 +485,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Ficheiro salvo" }, - "files.editor.find-close": { - "defaultMessage": "Fechar" - }, "files.editor.find-in-file": { "defaultMessage": "Encontrar" }, @@ -752,21 +737,6 @@ "instance.worlds.game_mode.unknown": { "defaultMessage": "Modo de jogo desconhecido" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Este modpack não inclui nenhum conteúdo adicional." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nenhum conteúdo encontrado" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Conteúdo do modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "A carregar conteúdo..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Nenhum projeto corresponde à tua pesquisa." - }, "instances.updater-modal.badge.current": { "defaultMessage": "Atual" }, diff --git a/packages/ui/src/locales/ro-RO/index.json b/packages/ui/src/locales/ro-RO/index.json index 689a414b43..e608d4140f 100644 --- a/packages/ui/src/locales/ro-RO/index.json +++ b/packages/ui/src/locales/ro-RO/index.json @@ -425,18 +425,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Nume ale proiectului" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetic" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Cele noi mai întâi" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Cele vechi mai întâi" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sortează cu {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Actualizează tot" }, @@ -551,9 +539,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Fișier salvat" }, - "files.editor.find-close": { - "defaultMessage": "Închide" - }, "files.editor.find-in-file": { "defaultMessage": "Caută" }, @@ -1025,24 +1010,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Selectează iconița" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Acest modpack nu include niciun conținut suplimentar." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nu a fost găsit niciun conținut" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Conținutul Modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Se încarcă materialul..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Niciun proiect nu corespunde căutării dvs." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Căutare {count, number}{count, plural,one {proiect}other {proiecte}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Curent" }, diff --git a/packages/ui/src/locales/ru-RU/index.json b/packages/ui/src/locales/ru-RU/index.json index 072d67b335..04829d0c5a 100644 --- a/packages/ui/src/locales/ru-RU/index.json +++ b/packages/ui/src/locales/ru-RU/index.json @@ -348,10 +348,10 @@ "defaultMessage": "Выбрать {project}" }, "content.confirm-bulk-update.admonition-body": { - "defaultMessage": "Вы уверены, что хотите обновить {count, plural, one {# проект} few {# проекта} other {# проектов}} до их последней совместимой версии? Рекомендуется обновлять контент по отдельности." + "defaultMessage": "Вы точно хотите обновить {count, plural, one {# проект} few {# проекта} other {# проектов}} до {count, plural, =1 {последней совместимой версии} other {последних совместимых версий}}? Рекомендуется обновлять контент по очереди." }, "content.confirm-bulk-update.admonition-header": { - "defaultMessage": "Предупреждение об обновлении" + "defaultMessage": "Предупреждение об обновлении" }, "content.confirm-bulk-update.header": { "defaultMessage": "Обновление проектов" @@ -363,10 +363,10 @@ "defaultMessage": "Обновить {count, plural, one {# проект} few {# проекта} other {# проектов}}" }, "content.confirm-deletion.admonition-body": { - "defaultMessage": "Удаление мода может необратимо повлиять на ваш мир, что приведет к потере контента или непредвиденным ошибкам при следующей загрузке." + "defaultMessage": "Удаление модов может повлиять на миры и привести к необратимой пропаже контента или ошибкам при следующей загрузке." }, "content.confirm-deletion.admonition-header": { - "defaultMessage": "Предупреждение об удалении" + "defaultMessage": "Предупреждение об удалении" }, "content.confirm-deletion.header": { "defaultMessage": "Удалить {itemType}" @@ -375,10 +375,10 @@ "defaultMessage": "Отключить {itemType}" }, "content.confirm-modpack-update.admonition-body": { - "defaultMessage": "{action, select, downgrade {Понижение версии} other {Обновление}} может привести к проблемам с совместимостью. Моды или другой контент, который вы установили в сборку, сохранятся, но могут быть несовместимы с новой версией." + "defaultMessage": "{action, select, downgrade {Откат} other {Обновление}} может нарушить совместимость. Добавленные вами моды и контент останутся, но могут перестать работать в новой версии." }, "content.confirm-modpack-update.admonition-header": { - "defaultMessage": "Предупреждение: {action, select, downgrade {откат} other {обновление}} версии" + "defaultMessage": "Предупреждение об {action, select, downgrade {откате} other {обновлении}}" }, "content.confirm-modpack-update.confirm-button": { "defaultMessage": "{action, select, downgrade {Откатить} other {Обновить}} сборку" @@ -387,7 +387,7 @@ "defaultMessage": "{action, select, downgrade {Откат} other {Обновление}} сборки" }, "content.confirm-unlink.admonition-body": { - "defaultMessage": "Моды и контент будут объединены с тем, что вы добавили в сборку. После этого сборка перестанет получать обновления." + "defaultMessage": "Моды и контент объединятся с вашими добавлениями, но сборка перестанет получать обновления." }, "content.confirm-unlink.admonition-header": { "defaultMessage": "Отвязка сборки" @@ -471,13 +471,13 @@ "defaultMessage": "Загрузчик" }, "content.diff-modal.modpack-linked": { - "defaultMessage": "Связанная сборка" + "defaultMessage": "Привязана сборка" }, "content.diff-modal.modpack-unlinked": { - "defaultMessage": "Несвязанная сборка" + "defaultMessage": "Отвязана сборка" }, "content.diff-modal.modpack-updated": { - "defaultMessage": "Обновлённая сборка" + "defaultMessage": "Обновлена сборка" }, "content.diff-modal.no-content-changes": { "defaultMessage": "Без изменений" @@ -584,18 +584,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Названия проектов" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "По алфавиту" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Сначала новые" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Сначала старые" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Сортировка: {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Обновить всё" }, @@ -846,7 +834,7 @@ "defaultMessage": "Начать с нуля, выбрав загрузчик и версию игры." }, "creation-flow.modal.setup-type.option.custom-setup.title": { - "defaultMessage": "Пользовательская настройка" + "defaultMessage": "Собственная настройка" }, "creation-flow.modal.setup-type.option.import-instance.description": { "defaultMessage": "Импортировать сборку из Prism, CurseForge, или похожего лаунчера." @@ -1229,9 +1217,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Файл сохранён" }, - "files.editor.find-close": { - "defaultMessage": "Закрыть" - }, "files.editor.find-in-file": { "defaultMessage": "Найти" }, @@ -1809,52 +1794,52 @@ "defaultMessage": "Настройка установки" }, "installation-settings.edit.warning-instance": { - "defaultMessage": "Мы не рекомендуем изменять настройки сборки после установки контента. Если вы всё же хотите их изменить, будьте осторожны, так как это может вызвать проблемы." + "defaultMessage": "Не рекомендуется изменять установку после добавления контента. Это может привести к ошибкам." }, "installation-settings.edit.warning-server": { - "defaultMessage": "Не рекомендуется менять настройки инсталляции после установки контента. Если вы всё же хотите изменить их, перезагрузите сервер." + "defaultMessage": "Не рекомендуется изменять установку после добавления контента. Лучше сразу переустановить сервер." }, "installation-settings.incompatible-content.auto-fix-button": { - "defaultMessage": "Авто-исправление" + "defaultMessage": "Исправить" }, "installation-settings.incompatible-content.change-loader-button": { "defaultMessage": "Сменить загрузчик" }, "installation-settings.incompatible-content.disable-conflicts-button": { - "defaultMessage": "Отключить конфликты" + "defaultMessage": "Отключить" }, "installation-settings.incompatible-content.game-version-warning-body": { - "defaultMessage": "При изменении версии игры вы можете либо отключить несовместимый контент, либо попытаться устранить несовместимости." + "defaultMessage": "При смене версии игры можно отключить несовместимый контент или попытаться исправить несовместимости автоматически." }, "installation-settings.incompatible-content.game-version-warning-title": { - "defaultMessage": "Предупреждение о несовместимости" + "defaultMessage": "Предупреждение о несовместимости" }, "installation-settings.incompatible-content.header": { - "defaultMessage": "Установлены несовместимые проекты" + "defaultMessage": "Нарушение совместимости" }, "installation-settings.incompatible-content.loader-change-body": { - "defaultMessage": "При смене загрузчика модов, все установленные проекты будут отключены. Вместо этого рекомендуется сбросить сервер." + "defaultMessage": "Смена загрузчика отключит установленный контент. Лучше сразу переустановить сервер." }, "installation-settings.incompatible-content.loader-change-title": { "defaultMessage": "Смена загрузчика небезопасна" }, "installation-settings.linked-instance.title": { - "defaultMessage": "Связанный {projectType}" + "defaultMessage": "Отвязка {projectType}" }, "installation-settings.linked.modpack": { - "defaultMessage": "сборка" + "defaultMessage": "сборки" }, "installation-settings.linked.server-project": { - "defaultMessage": "серверный проект" + "defaultMessage": "серверного проекта" }, "installation-settings.loader-version": { "defaultMessage": "Версия {loader}" }, "installation-settings.platform-lock-tooltip": { - "defaultMessage": "Необходимо сбросить сервер для изменения загрузчика." + "defaultMessage": "Для смены загрузчика необходимо переустановить сервер." }, "installation-settings.reinstall-modpack.description": { - "defaultMessage": "Переустановка сборки сбросит контент, который использует {type}, до исходного состояния, удалив все добавленные вами моды и файлы." + "defaultMessage": "Переустановка сбросит {type} к исходному состоянию, удалив все добавленные вами моды и контент." }, "installation-settings.reinstall-modpack.title": { "defaultMessage": "Переустановка сборки" @@ -1884,31 +1869,31 @@ "defaultMessage": "Поиск версии игры..." }, "installation-settings.type.instance": { - "defaultMessage": "сборка" + "defaultMessage": "сборку" }, "installation-settings.type.instance-possessive": { - "defaultMessage": "сборки" + "defaultMessage": "сборку" }, "installation-settings.type.server": { "defaultMessage": "сервер" }, "installation-settings.type.server-possessive": { - "defaultMessage": "серверы" + "defaultMessage": "сервер" }, "installation-settings.unlink": { "defaultMessage": "Отвязать" }, "installation-settings.unlink.description": { - "defaultMessage": "Отвязка навсегда отключит этот {type} от проекта {projectType}, что позволит вам изменить загрузчик и версию Minecraft, но вы больше не сможете получать обновления." + "defaultMessage": "Отвязка навсегда отключит {type} от исходного проекта. Это откроет доступ к смене версии игры и загрузчика, но получение обновлений прекратится." }, "installation-settings.verifying": { "defaultMessage": "Проверка..." }, "instance.confirm-reinstall.admonition-body": { - "defaultMessage": "Переустановка сбросит весь установленный или изменённый контент к начальному состоянию, удалив моды и контент, добавленные поверх исходной установки." + "defaultMessage": "Переустановка сбросит установленное содержимое к исходному состоянию, удалив добавленные вами моды и контент." }, "instance.confirm-reinstall.admonition-header": { - "defaultMessage": "Предупреждение переустановки" + "defaultMessage": "Предупреждение о переустановке" }, "instance.confirm-reinstall.header": { "defaultMessage": "Переустановка сборки" @@ -1997,33 +1982,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Выбрать иконку" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "В сборке нет дополнительного контента." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Сборка пуста" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "Сторонний" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "Файл не опубликован на Modrinth." - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Содержимое сборки" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Загрузка содержимого..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Не найдены проекты, соответствующие запросу." - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "Открыть в Slicer" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Поиск по {count, number} {count, plural, one {проекту} other {проектам}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Текущая" }, @@ -2156,6 +2114,9 @@ "label.details": { "defaultMessage": "Сведения" }, + "label.discover-content": { + "defaultMessage": "Найти проекты" + }, "label.done": { "defaultMessage": "Готово" }, @@ -2234,6 +2195,9 @@ "label.password": { "defaultMessage": "Пароль" }, + "label.permissions": { + "defaultMessage": "Разрешения" + }, "label.plan-custom": { "defaultMessage": "Свой" }, @@ -2762,9 +2726,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Автор на Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Пользователь Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} не сможет отправлять вам запросы в друзья, приглашать вас в сборки или приглашать вас управлять сервером Modrinth Hosting." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Вы действительно хотите заблокировать этого пользователя?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Произошла ошибка при блокировке пользователя. Попробуйте снова." + }, + "profile.block-user.error-title": { + "defaultMessage": "Не удалось заблокировать" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} заблокирован." + }, + "profile.block-user.success-title": { + "defaultMessage": "Пользователь заблокирован" + }, + "profile.block-user.title": { + "defaultMessage": "Заблокировать {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Посмотреть аналитику" + }, + "profile.button.billing": { + "defaultMessage": "Управление платежами" + }, + "profile.button.block": { + "defaultMessage": "Заблокировать" + }, + "profile.button.create-collection": { + "defaultMessage": "Создать коллекцию" + }, + "profile.button.create-project": { + "defaultMessage": "Создать проект" + }, + "profile.button.info": { + "defaultMessage": "Посмотреть подробности" + }, + "profile.button.manage-projects": { + "defaultMessage": "Управление проектами" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Убрать из партнёров" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Сделать партнёром" + }, + "profile.button.unblock": { + "defaultMessage": "Разблокировать" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# проект} few {# проекта} other {# проектов}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Разрешите всплывающие окна для Modrinth и повторите попытку." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Не удалось получить профиль GitHub. Повторите попытку." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Не удалось открыть профиль GitHub" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Сервисы входа" + }, + "profile.details.label.email-verified": { + "defaultMessage": "Почта подтверждена" + }, + "profile.details.label.has-password": { + "defaultMessage": "Есть пароль" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Есть TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Загрузка..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Способы оплаты" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Посмотреть профиль" + }, + "profile.details.title": { + "defaultMessage": "О пользователе" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "Почта не подтверждена" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "Почта подтверждена" + }, + "profile.error.load-description": { + "defaultMessage": "Не удалось загрузить профиль." + }, + "profile.error.not-found": { + "defaultMessage": "Пользователь не найден" + }, + "profile.label.affiliate": { + "defaultMessage": "Партнёр" + }, "profile.label.badges": { "defaultMessage": "Значки" }, + "profile.label.collection": { + "defaultMessage": "Коллекция" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {скачивание} few {скачивания} other {скачиваний}}" + }, + "profile.label.joined": { + "defaultMessage": "Регистрация:" + }, + "profile.label.no-collections": { + "defaultMessage": "У этого пользователя нет коллекций!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Коллекций пока нет." + }, + "profile.label.no-projects": { + "defaultMessage": "У этого пользователя нет проектов!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Проектов пока нет." + }, + "profile.label.organizations": { + "defaultMessage": "Организации" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {проект} few {проекта} other {проектов}}" + }, + "profile.official-account": { + "defaultMessage": "Официальный аккаунт Modrinth" + }, + "profile.official-account.bio": { + "defaultMessage": "Официальный аккаунт Modrinth. Связь с поддержкой: или по почте " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Произошла ошибка при разблокировке пользователя. Попробуйте снова." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Не удалось разблокировать" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} разблокирован." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Пользователь разблокирован" + }, "project-card.date.published.tooltip": { "defaultMessage": "Опубликован {date}" }, @@ -2792,6 +2909,9 @@ "project-type.all": { "defaultMessage": "Всё" }, + "project-type.collection.plural": { + "defaultMessage": "Коллекции" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {набор данных} few {набора данных} other {наборов данных}}" }, @@ -3584,15 +3704,6 @@ "search.filter_type.advanced": { "defaultMessage": "Расширенные" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Исключать наборы данных" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Исключать моды" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Исключать плагины" - }, "search.filter_type.environment": { "defaultMessage": "Среда" }, @@ -4290,7 +4401,7 @@ "defaultMessage": "После удаления {count, plural, one {эта резервная копия не может быть восстановлена} other {эти резервные копии не могут быть восстановлены}}. Удаление необратимо." }, "servers.backups.delete-modal.admonition-header": { - "defaultMessage": "Предупреждение об удалении" + "defaultMessage": "Предупреждение об удалении" }, "servers.backups.delete-modal.backups-label": { "defaultMessage": "{count, plural, one {Резервная копия} other {Резервные копии ({count})}}" @@ -4746,7 +4857,7 @@ "defaultMessage": "Способ оплаты" }, "servers.purchase.step.plan.billed": { - "defaultMessage": "оплата {interval, select, monthly {ежемесячно} quarterly {ежеквартально} yearly {ежегодно} other {{interval}}}" + "defaultMessage": "{interval, select, monthly {за месяц} quarterly {за 3 месяца} yearly {за год} other {billed {interval}}}" }, "servers.purchase.step.plan.billing-subtitle": { "defaultMessage": "Доступно в Северной Америке, Европе и Юго‑Восточной Азии." @@ -5018,9 +5129,120 @@ "settings.pats.title": { "defaultMessage": "Личные токены доступа" }, + "settings.profile.bio.description": { + "defaultMessage": "Возможность кратко рассказать всем о себе." + }, + "settings.profile.bio.title": { + "defaultMessage": "О себе" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Профиль" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Изображение профиля" + }, + "settings.profile.public-information.description": { + "defaultMessage": "Информация в вашем профиле доступна публично на Modrinth и через API Modrinth." + }, + "settings.profile.save-error": { + "defaultMessage": "Не удалось обновить профиль" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Произошла ошибка при обновлении профиля. Попробуйте снова." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Войдите в аккаунт Modrinth для кастомизации вашего публичного профиля." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Требуется аккаунт Modrinth" + }, + "settings.profile.username.description": { + "defaultMessage": "Уникальное имя для идентификации профиля." + }, "settings.sessions.title": { "defaultMessage": "Сеансы" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Действия" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Пользователь" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Это пользователи, которых вы заблокировали на Modrinth. Они не могут:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Вы никого не заблокировали." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Заблокированные пользователи не загрузились." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Загрузка заблокированных пользователей..." + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Отправлять вам запросы в друзья" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Приглашать вас управлять сервером Modrinth Hosting." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Приглашать вас в сборки" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Заблокированные пользователи" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Разблокировать" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Не удалось разблокировать" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Произошла ошибка при разблокировке пользователя. Попробуйте снова." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Разблокировать {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Аватар {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Настройте, кто может отправить вам заявку в друзья на Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Запросы в друзья" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Скоро будет!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Все" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Друзья" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Друзья друзей" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Никто" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Настройте, кто вам может отправить заявку на общие сборки и панели Modrinth Hosting." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Приглашения" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "С помощью аккаунта Modrinth, вы можете настраивать кто может взаимодействовать с вами, а также управлять заблокированными пользователями" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Требуется аккаунт Modrinth" + }, + "settings.social.title": { + "defaultMessage": "Общение" + }, "sharing.invite-players-modal.add": { "defaultMessage": "Добавить" }, @@ -5030,14 +5252,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "Этот пользователь уже приглашён." }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Применить" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "Аватар {username}" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "Отозвать" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Другое..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "Отмена" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Другое: {date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "Настроить ссылку." @@ -5045,6 +5270,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "Настройка ссылки" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "1 день" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "1 час" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "7 дней" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "6 часов" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "3 дня" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "12 часов" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "Срок действия" }, diff --git a/packages/ui/src/locales/sr-CS/index.json b/packages/ui/src/locales/sr-CS/index.json index 6117939c7d..91ea30e3f4 100644 --- a/packages/ui/src/locales/sr-CS/index.json +++ b/packages/ui/src/locales/sr-CS/index.json @@ -584,18 +584,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Imena projekata" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetski" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Najnovije prvo" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Najstarije prvo" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sortiraj so {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Ažuiraj sve" }, @@ -1253,9 +1241,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Datoteka sačuvana" }, - "files.editor.find-close": { - "defaultMessage": "Zatvori" - }, "files.editor.find-in-file": { "defaultMessage": "Pronađi" }, @@ -2033,24 +2018,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Izaberi ikonu" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Ovaj modpack ne uključuje nikakav dodatni sadržaj." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Nema pronađenog sadržaja" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Sadržaj modpacka" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Učitavanje sadržaja..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Nijedan projekat ne odgovara tvojoj pretrazi." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Pretraga {count, number} {count, plural, one {projekta} few {projekta} other {projekata}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Upravo" }, @@ -3593,15 +3560,6 @@ "search.filter_type.advanced": { "defaultMessage": "Napredno" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Isključi data pakete" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Isključi modove" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Isključi plugine" - }, "search.filter_type.environment": { "defaultMessage": "Okruže" }, diff --git a/packages/ui/src/locales/sv-SE/index.json b/packages/ui/src/locales/sv-SE/index.json index fa83bc14dd..e42b371e02 100644 --- a/packages/ui/src/locales/sv-SE/index.json +++ b/packages/ui/src/locales/sv-SE/index.json @@ -117,7 +117,7 @@ "defaultMessage": "Du har valt {count, number} projekt att installera. Installera dem nu eller gå tillbaka utan att installera dem." }, "browse.selected-projects-leave-modal.admonition-header": { - "defaultMessage": "Valda projekt är inte installerade än" + "defaultMessage": "De valda projekten är inte installerade än" }, "browse.selected-projects-leave-modal.discard": { "defaultMessage": "Kasta" @@ -377,6 +377,9 @@ "content.confirm-deletion.header": { "defaultMessage": "Radera {itemType}" }, + "content.confirm-disable.header": { + "defaultMessage": "Inaktivera {itemType}" + }, "content.confirm-modpack-update.admonition-body": { "defaultMessage": "Att {action, select, downgrade {nedgradera} other {uppdatera}} kan orsaka kompatibilitetsproblem. Moddar eller innehåller du själv lagt till kommer behållas, men är kanske inte kompatibel med den nya versionen." }, @@ -455,6 +458,9 @@ "content.diff-modal.diff-type.removed": { "defaultMessage": "Inaktiverade" }, + "content.diff-modal.diff-type.removed-disabled": { + "defaultMessage": "Tog bort (inaktiverad)" + }, "content.diff-modal.diff-type.updated": { "defaultMessage": "Uppdaterade" }, @@ -470,18 +476,33 @@ "content.diff-modal.external-diff-type.updated": { "defaultMessage": "Uppdaterad" }, + "content.diff-modal.file-count": { + "defaultMessage": "{count, plural, one {# fil} other {# filer}}" + }, "content.diff-modal.game-version-updated": { "defaultMessage": "Spelversion" }, "content.diff-modal.install-anyway": { "defaultMessage": "Installera ändå" }, + "content.diff-modal.modpack-linked": { + "defaultMessage": "Länkat modpaket" + }, + "content.diff-modal.modpack-unlinked": { + "defaultMessage": "Avlänkat modpaket" + }, + "content.diff-modal.modpack-updated": { + "defaultMessage": "Uppdaterat modpaket" + }, "content.diff-modal.no-content-changes": { "defaultMessage": "Inga innehållsändringar" }, "content.diff-modal.removed-count": { "defaultMessage": "{count} borttagna" }, + "content.diff-modal.reviewed-files": { + "defaultMessage": "En fil granskas bara om den publiceras på Modrinth, oavsett dess filformat (däribland .mrpack)." + }, "content.diff-modal.unknown-content-body": { "defaultMessage": "Något innehåll på din server kunde inte analyseras och kommer kanske påverkas av denna ändring." }, @@ -590,18 +611,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Projektnamn" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetisk" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Nyaste först" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Äldsta först" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sortera i {mode} ordning" - }, "content.page-layout.update-all": { "defaultMessage": "Uppdatera alla" }, @@ -774,7 +783,7 @@ "defaultMessage": "Ange världnamn" }, "creation-flow.modal.final-config.world-seed.description": { - "defaultMessage": "Lämna tom för slumpmässig utsäde." + "defaultMessage": "Lämna tom för slumpmässig frö." }, "creation-flow.modal.final-config.world-seed.placeholder": { "defaultMessage": "Ange världsfrö" @@ -842,12 +851,21 @@ "creation-flow.modal.setup-type.option.import-instance.title": { "defaultMessage": "Importera instans" }, + "creation-flow.modal.setup-type.option.modpack-base.description": { + "defaultMessage": "Bläddra bland modpaket på Modrinth eller importera ett från en fil." + }, "creation-flow.modal.setup-type.option.modpack-base.title": { "defaultMessage": "Installera modpaket" }, "creation-flow.modal.setup-type.option.vanilla-minecraft.description": { "defaultMessage": "Klassiska Minecraft, utan moddar eller plugin." }, + "creation-flow.modal.setup-type.option.vanilla-minecraft.title": { + "defaultMessage": "Vanilla Minecraft" + }, + "creation-flow.modal.setup-type.title.installation": { + "defaultMessage": "Välj installationstyp" + }, "creation-flow.modal.setup-type.title.instance": { "defaultMessage": "Välj instanstyp" }, @@ -869,9 +887,15 @@ "creation-flow.title.reset-server": { "defaultMessage": "Starta om server" }, + "creation-flow.title.set-up-server": { + "defaultMessage": "Ställ in server" + }, "external-files.permissions-card.add-files-modal.confirm": { "defaultMessage": "Lägg till {count, plural, one {# fil} other {# filer}}" }, + "external-files.permissions-card.add-files-modal.load-error.title": { + "defaultMessage": "Kunde inte ladda filer" + }, "external-files.permissions-card.add-files-modal.no-search-results": { "defaultMessage": "Inga filer matchade din sökning." }, @@ -896,9 +920,15 @@ "external-files.permissions-card.attribution.moderation-status.passed": { "defaultMessage": "Godkänd" }, + "external-files.permissions-card.badge.no-permission": { + "defaultMessage": "Ingen tillåtelse" + }, "external-files.permissions-card.badge.not-allowed": { "defaultMessage": "Inte tillåten" }, + "external-files.permissions-card.badge.pending": { + "defaultMessage": "Väntar" + }, "external-files.permissions-card.custom-license-option": { "defaultMessage": "Annan" }, @@ -962,6 +992,12 @@ "external-files.permissions-card.file-count": { "defaultMessage": "{count, plural, one {# fil} other {# filer}}" }, + "external-files.permissions-card.included-files": { + "defaultMessage": "Inkluderade filer:" + }, + "external-files.permissions-card.included-in-versions": { + "defaultMessage": "Inkuderad i {count, plural, one {# verion} other {# versioner}}:" + }, "external-files.permissions-card.last-updated": { "defaultMessage": "Senast uppdaterad den {date} av {user}" }, @@ -1010,6 +1046,18 @@ "external-files.permissions-card.reason.special-permission.description": { "defaultMessage": "Du har erhållit speciell tillåtelse för att distribuera detta verk i ditt modpaket." }, + "external-files.permissions-card.remove-group": { + "defaultMessage": "Radera grupp" + }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "Radera {title}?" + }, + "external-files.permissions-card.remove-group-error.title": { + "defaultMessage": "Kunde inte radera grupp" + }, + "external-files.permissions-card.remove-group-shift-hint": { + "defaultMessage": "Håll skift medan du klickar för att hoppa över bekräftelsen." + }, "external-files.permissions-card.split-file": { "defaultMessage": "Ta bort från grupp" }, @@ -1094,9 +1142,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Filen sparades" }, - "files.editor.find-close": { - "defaultMessage": "Stäng" - }, "files.editor.find-in-file": { "defaultMessage": "Hitta" }, @@ -1145,12 +1190,18 @@ "files.image_viewer.image_too_large": { "defaultMessage": "Bilden är för stor för att se (högst {maxDimension}x{maxDimension} pixlar)" }, + "files.image_viewer.invalid_image": { + "defaultMessage": "Ogiltig eller tom bildfil." + }, "files.image_viewer.load_failed": { "defaultMessage": "Kunde inte ladda bilden" }, "files.image_viewer.reset_zoom": { "defaultMessage": "Återställ zoom" }, + "files.image_viewer.viewed_image_alt": { + "defaultMessage": "Visad bild" + }, "files.image_viewer.zoom_in": { "defaultMessage": "Zooma in" }, @@ -1190,6 +1241,9 @@ "files.move-modal.header": { "defaultMessage": "Flytta {type}" }, + "files.navbar.back-to-home": { + "defaultMessage": "Tillbaka hem" + }, "files.navbar.breadcrumb-navigation": { "defaultMessage": "Länkstigsnavigering" }, @@ -1220,9 +1274,24 @@ "files.navbar.upload-from-zip": { "defaultMessage": "Ladda upp .zip-fil" }, + "files.navbar.upload-from-zip-url": { + "defaultMessage": "Uppladdad från .zip-URL" + }, "files.operations.current-file": { "defaultMessage": "Nuvarande fil: {file}" }, + "files.operations.extracted": { + "defaultMessage": "{size} packas upp" + }, + "files.operations.extracting": { + "defaultMessage": "Packar upp {source}" + }, + "files.operations.extracting-completed": { + "defaultMessage": "Uppackning {source} slutförd" + }, + "files.operations.extracting-failed": { + "defaultMessage": "Uppackning {source} misslyckad" + }, "files.operations.modpack-from-url": { "defaultMessage": "modpaket från en webbadress" }, @@ -1437,7 +1506,7 @@ "defaultMessage": "Prestandapåverkan" }, "header.category.resolutions": { - "defaultMessage": "Kvalitet" + "defaultMessage": "Upplösning" }, "hosting.content.failed-to-bulk-delete": { "defaultMessage": "Kunde inte radera innehållet" @@ -1496,6 +1565,9 @@ "hosting.loader.loader-version": { "defaultMessage": "{loader, select, null {Loader} other {{loader}}} version" }, + "hosting.loader.reset-server": { + "defaultMessage": "Återställ server" + }, "hosting.specs.burst": { "defaultMessage": "Ökar upp till {cpus} CPU:er" }, @@ -1571,9 +1643,15 @@ "installation-settings.incompatible-content.auto-fix-button": { "defaultMessage": "Auto-fix" }, + "installation-settings.linked-instance.title": { + "defaultMessage": "Länkat {projectType}" + }, "installation-settings.linked.modpack": { "defaultMessage": "modpaket" }, + "installation-settings.linked.server-project": { + "defaultMessage": "serverprojekt" + }, "installation-settings.loader-version": { "defaultMessage": "{loader} version" }, @@ -1581,7 +1659,7 @@ "defaultMessage": "Du kommer att behöva ställa om din server för att ändra loader." }, "installation-settings.reinstall-modpack.description": { - "defaultMessage": "Ominstallering av modpaketet återställer {type} innehåll till dess ursprungliga skick, vilket tar bort moddar eller innehåll du lagt till." + "defaultMessage": "Ominstallering av modpaketet återställer {type}innehållet till dess ursprungliga skick, vilket tar bort moddar eller innehåll du lagt till." }, "installation-settings.reinstall-modpack.title": { "defaultMessage": "Ominstallera modpaket" @@ -1709,24 +1787,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Välj ikon" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Modpaketet innehåller inget ytterligare innehåll." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Inget innehåll hittades" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Modpaketets innehåll" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Laddar innehåll..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Inga projekt matchar din sökning." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Sök genom {count, number} projekt" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Nuvarande" }, @@ -1823,6 +1883,9 @@ "label.copied-path": { "defaultMessage": "Kopiera sökväg" }, + "label.create-failed": { + "defaultMessage": "Skapning misslyckades" + }, "label.created-ago": { "defaultMessage": "Skapad {ago}" }, @@ -1844,6 +1907,9 @@ "label.details": { "defaultMessage": "Detaljer" }, + "label.discover-content": { + "defaultMessage": "Upptäck innehåll" + }, "label.done": { "defaultMessage": "Klart" }, @@ -1859,6 +1925,9 @@ "label.error": { "defaultMessage": "Fel" }, + "label.extract-failed": { + "defaultMessage": "Uppackning misslyckades" + }, "label.filter-by": { "defaultMessage": "Filtrera efter" }, @@ -1874,6 +1943,9 @@ "label.hide-installed-content": { "defaultMessage": "Göm redan installerat innehåll" }, + "label.hide-selected-content": { + "defaultMessage": "Göm valt innehåll" + }, "label.installation-info": { "defaultMessage": "Installationsinfo" }, @@ -1898,6 +1970,9 @@ "label.modpack": { "defaultMessage": "Modpaket" }, + "label.move-failed": { + "defaultMessage": "Flytt misslyckades" + }, "label.no": { "defaultMessage": "Nej" }, @@ -1913,6 +1988,9 @@ "label.password": { "defaultMessage": "Lösenord" }, + "label.permissions": { + "defaultMessage": "Behörigheter" + }, "label.plan-custom": { "defaultMessage": "Anpassad" }, @@ -1943,6 +2021,9 @@ "label.rejected": { "defaultMessage": "Nekad" }, + "label.rename-failed": { + "defaultMessage": "Namnbyte misslyckades" + }, "label.rewards-program-terms-agreement": { "defaultMessage": "Jag godkänner Belöningsprogrammets Villkor" }, @@ -1958,12 +2039,18 @@ "label.select-all": { "defaultMessage": "Välj alla" }, + "label.selected": { + "defaultMessage": "Vald" + }, "label.selection-actions": { "defaultMessage": "Valåtgärder" }, "label.server": { "defaultMessage": "Server" }, + "label.server-only": { + "defaultMessage": "Endast server" + }, "label.servers": { "defaultMessage": "Servrar" }, @@ -1994,6 +2081,9 @@ "label.updating": { "defaultMessage": "Uppdaterar..." }, + "label.upload-failed": { + "defaultMessage": "Uppladdning misslyckades" + }, "label.username": { "defaultMessage": "Användarnamn" }, @@ -2162,6 +2252,9 @@ "markdown-editor.markdown-formatting-support": { "defaultMessage": "Denna redigerare stödjer markdown formatering." }, + "markdown-editor.max-length.label": { + "defaultMessage": "Max längd:" + }, "markdown-editor.max-length.unlimited": { "defaultMessage": "Obegränsad" }, @@ -2420,6 +2513,108 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.user": { + "defaultMessage": "En Modrinth-användare." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Är du säker på att du vill blocka den här användaren?" + }, + "profile.block-user.success-title": { + "defaultMessage": "Användare blockerad" + }, + "profile.block-user.title": { + "defaultMessage": "Blocka {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Visa användarstatistik" + }, + "profile.button.block": { + "defaultMessage": "Blockera" + }, + "profile.button.create-project": { + "defaultMessage": "Skapa ett projekt" + }, + "profile.button.info": { + "defaultMessage": "Visa användardetaljer" + }, + "profile.button.manage-projects": { + "defaultMessage": "Hantera projekt" + }, + "profile.button.unblock": { + "defaultMessage": "Avblockera" + }, + "profile.collection.projects-count": { + "defaultMessage": "projekt" + }, + "profile.details.label.email-verified": { + "defaultMessage": "E-post verifierad" + }, + "profile.details.label.has-password": { + "defaultMessage": "Har lösenord" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Har TOTP" + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Betalningsmetoder" + }, + "profile.details.title": { + "defaultMessage": "Användardetaljer" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "E-post ej verifierad" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "E-post verifierad" + }, + "profile.error.load-description": { + "defaultMessage": "Användarprofilen kunde inte laddas in." + }, + "profile.error.not-found": { + "defaultMessage": "Användare hittades inte" + }, + "profile.label.collection": { + "defaultMessage": "Sammling" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {nedladdning} other {nedladdningar}}" + }, + "profile.label.joined": { + "defaultMessage": "Gick med" + }, + "profile.label.no-collections": { + "defaultMessage": "Den här användaren har inga samlingar!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Du har inga samlingar än." + }, + "profile.label.no-projects": { + "defaultMessage": "Den här användaren har inga projekt!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Du har inga projekt än." + }, + "profile.label.organizations": { + "defaultMessage": "Organisationer" + }, + "profile.label.project-count": { + "defaultMessage": "Projekt" + }, + "profile.official-account": { + "defaultMessage": "Officiellt Modrinth-konto" + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Ett fel inträffade under avblockeringen av den här användaren. Vänligen försök igen." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Misslyckades att avblockera användare" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} har avblockerats." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Användare avblockerad" + }, "project-card.date.published.tooltip": { "defaultMessage": "Skapades {date}" }, @@ -2438,9 +2633,15 @@ "project-card.environment.server": { "defaultMessage": "Server" }, + "project-card.environment.singleplayer": { + "defaultMessage": "Enspelarläge" + }, "project-type.all": { "defaultMessage": "Alla" }, + "project-type.collection.plural": { + "defaultMessage": "Samlingar" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Datapaket} other {Datapaket}}" }, @@ -2540,6 +2741,9 @@ "project.about.compatibility.platforms": { "defaultMessage": "Plattformar" }, + "project.about.compatibility.platforms-plural": { + "defaultMessage": "Platform{count, plural, one {} other {ar}}" + }, "project.about.compatibility.title": { "defaultMessage": "Kompatibilitet" }, @@ -2708,6 +2912,9 @@ "project.follower-count-tooltip": { "defaultMessage": "{count, number} följare" }, + "project.license.title": { + "defaultMessage": "Licens" + }, "project.online-player-count": { "defaultMessage": "{count, number} online" }, @@ -3113,6 +3320,12 @@ "project.settings.view.title": { "defaultMessage": "Visa" }, + "project.stats.downloads-label": { + "defaultMessage": "nedladdning{count, plural, one {} other {ar}}" + }, + "project.stats.followers-label": { + "defaultMessage": "följare" + }, "project.versions.channel.alpha.symbol": { "defaultMessage": "A" }, @@ -3122,6 +3335,9 @@ "project.versions.channel.release.symbol": { "defaultMessage": "R" }, + "project.versions.platform.modloader.short": { + "defaultMessage": "ModLoader" + }, "project.visibility.archived": { "defaultMessage": "Arkiverad" }, @@ -3200,12 +3416,6 @@ "search.filter_type.advanced": { "defaultMessage": "Avancerat" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Exkludera datapaket" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Exkludera moddar" - }, "search.filter_type.environment": { "defaultMessage": "Miljö" }, @@ -3338,6 +3548,9 @@ "servers.access-page.activity-log-filter.action.java-version-modified": { "defaultMessage": "Ändrade Java-version" }, + "servers.access-page.activity-log-filter.action.loader-version-edited": { + "defaultMessage": "Ändrade loaderversion" + }, "servers.access-page.activity-log-filter.action.modpack-changed": { "defaultMessage": "Ändrade modpaket" }, @@ -3638,6 +3851,18 @@ "servers.audit-log.event.java-version-modified": { "defaultMessage": "Ändrade Java-version till " }, + "servers.audit-log.event.loader-and-version-changed": { + "defaultMessage": "Ändrade loader till " + }, + "servers.audit-log.event.loader-changed": { + "defaultMessage": "Ändrade loader till " + }, + "servers.audit-log.event.loader-version-changed": { + "defaultMessage": "Ändrare loaderversion till " + }, + "servers.audit-log.event.loader-version-cleared": { + "defaultMessage": "Rensade laoaderversion" + }, "servers.audit-log.event.modpack-changed": { "defaultMessage": "Ändrade modpaket" }, @@ -3695,6 +3920,9 @@ "servers.audit-log.event.server-properties-modified-label": { "defaultMessage": "Modifierade serveregenskaper" }, + "servers.audit-log.event.server-reset": { + "defaultMessage": "Återställ server" + }, "servers.audit-log.event.server-restarted": { "defaultMessage": "Startade om server" }, @@ -3767,30 +3995,75 @@ "servers.backups.admonition.fallback-name": { "defaultMessage": "Din säkerhetskopia" }, + "servers.backups.admonition.restore-cancelled.title": { + "defaultMessage": "Återställning avbröts" + }, "servers.backups.admonition.restore-failed.description": { "defaultMessage": "Något gick fel när vi försökte återställa från säkerhetskopian {backupName}. Vänligen försök igen eller kontakta support om felet återkommer." }, + "servers.backups.admonition.restore-failed.title": { + "defaultMessage": "Återställning misslyckades" + }, "servers.backups.admonition.restore-queued.description": { "defaultMessage": "Återställning från {backupName} är köad och kommer att börja strax." }, "servers.backups.admonition.restore-successful.description": { "defaultMessage": "Din server har återställts till {backupName} och är redo för att startas." }, + "servers.backups.admonition.restore-successful.title": { + "defaultMessage": "Återställning slutförd" + }, "servers.backups.admonition.restoring-backup.description": { "defaultMessage": "Återställer din server från {backupName}. Detta kan ta några minuter." }, "servers.backups.admonition.restoring-backup.title": { "defaultMessage": "Återställer från säkerhetskopia" }, + "servers.backups.bulk-bar.deleting": { + "defaultMessage": "Raderar {total, plural, one {# säkerhetskopia} other {# säkerhetskopior}}..." + }, + "servers.backups.bulk-bar.selected-count": { + "defaultMessage": "{count, plural, one {# säkerhetskopia vald} other {# säkerhetskopior valda}}" + }, "servers.backups.delete-modal.admonition-body": { "defaultMessage": "När {count, plural, one {denna säkerhetskopia raderas kan den} other {dessa säkerhetskopior raderas kan de}} inte återställas. Radering är permanent." }, + "servers.backups.delete-modal.admonition-header": { + "defaultMessage": "Raderingsvarning" + }, + "servers.backups.delete-modal.backups-label": { + "defaultMessage": "{count, plural, one {Säkerhetskopia} other {Säkerhetskopior ({count})}}" + }, + "servers.backups.delete-modal.confirm": { + "defaultMessage": "Radera {count, plural, one {säkerhetskopia} other {# säkerhetskopior}}" + }, + "servers.backups.delete-modal.header": { + "defaultMessage": "Radera {count, plural, one {säkerhetskopia} other {säkerhetskopior}}" + }, + "servers.backups.empty.description": { + "defaultMessage": "Skapa din första säkerhetskopia" + }, + "servers.backups.empty.heading": { + "defaultMessage": "Inga säkerhetskopior än" + }, + "servers.backups.filtered-empty.clear-filters": { + "defaultMessage": "Töm filter" + }, + "servers.backups.filtered-empty.description": { + "defaultMessage": "Prova ett annat filer eller töm filtren för att se alla säkerhetskopior." + }, + "servers.backups.filtered-empty.heading": { + "defaultMessage": "Inga säkerhetskopior matchar" + }, "servers.backups.item.auto": { "defaultMessage": "Auto" }, "servers.backups.item.backup-schedule": { "defaultMessage": "Säkerhetskopieringschema" }, + "servers.backups.item.creator-avatar-alt": { + "defaultMessage": "{username}s avatar" + }, "servers.backups.item.manual-backup": { "defaultMessage": "Manuel säkerhetskopiering" }, @@ -3800,6 +4073,9 @@ "servers.backups.item.restore": { "defaultMessage": "Återställ" }, + "servers.backups.select-backup-aria": { + "defaultMessage": "Välj säkerhetskopia {name}" + }, "servers.backups.toolbar.create-backup": { "defaultMessage": "Skapa säkerhetskopia" }, @@ -3872,12 +4148,18 @@ "servers.installing-banner.error.internal-platform": { "defaultMessage": "Ett internt fel inträffade när plattformen installerades. Vänligen försök igen." }, + "servers.installing-banner.error.invalid-loader-version": { + "defaultMessage": "Den angivna loader eller Minecraft-versionen kunde inte installeras. Den kan vara ogiltig eller stöds inte." + }, "servers.installing-banner.error.modpack-install-failed": { "defaultMessage": "Modpaketet kunde inte installeras. Det kanske är korrumperad eller inkompatibel." }, "servers.installing-banner.error.unknown": { "defaultMessage": "Ett oväntat fel inträffade under installeringen." }, + "servers.installing-banner.error.unsupported-loader-version": { + "defaultMessage": "Denna version av Minecraft eller loader stöds ännu inte av Modrinth Hosting." + }, "servers.installing-banner.phase.installing-addons": { "defaultMessage": "Installerar tillägg..." }, @@ -3906,7 +4188,7 @@ "defaultMessage": "Ny server" }, "servers.list-empty.no-servers-description": { - "defaultMessage": "Installera moddar, bjud in vänner och spela tillsammans, allt från Modrinth-appen." + "defaultMessage": "Installera moddar, bjud in vänner och spela tillsammans, allt från Modrinth App." }, "servers.list-empty.no-servers-title": { "defaultMessage": "Inga servrar än" @@ -3983,6 +4265,9 @@ "servers.manage.error.details": { "defaultMessage": "Feldetaljer:" }, + "servers.manage.error.title": { + "defaultMessage": "Servrar kunde inte laddas in" + }, "servers.manage.handle-error.title": { "defaultMessage": "Ett fel inträffade" }, @@ -4001,6 +4286,9 @@ "servers.manage.purchase-unavailable.text": { "defaultMessage": "Betalningsinformation laddar fortfarande. Öppnar kassan så snart som möjligt." }, + "servers.manage.purchase-unavailable.title": { + "defaultMessage": "Köp otillgängligt" + }, "servers.manage.reload-button": { "defaultMessage": "Ladda om" }, @@ -4034,9 +4322,15 @@ "servers.manage.your-servers-title": { "defaultMessage": "Dina servrar" }, + "servers.medal-listing.countdown.remaining": { + "defaultMessage": "{days} {days, plural, one {dag} other {dagar}} {hours} {hours, plural, one {timme} other {timmar}} {minutes} {minutes, plural, one {minut} other {minuter}} {seconds} {seconds, plural, one {sekund} other {sekunder}} återstår..." + }, "servers.medal-listing.new-server-label": { "defaultMessage": "Ny server" }, + "servers.medal-listing.notice.upgrading": { + "defaultMessage": "Din servers hårdvara uppgraderas just nu och kommer snart vara online igen." + }, "servers.medal-listing.owner-avatar-alt": { "defaultMessage": "{username}s avatar" }, @@ -4232,6 +4526,12 @@ "servers.setup.onboarding.modpack-upload-failed.title": { "defaultMessage": "Modpaket-uppladdning misslyckades" }, + "servers.setup.onboarding.setup-server.button": { + "defaultMessage": "Ställ in server" + }, + "servers.setup.onboarding.step.choose.description": { + "defaultMessage": "Välj ditt favorit modpaket från Modrinth, eller välj en loader och lägg till de moddar du vill." + }, "servers.setup.onboarding.step.choose.title": { "defaultMessage": "Välj vad du vill spela" }, @@ -4241,6 +4541,9 @@ "servers.setup.onboarding.step.invite-friends.title": { "defaultMessage": "Bjud in dina vänner" }, + "servers.setup.onboarding.steps.heading": { + "defaultMessage": "Ställ in din server (≈ 2 min)" + }, "servers.setup.onboarding.uploading.progress": { "defaultMessage": "Laddar upp ({percent, number}%)" }, @@ -4275,7 +4578,7 @@ "defaultMessage": "Dina applikationer" }, "settings.authorized-apps.title": { - "defaultMessage": "Auktoriserade appar" + "defaultMessage": "Behöriga appar" }, "settings.billing.title": { "defaultMessage": "Prenumerationer" @@ -4293,10 +4596,10 @@ "defaultMessage": "OLED" }, "settings.display.theme.preferred-dark-theme": { - "defaultMessage": "Önskat mörkt tema" + "defaultMessage": "Föredraget mörkt tema" }, "settings.display.theme.preferred-light-theme": { - "defaultMessage": "Önskat ljust tema" + "defaultMessage": "Föredraget ljust tema" }, "settings.display.theme.retro": { "defaultMessage": "Retro" @@ -4340,9 +4643,177 @@ "settings.pats.title": { "defaultMessage": "Personliga åtkomstnycklar" }, + "settings.profile.bio.title": { + "defaultMessage": "Biografi" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Profil" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Profilbild" + }, + "settings.profile.save-error": { + "defaultMessage": "Misslyckades att uppdatera profil" + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Logga in på ett Modrinth-konto för att anpassa din offentliga profil." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Modrinth-konto behövs" + }, "settings.sessions.title": { "defaultMessage": "Sessioner" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Åtgärder" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Användare" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Det här är användare du har blockat på Modrinth. De kan inte:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Du har inte blockerat någon." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Blockerade användare kunde inte laddas in." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Laddar in blockerade användare…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Skicka vänförfrågan till dig" + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Bjuda in dig till en delad instans" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Blockerade användare" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Avblockera" + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Avblockera {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "{username}s avatar" + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Vänförfrågningar" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Kommer snart!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Alla" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Vänner" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Vänners vänner" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Ingen" + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Inbjudningar" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Modrinth-konto krävs" + }, + "sharing.invite-players-modal.add": { + "defaultMessage": "Lägg till" + }, + "sharing.invite-players-modal.added": { + "defaultMessage": "Tillagd" + }, + "sharing.invite-players-modal.already-invited": { + "defaultMessage": "Den här användaren har redan bjudits in." + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Tillämpa" + }, + "sharing.invite-players-modal.avatar-alt": { + "defaultMessage": "{username}s avatar" + }, + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Anpassat..." + }, + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Anpassat: {date}" + }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "Om 1 dag" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "Om 1 timme" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "Om 7 dagar" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "Om 6 timmar" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "Om 3 dagar" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "Om 12 timmar" + }, + "sharing.invite-players-modal.expiry-label": { + "defaultMessage": "Utgångsdatum" + }, + "sharing.invite-players-modal.friends-heading": { + "defaultMessage": "Dina vänner – {count}" + }, + "sharing.invite-players-modal.invite": { + "defaultMessage": "Bjud in" + }, + "sharing.invite-players-modal.invite-expiry-description": { + "defaultMessage": "Din inbjudningslänk går ut om {duration}." + }, + "sharing.invite-players-modal.invite-link-heading": { + "defaultMessage": "Eller använd en inbjudningslänk" + }, + "sharing.invite-players-modal.link-copied-text": { + "defaultMessage": "Inbjudningslänken har kopierats till urklippet." + }, + "sharing.invite-players-modal.link-copied-title": { + "defaultMessage": "Länk kopierad" + }, + "sharing.invite-players-modal.link-copy-failed-title": { + "defaultMessage": "Kunde inte kopiera länk" + }, + "sharing.invite-players-modal.max-uses-label": { + "defaultMessage": "Högst antal användningar" + }, + "sharing.invite-players-modal.no-friends": { + "defaultMessage": "Inga vänner hittades." + }, + "sharing.invite-players-modal.no-search-results": { + "defaultMessage": "Inga matchande användare hittades." + }, + "sharing.invite-players-modal.requested": { + "defaultMessage": "Förfrågan skickad" + }, + "sharing.invite-players-modal.requested-tooltip": { + "defaultMessage": "{username} behöver acceptera din vänförfrågan först" + }, + "sharing.invite-players-modal.save-button": { + "defaultMessage": "Spara" + }, + "sharing.invite-players-modal.search-placeholder": { + "defaultMessage": "Ange Modrinth-användarnamn" + }, + "sharing.invite-players-modal.searching": { + "defaultMessage": "Söker..." + }, + "sharing.invite-players-modal.update-invite-link-failed-title": { + "defaultMessage": "Kunde inte uppdatera inbjudningslänken" + }, "tag.category.128x": { "defaultMessage": "128x" }, @@ -4844,6 +5315,9 @@ "ui.confirm-leave-modal.title": { "defaultMessage": "Lämna sidan?" }, + "ui.stacked-admonitions.dismiss-all": { + "defaultMessage": "Avvisa alla" + }, "unknown-file-warning-modal.dont-install": { "defaultMessage": "Installera inte" }, @@ -4889,12 +5363,18 @@ "user.profile.badge.pride.about.1": { "defaultMessage": "Denna användare har deltagit i åtminstone ett av Modrinths Pride-insamlingar för LGBTQ+ gemenskapen." }, + "user.profile.badge.staff.name": { + "defaultMessage": "Modrinth-team" + }, "version.content.name": { "defaultMessage": "Namn" }, "version.content.version": { "defaultMessage": "Version" }, + "version.file-type.primary": { + "defaultMessage": "Primär" + }, "version.file-type.signature": { "defaultMessage": "Signaturfil" }, @@ -4925,6 +5405,9 @@ "version.section.included-content": { "defaultMessage": "Inkluderat innehåll" }, + "version.section.no-modpack-mod-loader": { + "defaultMessage": "Ingen modloader" + }, "version.supplementary-resources.file": { "defaultMessage": "Fil" }, diff --git a/packages/ui/src/locales/th-TH/index.json b/packages/ui/src/locales/th-TH/index.json index 4908b72a79..8be06fa3ac 100644 --- a/packages/ui/src/locales/th-TH/index.json +++ b/packages/ui/src/locales/th-TH/index.json @@ -317,15 +317,6 @@ "instances.content-install.select-icon": { "defaultMessage": "เลือกไอคอน" }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "ไม่พบเนื้อหา" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "เนื้อหาม็อดแพ็ค" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "กำลังโหลดเนื้อหา" - }, "label.available": { "defaultMessage": "ว่างอยู่ {amount}" }, diff --git a/packages/ui/src/locales/tr-TR/index.json b/packages/ui/src/locales/tr-TR/index.json index 5d52c8ea46..41a6191f92 100644 --- a/packages/ui/src/locales/tr-TR/index.json +++ b/packages/ui/src/locales/tr-TR/index.json @@ -467,9 +467,21 @@ "content.diff-modal.external-diff-type.updated": { "defaultMessage": "Güncellendi" }, + "content.diff-modal.file-count": { + "defaultMessage": "{count, plural,one {# dosya}other {# dosya}}" + }, + "content.diff-modal.game-version-updated": { + "defaultMessage": "Oyun sürümü" + }, "content.diff-modal.install-anyway": { "defaultMessage": "Yine de indir" }, + "content.diff-modal.loader-updated": { + "defaultMessage": "Yükleyici" + }, + "content.diff-modal.modpack-linked": { + "defaultMessage": "Bağlantılı mod paketi" + }, "content.diff-modal.removed-count": { "defaultMessage": "{count} kaldırıldı" }, @@ -584,18 +596,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Proje isimleri" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Alfabetik" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Önce en yeni" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Önce en eski" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sıralama şekli {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Tümünü güncelle" }, @@ -1160,6 +1160,15 @@ "external-files.permissions-card.reason.special-permission.description": { "defaultMessage": "Bu çalışmayı mod paketinizde yeniden dağıtmak için özel izin alınmıştır." }, + "external-files.permissions-card.remove-group": { + "defaultMessage": "Grubu sil" + }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "{title} silinsin mi?" + }, + "external-files.permissions-card.remove-group-error.title": { + "defaultMessage": "Grup silinemedi" + }, "external-files.permissions-card.split-file": { "defaultMessage": "Gruptan kaldır" }, @@ -1253,9 +1262,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Dosya kaydedildi" }, - "files.editor.find-close": { - "defaultMessage": "Kapat" - }, "files.editor.find-in-file": { "defaultMessage": "Bul" }, @@ -2033,24 +2039,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Simge seç" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Bu mod paketi başka hiç bir ekstra işerik içermez." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "İçerik bulunamadı" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Mod paketi içeriği" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "İçerik yükleniyor..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Aramanızla eşleşen proje yok." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Search {count, number} {count, plural, one {project} other {projects}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Şu anki" }, @@ -2792,6 +2780,42 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.user": { + "defaultMessage": "Bir Modrinth kullanıcısı." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Bu kullanıcıyı engellemek istediğinize emin misiniz?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Kullanıcıyı engellerken bir sorun oluştu. Lütfen tekrar deneyin." + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} engellendi." + }, + "profile.block-user.success-title": { + "defaultMessage": "Kullanıcı engellendi" + }, + "profile.block-user.title": { + "defaultMessage": "{username}'i engelle" + }, + "profile.button.analytics": { + "defaultMessage": "Kullanıcı analizlerini göster" + }, + "profile.button.block": { + "defaultMessage": "Engelle" + }, + "profile.button.info": { + "defaultMessage": "Kullanıcı detaylarını göster" + }, + "profile.button.unblock": { + "defaultMessage": "Engellemeyi kaldır" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural,one{# proje} other{# proje}}" + }, + "profile.error.load-description": { + "defaultMessage": "Kullanıcı profili yüklenemedi." + }, "profile.label.badges": { "defaultMessage": "Rozetler" }, @@ -3593,15 +3617,6 @@ "search.filter_type.advanced": { "defaultMessage": "Gelişmiş" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Veri paketlerini hariç tut" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Modları hariç tut" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Eklentileri hariç tut" - }, "search.filter_type.environment": { "defaultMessage": "Ortam" }, diff --git a/packages/ui/src/locales/uk-UA/index.json b/packages/ui/src/locales/uk-UA/index.json index 67d677efb3..bbab12eba5 100644 --- a/packages/ui/src/locales/uk-UA/index.json +++ b/packages/ui/src/locales/uk-UA/index.json @@ -374,6 +374,9 @@ "content.confirm-deletion.header": { "defaultMessage": "Видалити {itemType}" }, + "content.confirm-disable.header": { + "defaultMessage": "Вимкнути {itemType}" + }, "content.confirm-modpack-update.admonition-body": { "defaultMessage": "{action, select, downgrade {Пониження} other {Підвищення}} може спричинити проблеми сумісности. Моди чи вміст, який ви додали в збірку, буде збережено, але може бути несумісним із новою версією." }, @@ -443,12 +446,18 @@ "content.diff-modal.added-count": { "defaultMessage": "Додано {count}" }, + "content.diff-modal.config-files-updated": { + "defaultMessage": "Змінені конфігураційні файли" + }, "content.diff-modal.diff-type.added": { "defaultMessage": "Додано (залежності)" }, "content.diff-modal.diff-type.removed": { "defaultMessage": "Вимкнено" }, + "content.diff-modal.diff-type.removed-disabled": { + "defaultMessage": "Видалено (вимкнено)" + }, "content.diff-modal.diff-type.updated": { "defaultMessage": "Оновлено" }, @@ -464,12 +473,36 @@ "content.diff-modal.external-diff-type.updated": { "defaultMessage": "Оновлено" }, + "content.diff-modal.file-count": { + "defaultMessage": "{count, plural, one {# файл} few {# файли} many {# файлів} other {# файлу}}" + }, + "content.diff-modal.game-version-updated": { + "defaultMessage": "Версія гри" + }, "content.diff-modal.install-anyway": { "defaultMessage": "Усе одно встановити" }, + "content.diff-modal.loader-updated": { + "defaultMessage": "Завантажувач" + }, + "content.diff-modal.modpack-linked": { + "defaultMessage": "Прив'язана збірка" + }, + "content.diff-modal.modpack-unlinked": { + "defaultMessage": "Відв'язана збірка" + }, + "content.diff-modal.modpack-updated": { + "defaultMessage": "Оновлена збірка" + }, + "content.diff-modal.no-content-changes": { + "defaultMessage": "Без змін у вмісті" + }, "content.diff-modal.removed-count": { "defaultMessage": "Видалено {count}" }, + "content.diff-modal.removed-disabled-count": { + "defaultMessage": "Видалено (вимкнено): {count}" + }, "content.diff-modal.reviewed-files": { "defaultMessage": "Файл перевірятиметься, лише якщо його опубліковано на Modrinth, незалежно від його формату (включно з .mrpack)." }, @@ -525,7 +558,7 @@ "defaultMessage": "Утримуйте клавішу Shift під час натискання, щоб пропустити підтвердження." }, "content.inline-backup.warning-body": { - "defaultMessage": "Ми рекомендуємо створити резервну копію перш ніж продовжувати, щоб ви могли відновити свій {type}, якщо щось піде не так." + "defaultMessage": "Радимо створити резервну копію перед тим, як продовжити, щоб ви могли відновити ваш {type}, якщо щось зламається." }, "content.inline-backup.world-label": { "defaultMessage": "світ" @@ -575,18 +608,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Назви проєктів" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "За абеткою" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Спочатку новіші" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Спочатку старіші" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Сортування: {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Оновити все" }, @@ -810,7 +831,7 @@ "defaultMessage": "Переглянути збірки" }, "creation-flow.modal.modpack.action.import": { - "defaultMessage": "Імпортувати збірку" + "defaultMessage": "Перенести збірку" }, "creation-flow.modal.modpack.known-modpack.prompt": { "defaultMessage": "Уже знаєте яку збірку хочете встановити?" @@ -831,13 +852,13 @@ "defaultMessage": "Власне налаштування" }, "creation-flow.modal.setup-type.option.import-instance.description": { - "defaultMessage": "Імпортуйте збірку з Prism, CurseForge або подібних програм." + "defaultMessage": "Перенесіть збірку з Prism, CurseForge абощо." }, "creation-flow.modal.setup-type.option.import-instance.title": { "defaultMessage": "Імпорт збірки" }, "creation-flow.modal.setup-type.option.modpack-base.description": { - "defaultMessage": "Перегляньте збірки на Modrinth або імпортуйте їх з файлу." + "defaultMessage": "Перегляньте збірки на Modrinth або перенесіть їх із файлу." }, "creation-flow.modal.setup-type.option.modpack-base.title": { "defaultMessage": "Установити збірку" @@ -1115,6 +1136,21 @@ "external-files.permissions-card.reason.special-permission.description": { "defaultMessage": "Ви отримали особливі дозволи для поширення цієї роботи у вашій збірці." }, + "external-files.permissions-card.remove-group": { + "defaultMessage": "Видалити групу" + }, + "external-files.permissions-card.remove-group-confirmation.description": { + "defaultMessage": "Це назавжди видалить цю групу атрибуції та всі файли в ній. Цю дію неможливо скасувати." + }, + "external-files.permissions-card.remove-group-confirmation.title": { + "defaultMessage": "Видалити {title}?" + }, + "external-files.permissions-card.remove-group-error.title": { + "defaultMessage": "Групу не видалено" + }, + "external-files.permissions-card.remove-group-shift-hint": { + "defaultMessage": "Утримуйте Shift під час кліку, щоб пропустити підтвердження." + }, "external-files.permissions-card.split-file": { "defaultMessage": "Видалити з групи" }, @@ -1208,9 +1244,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Файл збережено" }, - "files.editor.find-close": { - "defaultMessage": "Закрити" - }, "files.editor.find-in-file": { "defaultMessage": "Знайти" }, @@ -1800,10 +1833,10 @@ "defaultMessage": "Редагувати інсталяцію" }, "installation-settings.edit.warning-instance": { - "defaultMessage": "Ми не рекомендуємо змінювати налаштування інсталяції після встановлення вмісту. Якщо ви все ж хочете їх змінити, будьте обережні, оскільки це може спричинити проблеми." + "defaultMessage": "Не радимо відміняти налаштування інсталяції після встановлення вмісту. Коли все ж бажаєте їх змінити, то будьте обережні, адже це може завдати вам клопоту." }, "installation-settings.edit.warning-server": { - "defaultMessage": "Ми не рекомендуємо змінювати налаштування інсталяції після встановлення вмісту. Якщо ви все ж хочете їх змінити, скиньте ваш сервер." + "defaultMessage": "Не радимо змінювати налаштування інсталяції після встановлення вмісту. Коли все ж хочете їх змінити, то скиньте свій сервер." }, "installation-settings.incompatible-content.auto-fix-button": { "defaultMessage": "Виправити автоматично" @@ -1988,24 +2021,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Вибрати значок" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Збірка не включає додатковий уміст." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Умісту не знайдено" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Уміст збірки" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Завантаження вмісту…" - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "За вашим запитом не знайдено жодного проєкту." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Пошук {count, number} {count, plural, one {проєкту} other {проєктів}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Поточна" }, @@ -2138,6 +2153,9 @@ "label.details": { "defaultMessage": "Деталі" }, + "label.discover-content": { + "defaultMessage": "Огляд вмісту" + }, "label.done": { "defaultMessage": "Готово" }, @@ -2216,6 +2234,9 @@ "label.password": { "defaultMessage": "Пароль" }, + "label.permissions": { + "defaultMessage": "Дозволи" + }, "label.plan-custom": { "defaultMessage": "Власний" }, @@ -2747,9 +2768,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "Творець Modrinth." + }, + "profile.bio.fallback.user": { + "defaultMessage": "Користувач Modrinth." + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} Не зможе надсилати вам запити в друзі, запрошувати до спільних збірок або запрошувати на сервери Modrinth Hosting." + }, + "profile.block-user.admonition-title": { + "defaultMessage": "Дійсно заблокувати цього користувача?" + }, + "profile.block-user.error-description": { + "defaultMessage": "Виникла помилка під час блокування користувача. Спробуйте знову." + }, + "profile.block-user.error-title": { + "defaultMessage": "Не вдалося заблокувати користувача" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} заблоковано." + }, + "profile.block-user.success-title": { + "defaultMessage": "Користувача заблоковано" + }, + "profile.block-user.title": { + "defaultMessage": "Заблокувати {username}" + }, + "profile.button.analytics": { + "defaultMessage": "Переглянути аналітику користувача" + }, + "profile.button.billing": { + "defaultMessage": "Керувати виплатами користувача" + }, + "profile.button.block": { + "defaultMessage": "Заблокувати" + }, + "profile.button.create-collection": { + "defaultMessage": "Створити добірку" + }, + "profile.button.create-project": { + "defaultMessage": "Створити проєкт" + }, + "profile.button.info": { + "defaultMessage": "Деталі про користувача" + }, + "profile.button.manage-projects": { + "defaultMessage": "Керувати проєктами" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "Видалити як партнера" + }, + "profile.button.set-affiliate": { + "defaultMessage": "Призначити партнером" + }, + "profile.button.unblock": { + "defaultMessage": "Розблокувати" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, one {# проєкт} few {# проєкти} many {# проєктів} other {# проєкту}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "Дозвольте спливні вікна для Modrinth, потім спробуйте знову." + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "Не вдалося отримати профіль GitHub. Спробуйте знову." + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "Не вдалося відкрити профіль GitHub" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "Сервіси автентифікації" + }, + "profile.details.label.email-verified": { + "defaultMessage": "Підтверджена електронна пошта" + }, + "profile.details.label.has-password": { + "defaultMessage": "Має пароль" + }, + "profile.details.label.has-totp": { + "defaultMessage": "Має TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "Завантаження…" + }, + "profile.details.label.payment-methods": { + "defaultMessage": "Способи оплати" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "Переглянути профіль" + }, + "profile.details.title": { + "defaultMessage": "Деталі користувача" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "Пошту не підтверджено" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "Пошту підтверджено" + }, + "profile.error.load-description": { + "defaultMessage": "Не вдалося завантажити профіль користувача." + }, + "profile.error.not-found": { + "defaultMessage": "Користувача не знайдено" + }, + "profile.label.affiliate": { + "defaultMessage": "Партнер" + }, "profile.label.badges": { "defaultMessage": "Значки" }, + "profile.label.collection": { + "defaultMessage": "Добірка" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, one {завантаження} few {завантаження} many {завантажень} other {завантаження}}" + }, + "profile.label.joined": { + "defaultMessage": "Приєднався" + }, + "profile.label.no-collections": { + "defaultMessage": "Цей користувач не має добірок!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "Ви поки не маєте добірок." + }, + "profile.label.no-projects": { + "defaultMessage": "Цей користувач не має проєктів!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "Ви поки не маєте проєктів." + }, + "profile.label.organizations": { + "defaultMessage": "Організації" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, one {проєкт} few {проєкти} many {проєктів} other {проєктів}}" + }, + "profile.official-account": { + "defaultMessage": "Офіційний обліковий запис Modrinth" + }, + "profile.official-account.bio": { + "defaultMessage": "Офіційний обліковий запис Modrinth. Зв'язатися з підтримкою можна за або через електронну пошту за " + }, + "profile.unblock-user.error-description": { + "defaultMessage": "Виникла помилка під час розблокування користувача. Спробуйте знову." + }, + "profile.unblock-user.error-title": { + "defaultMessage": "Не вдалося розблокувати користувача" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} розблоковано." + }, + "profile.unblock-user.success-title": { + "defaultMessage": "Користувача розблоковано" + }, "project-card.date.published.tooltip": { "defaultMessage": "Опубліковано {date}" }, @@ -2765,12 +2939,21 @@ "project-card.environment.client-or-server": { "defaultMessage": "Клієнт чи сервер" }, + "project-card.environment.dedicated-server": { + "defaultMessage": "Виділений сервер" + }, "project-card.environment.server": { "defaultMessage": "Сервер" }, + "project-card.environment.singleplayer": { + "defaultMessage": "Одиночна гра" + }, "project-type.all": { "defaultMessage": "Усі" }, + "project-type.collection.plural": { + "defaultMessage": "Добірки" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, one {Пакет даних} few {Пакети даних} many {Пакетів даних} other {Пакетів даних}}" }, @@ -3563,15 +3746,6 @@ "search.filter_type.advanced": { "defaultMessage": "Більше" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "Виключити пакети даних" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "Виключити моди" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "Виключити плаґіни" - }, "search.filter_type.environment": { "defaultMessage": "Середовище" }, @@ -4997,9 +5171,216 @@ "settings.pats.title": { "defaultMessage": "Особистий токен доступу" }, + "settings.profile.bio.description": { + "defaultMessage": "Короткий опис, щоб розповісти іншим трохи про себе." + }, + "settings.profile.bio.title": { + "defaultMessage": "Про себе" + }, + "settings.profile.navigation-title": { + "defaultMessage": "Профіль" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "Зображення профілю" + }, + "settings.profile.public-information.description": { + "defaultMessage": "Інформація з вашого профілю є загальнодоступною на Modrinth та через Modrinth API." + }, + "settings.profile.save-error": { + "defaultMessage": "Не вдалося оновити профіль" + }, + "settings.profile.save-error-description": { + "defaultMessage": "Виникла помилка під час оновлення вашого профілю Спробуйте знову." + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "Увійдіть за допомогою облікового запису Modrinth, щоб налаштувати свій публічний профіль." + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "Потрібен обліковий запис Modrinth" + }, + "settings.profile.username.description": { + "defaultMessage": "Унікальне ім'я для ідентифікації вашого профілю." + }, "settings.sessions.title": { "defaultMessage": "Сеанси" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "Дії" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "Користувач" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "Це користувачі, яких ви заблокували на Modrinth. Вони не можуть:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "Ви нікого не заблокували." + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "Не вдалося завантажити заблокованих користувачів." + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "Завантаження заблокованих користувачів…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "Надсилати вам запити в друзі" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "Запрошувати вас керувати сервером Modrinth Hosting." + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "Запрошувати вас до спільних збірок" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "Заблоковані користувачі" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "Розблокувати" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "Не вдалося розблокувати користувача" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "Сталася помилка під час розблокування цього користувача. Будь ласка, спробуйте ще раз." + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "Розблокувати {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "Аватар користувача {username}" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "Керуйте тим, хто може надсилати вам запити в друзі на Modrinth." + }, + "settings.social.friend-requests.title": { + "defaultMessage": "Запити в друзі" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "Незабаром!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "Усі" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "Друзі" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "Друзі друзів" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "Ніхто" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "Керуйте тим, хто може надсилати вам запрошення до спільних збірок та панелей Modrinth Hosting." + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "Запрошення" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "З обліковим записом Modrinth ви можете налаштувати, хто може взаємодіяти з вами, або керувати заблокованими користувачами" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "Потрібен обліковий запис Modrinth" + }, + "settings.social.title": { + "defaultMessage": "Соціальні мережі" + }, + "sharing.invite-players-modal.add": { + "defaultMessage": "Додати" + }, + "sharing.invite-players-modal.added": { + "defaultMessage": "Додано" + }, + "sharing.invite-players-modal.already-invited": { + "defaultMessage": "Цього користувача вже запрошено." + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "Застосувати" + }, + "sharing.invite-players-modal.avatar-alt": { + "defaultMessage": "Аватар користувача {username}" + }, + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "Власна…" + }, + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "Власна: {date}" + }, + "sharing.invite-players-modal.edit-invite-link": { + "defaultMessage": "Редагувати посилання-запрошення." + }, + "sharing.invite-players-modal.edit-invite-link-title": { + "defaultMessage": "Редагувати посилання-запрошення" + }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "Через 1 день" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "Через 1 годину" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "Через 7 днів" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "Через 6 годин" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "Через 3 дні" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "Через 12 годин" + }, + "sharing.invite-players-modal.expiry-label": { + "defaultMessage": "Термін дії" + }, + "sharing.invite-players-modal.friends-heading": { + "defaultMessage": "Ваші друзі — {count}" + }, + "sharing.invite-players-modal.invite": { + "defaultMessage": "Запросити" + }, + "sharing.invite-players-modal.invite-expiry-description": { + "defaultMessage": "Термін дії вашого посилання-запрошення закінчується через {duration}." + }, + "sharing.invite-players-modal.invite-link-heading": { + "defaultMessage": "Або використайте посилання-запрошення" + }, + "sharing.invite-players-modal.link-copied-text": { + "defaultMessage": "Посилання-запрошення скопійовано до буфера обміну." + }, + "sharing.invite-players-modal.link-copied-title": { + "defaultMessage": "Посилання скопійовано" + }, + "sharing.invite-players-modal.link-copy-failed-title": { + "defaultMessage": "Не вдалося скопіювати посилання" + }, + "sharing.invite-players-modal.max-uses-label": { + "defaultMessage": "Максимальна кількість використань" + }, + "sharing.invite-players-modal.no-friends": { + "defaultMessage": "Не знайдено друзів." + }, + "sharing.invite-players-modal.no-search-results": { + "defaultMessage": "Відповідних користувачів не знайдено." + }, + "sharing.invite-players-modal.requested": { + "defaultMessage": "Запит відправлено" + }, + "sharing.invite-players-modal.requested-tooltip": { + "defaultMessage": "{username} спочатку має прийняти ваш запит у друзі" + }, + "sharing.invite-players-modal.save-button": { + "defaultMessage": "Зберегти" + }, + "sharing.invite-players-modal.search-placeholder": { + "defaultMessage": "Уведіть ім’я користувача Modrinth" + }, + "sharing.invite-players-modal.searching": { + "defaultMessage": "Шукаємо…" + }, + "sharing.invite-players-modal.update-invite-link-failed-title": { + "defaultMessage": "Не вдалося оновити посилання" + }, "tag.category.128x": { "defaultMessage": "×128" }, @@ -5166,7 +5547,7 @@ "defaultMessage": "Низьке" }, "tag.category.magic": { - "defaultMessage": "Магія" + "defaultMessage": "Чаклунство" }, "tag.category.management": { "defaultMessage": "Керування" @@ -5190,7 +5571,7 @@ "defaultMessage": "ММО" }, "tag.category.mobs": { - "defaultMessage": "Моби" + "defaultMessage": "Сутності" }, "tag.category.modded": { "defaultMessage": "Для модів" @@ -5550,13 +5931,13 @@ "defaultMessage": "Шкідливе програмне забезпечення часто поширюють через моди, які публікуються на таких платформах, як Discord." }, "unknown-file-warning-modal.mod-warning-body": { - "defaultMessage": " не є опублікований на Modrinth. Ми наполегливо рекомендуємо встановлювати лише ті файли, яким довіряєте." + "defaultMessage": " не викладено на Modrinth. Наполегливо радимо встановлювати вміст лише з тих джерел, яким ви довіряєте." }, "unknown-file-warning-modal.mod-warning-title": { "defaultMessage": "Попередження про невідомий файл" }, "unknown-file-warning-modal.modpack-warning-body": { - "defaultMessage": " містить файли, які не є опубліковані на Modrinth. Ми наполегливо рекомендуємо встановлювати лише ті файли, яким довіряєте." + "defaultMessage": " містить файли, котрі не викладені на Modrinth. Наполегливо радимо встановлювати вміст лише з тих джерел, яким ви довіряєте." }, "unknown-file-warning-modal.modpack-warning-title": { "defaultMessage": "Попередження про невідомі файли" diff --git a/packages/ui/src/locales/vi-VN/index.json b/packages/ui/src/locales/vi-VN/index.json index 50d370d6d4..9e4f34f272 100644 --- a/packages/ui/src/locales/vi-VN/index.json +++ b/packages/ui/src/locales/vi-VN/index.json @@ -530,18 +530,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "Tên dự án" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "Thứ tự bảng chữ cái" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "Mới nhất" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "Cũ nhất" - }, - "content.page-layout.sort.label": { - "defaultMessage": "Sắp xếp theo {mode}" - }, "content.page-layout.update-all": { "defaultMessage": "Cập nhật tất cả" }, @@ -935,9 +923,6 @@ "files.editor.file-saved-title": { "defaultMessage": "Tệp đã được lưu" }, - "files.editor.find-close": { - "defaultMessage": "Đóng" - }, "files.editor.find-in-file": { "defaultMessage": "Tìm" }, @@ -1712,24 +1697,6 @@ "instances.content-install.select-icon": { "defaultMessage": "Chọn biểu tượng" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "Gói modpack này không bao gồm các nội dung bổ sung nào." - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "Không có nội dung nào được tìm thấy" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "Nội dung modpack" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "Đang tải nội dung..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "Không có dự án nào phù hợp với kết quả tìm kiếm." - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "Tìm {count, number} {count, plural, other {dự án}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "Hiện tại" }, diff --git a/packages/ui/src/locales/zh-CN/index.json b/packages/ui/src/locales/zh-CN/index.json index e4f883d767..c173ccbcb1 100644 --- a/packages/ui/src/locales/zh-CN/index.json +++ b/packages/ui/src/locales/zh-CN/index.json @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "项目名称" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "按字母顺序" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "按从新到旧顺序" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "按从旧到新顺序" - }, - "content.page-layout.sort.label": { - "defaultMessage": "按{mode}排序" - }, "content.page-layout.update-all": { "defaultMessage": "更新所有" }, @@ -1301,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "文件已保存" }, - "files.editor.find-close": { - "defaultMessage": "关闭" - }, "files.editor.find-in-file": { "defaultMessage": "查找" }, @@ -2081,33 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "选择图标" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "这个整合包不包含任何额外内容。" - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "未找到内容" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "外部来源" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "此文件未发布于 Modrinth 平台。" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "整合包内容" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "加载内容……" - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "没有符合搜索条件的项目。" - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "在 Slicer 中打开" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "搜索 {count, number} {count, plural, other {个项目}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "当前" }, @@ -2240,6 +2198,9 @@ "label.details": { "defaultMessage": "信息" }, + "label.discover-content": { + "defaultMessage": "发现内容" + }, "label.done": { "defaultMessage": "完成" }, @@ -2318,6 +2279,9 @@ "label.password": { "defaultMessage": "密码" }, + "label.permissions": { + "defaultMessage": "权限" + }, "label.plan-custom": { "defaultMessage": "自定义" }, @@ -2849,9 +2813,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "一位 Modrinth 创作者。" + }, + "profile.bio.fallback.user": { + "defaultMessage": "一位 Modrinth 用户。" + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} 将无法向你发送好友请求、将你邀请到共享实例或 Modrinth Hosting 服务器。" + }, + "profile.block-user.admonition-title": { + "defaultMessage": "你确定要屏蔽该用户吗?" + }, + "profile.block-user.error-description": { + "defaultMessage": "屏蔽该用户时发生了错误。请重试。" + }, + "profile.block-user.error-title": { + "defaultMessage": "屏蔽用户失败" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} 已被屏蔽。" + }, + "profile.block-user.success-title": { + "defaultMessage": "用户已屏蔽" + }, + "profile.block-user.title": { + "defaultMessage": "屏蔽 {username}" + }, + "profile.button.analytics": { + "defaultMessage": "查看用户分析" + }, + "profile.button.billing": { + "defaultMessage": "管理用户财务" + }, + "profile.button.block": { + "defaultMessage": "屏蔽" + }, + "profile.button.create-collection": { + "defaultMessage": "创建收藏夹" + }, + "profile.button.create-project": { + "defaultMessage": "创建项目" + }, + "profile.button.info": { + "defaultMessage": "查看用户详情" + }, + "profile.button.manage-projects": { + "defaultMessage": "管理项目" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "解除作为联盟伙伴" + }, + "profile.button.set-affiliate": { + "defaultMessage": "设置为联盟伙伴" + }, + "profile.button.unblock": { + "defaultMessage": "解除屏蔽" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, other {# 个项目}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "请在来自 Modrinth 的弹出窗口中选择允许,然后重试。" + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "无法获取 GitHub 个人资料。请重试。" + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "无法打开 GitHub 个人主页" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "身份验证提供器" + }, + "profile.details.label.email-verified": { + "defaultMessage": "电子邮箱已验证" + }, + "profile.details.label.has-password": { + "defaultMessage": "是否有密码" + }, + "profile.details.label.has-totp": { + "defaultMessage": "是否有 TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "正在加载……" + }, + "profile.details.label.payment-methods": { + "defaultMessage": "支付方式" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "查看个人资料" + }, + "profile.details.title": { + "defaultMessage": "用户详情" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "电子邮箱未验证" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "电子邮箱已验证" + }, + "profile.error.load-description": { + "defaultMessage": "无法加载该用户的个人资料。" + }, + "profile.error.not-found": { + "defaultMessage": "未找到用户" + }, + "profile.label.affiliate": { + "defaultMessage": "联盟" + }, "profile.label.badges": { "defaultMessage": "荣誉徽章" }, + "profile.label.collection": { + "defaultMessage": "收藏" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, other {次下载}}" + }, + "profile.label.joined": { + "defaultMessage": "加入于" + }, + "profile.label.no-collections": { + "defaultMessage": "该用户没有收藏夹!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "你还没有任何收藏夹。" + }, + "profile.label.no-projects": { + "defaultMessage": "该用户没有项目!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "你还没有任何项目。" + }, + "profile.label.organizations": { + "defaultMessage": "组织" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, other {项目}}" + }, + "profile.official-account": { + "defaultMessage": "官方 Modrinth 账户" + }, + "profile.official-account.bio": { + "defaultMessage": "Modrinth 的官方用户账号。可通过 或电子邮件 获取支持" + }, + "profile.unblock-user.error-description": { + "defaultMessage": "解除屏蔽该用户时发生了错误。请重试。" + }, + "profile.unblock-user.error-title": { + "defaultMessage": "解除屏蔽用户失败" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} 已被解除屏蔽。" + }, + "profile.unblock-user.success-title": { + "defaultMessage": "用户已解除屏蔽" + }, "project-card.date.published.tooltip": { "defaultMessage": "发布于 {date}" }, @@ -2879,6 +2996,9 @@ "project-type.all": { "defaultMessage": "全部" }, + "project-type.collection.plural": { + "defaultMessage": "收藏夹" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, other {数据包}}" }, @@ -3564,10 +3684,10 @@ "defaultMessage": "视图" }, "project.stats.downloads-label": { - "defaultMessage": "{count, plural, other {下载量}}" + "defaultMessage": "{count, plural, other {次下载}}" }, "project.stats.followers-label": { - "defaultMessage": "{count, plural, other {关注者}}" + "defaultMessage": "{count, plural, other {人关注}}" }, "project.versions.channel.alpha.symbol": { "defaultMessage": "A" @@ -3671,15 +3791,6 @@ "search.filter_type.advanced": { "defaultMessage": "高级" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "排除数据包" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "排除模组" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "排除插件" - }, "search.filter_type.environment": { "defaultMessage": "运行环境" }, @@ -3969,7 +4080,7 @@ "defaultMessage": "角色:{role}" }, "servers.access-page.role.editor": { - "defaultMessage": "编辑" + "defaultMessage": "编辑者" }, "servers.access-page.role.editor-description": { "defaultMessage": "管理实例内容、文件、备份及其他设置。" @@ -3984,13 +4095,13 @@ "defaultMessage": "受限" }, "servers.access-page.role.viewer-description": { - "defaultMessage": "可启动、停止并查看服务器状态,但无法进行更改。" + "defaultMessage": "可启动、停止和查看服务器,但无法进行更改。" }, "servers.access-page.search-users-placeholder": { "defaultMessage": "搜索 {count} {count, plural, one {用户} other {用户}}………" }, "servers.access-role.editor": { - "defaultMessage": "编辑" + "defaultMessage": "编辑者" }, "servers.access-role.owner": { "defaultMessage": "所有者" @@ -4467,7 +4578,7 @@ "defaultMessage": "邀请" }, "servers.grant-access-modal.permissions-help": { - "defaultMessage": "在这里查看各职务的完整清单。" + "defaultMessage": "在这里查看各角色权限的完整列表。" }, "servers.grant-access-modal.role.editor": { "defaultMessage": "编辑" @@ -4476,13 +4587,13 @@ "defaultMessage": "管理实例内容、文件、备份及其他设置。" }, "servers.grant-access-modal.role.label": { - "defaultMessage": "选择职能" + "defaultMessage": "选择角色" }, "servers.grant-access-modal.role.viewer": { - "defaultMessage": "受制" + "defaultMessage": "受限" }, "servers.grant-access-modal.role.viewer-description": { - "defaultMessage": "可以启动、停止与查看服务器,但无法进行任何更改。" + "defaultMessage": "可启动、停止和查看服务器,但无法进行更改。" }, "servers.grant-access-modal.suggestion-avatar-alt": { "defaultMessage": "{username}的头像" @@ -5105,9 +5216,120 @@ "settings.pats.title": { "defaultMessage": "个人访问令牌" }, + "settings.profile.bio.description": { + "defaultMessage": "用一段简短的描述,向大家展示你自己。" + }, + "settings.profile.bio.title": { + "defaultMessage": "简介" + }, + "settings.profile.navigation-title": { + "defaultMessage": "个人资料" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "头像" + }, + "settings.profile.public-information.description": { + "defaultMessage": "您的个人资料信息可以在 Modrinth 上公开查看,也可通过 Modrinth API 获取。" + }, + "settings.profile.save-error": { + "defaultMessage": "更新档案失败" + }, + "settings.profile.save-error-description": { + "defaultMessage": "更新个人资料失败,请稍后重试。" + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "登录 Modrinth 账号以自定义您的公开资料。" + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "需要 Modrinth 账户" + }, + "settings.profile.username.description": { + "defaultMessage": "用于识别您个人资料的唯一名称。" + }, "settings.sessions.title": { "defaultMessage": "会话" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "活动" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "用户" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "这些是你在 Modrinth 中屏蔽的用户。他们无法:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "你还没有屏蔽任何人。" + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "无法加载被屏蔽的用户。" + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "正在加载被屏蔽的用户…" + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "给你发送好友邀请" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "邀请你管理 Modrinth 托管服务器。" + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "邀请你加入共享实例" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "被屏蔽的用户" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "解除屏蔽" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "解除屏蔽用户失败" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "解除屏蔽该用户时发生了错误。请重试。" + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "解除屏蔽 {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "{username} 的头像" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "控制谁可以在 Modrinth 上向你发送好友申请。" + }, + "settings.social.friend-requests.title": { + "defaultMessage": "好友邀请" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "即将到来!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "所有人" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "好友" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "好友的好友" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "无" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "控制谁可以向您发送共享实例和 Modrinth 托管面板的邀请。" + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "邀请" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "使用 Modrinth 账号,你可以控制谁能与你互动,并管理黑名单用户" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "需要登录 Modrinth 账号" + }, + "settings.social.title": { + "defaultMessage": "社交" + }, "sharing.invite-players-modal.add": { "defaultMessage": "添加" }, @@ -5117,14 +5339,17 @@ "sharing.invite-players-modal.already-invited": { "defaultMessage": "此用户已被邀请。" }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "应用" + }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "{username} 的头像" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "取消" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "自定义……" }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "取消" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "自定义:{date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "编辑邀请链接。" @@ -5132,6 +5357,24 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "编辑邀请链接" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "1 天" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "1 小时" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "7 天" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "6 小时" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "3 天" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "12 小时" + }, "sharing.invite-players-modal.expiry-label": { "defaultMessage": "过期日期" }, diff --git a/packages/ui/src/locales/zh-TW/index.json b/packages/ui/src/locales/zh-TW/index.json index 191ff0108f..62ea4f4436 100644 --- a/packages/ui/src/locales/zh-TW/index.json +++ b/packages/ui/src/locales/zh-TW/index.json @@ -561,7 +561,7 @@ "defaultMessage": "按住 Shift 鍵並點選以跳過確認。" }, "content.inline-backup.warning-body": { - "defaultMessage": "我們建議您在繼續操作之前建立備份,以便在出現任何問題時可以還原您的{type}。" + "defaultMessage": "我們建議在繼續操作前先建立備份,以便在發生問題時還原你的{type}。" }, "content.inline-backup.world-label": { "defaultMessage": "世界" @@ -617,18 +617,6 @@ "content.page-layout.share.project-names": { "defaultMessage": "專案名稱" }, - "content.page-layout.sort.alphabetical": { - "defaultMessage": "字母順序" - }, - "content.page-layout.sort.date-added-newest": { - "defaultMessage": "最新在前" - }, - "content.page-layout.sort.date-added-oldest": { - "defaultMessage": "最舊在前" - }, - "content.page-layout.sort.label": { - "defaultMessage": "排序依據:{mode}" - }, "content.page-layout.update-all": { "defaultMessage": "更新全部" }, @@ -1278,10 +1266,10 @@ "defaultMessage": "刪除檔案" }, "files.delete-modal.warning.file": { - "defaultMessage": "此檔案將永久刪除。此操作無法撤銷。" + "defaultMessage": "這個檔案將永久刪除,這項動作無法復原。" }, "files.delete-modal.warning.folder": { - "defaultMessage": "此資料夾及其所有內容將永久刪除。此操作無法撤銷。" + "defaultMessage": "這個資料夾及其所有內容將永久刪除,這項動作無法復原。" }, "files.editor.failed-to-open-text": { "defaultMessage": "無法載入檔案內容。" @@ -1301,9 +1289,6 @@ "files.editor.file-saved-title": { "defaultMessage": "已儲存檔案" }, - "files.editor.find-close": { - "defaultMessage": "關閉" - }, "files.editor.find-in-file": { "defaultMessage": "尋找" }, @@ -2081,33 +2066,6 @@ "instances.content-install.select-icon": { "defaultMessage": "選擇圖示" }, - "instances.modpack-content-modal.empty-description": { - "defaultMessage": "這個模組包不包含任何額外內容。" - }, - "instances.modpack-content-modal.empty-title": { - "defaultMessage": "找不到內容" - }, - "instances.modpack-content-modal.external-content": { - "defaultMessage": "外部" - }, - "instances.modpack-content-modal.external-content-description": { - "defaultMessage": "這個檔案未在 Modrinth 上發布。" - }, - "instances.modpack-content-modal.header": { - "defaultMessage": "模組包內容" - }, - "instances.modpack-content-modal.loading": { - "defaultMessage": "正在載入內容..." - }, - "instances.modpack-content-modal.no-results": { - "defaultMessage": "沒有專案符合你的搜尋字詞。" - }, - "instances.modpack-content-modal.open-in-slicer": { - "defaultMessage": "在 Slicer 中開啟" - }, - "instances.modpack-content-modal.search-placeholder": { - "defaultMessage": "搜尋 {count, number} {count, plural, other {個專案}}" - }, "instances.updater-modal.badge.current": { "defaultMessage": "目前" }, @@ -2240,6 +2198,9 @@ "label.details": { "defaultMessage": "詳細資訊" }, + "label.discover-content": { + "defaultMessage": "探索內容" + }, "label.done": { "defaultMessage": "完成" }, @@ -2318,6 +2279,9 @@ "label.password": { "defaultMessage": "密碼" }, + "label.permissions": { + "defaultMessage": "權限" + }, "label.plan-custom": { "defaultMessage": "自訂" }, @@ -2766,7 +2730,7 @@ "defaultMessage": "由工作人員設為不公開" }, "omorphia.component.copy.action.copy": { - "defaultMessage": "將程式碼複製到剪貼簿" + "defaultMessage": "將代碼複製到剪貼簿" }, "omorphia.component.environment-indicator.label.client": { "defaultMessage": "用戶端" @@ -2849,9 +2813,162 @@ "payment-method.visa": { "defaultMessage": "Visa" }, + "profile.bio.fallback.creator": { + "defaultMessage": "一位 Modrinth 創作者。" + }, + "profile.bio.fallback.user": { + "defaultMessage": "一位 Modrinth 使用者。" + }, + "profile.block-user.admonition-body": { + "defaultMessage": "{username} 將無法向你傳送好友邀請、邀請你加入共用實例,或邀請你加入 Modrinth Hosting 伺服器。" + }, + "profile.block-user.admonition-title": { + "defaultMessage": "確定要封鎖這位使用者嗎?" + }, + "profile.block-user.error-description": { + "defaultMessage": "封鎖使用者時發生錯誤,請再試一次。" + }, + "profile.block-user.error-title": { + "defaultMessage": "無法封鎖使用者" + }, + "profile.block-user.success-description": { + "defaultMessage": "{username} 已被封鎖。" + }, + "profile.block-user.success-title": { + "defaultMessage": "使用者已封鎖" + }, + "profile.block-user.title": { + "defaultMessage": "封鎖 {username}" + }, + "profile.button.analytics": { + "defaultMessage": "檢視使用者數據分析" + }, + "profile.button.billing": { + "defaultMessage": "管理使用者帳務" + }, + "profile.button.block": { + "defaultMessage": "封鎖" + }, + "profile.button.create-collection": { + "defaultMessage": "建立收藏" + }, + "profile.button.create-project": { + "defaultMessage": "建立專案" + }, + "profile.button.info": { + "defaultMessage": "檢視使用者詳細資訊" + }, + "profile.button.manage-projects": { + "defaultMessage": "管理專案" + }, + "profile.button.remove-affiliate": { + "defaultMessage": "移除聯盟行銷夥伴資格" + }, + "profile.button.set-affiliate": { + "defaultMessage": "設為聯盟行銷夥伴" + }, + "profile.button.unblock": { + "defaultMessage": "解除封鎖" + }, + "profile.collection.projects-count": { + "defaultMessage": "{count, plural, other {# 個專案}}" + }, + "profile.details.error.github-popup-blocked": { + "defaultMessage": "請允許 Modrinth 的彈出式視窗,然後再試一次。" + }, + "profile.details.error.github-profile-message": { + "defaultMessage": "無法擷取 GitHub 個人檔案,請再試一次。" + }, + "profile.details.error.github-profile-title": { + "defaultMessage": "無法開啟 GitHub 個人檔案" + }, + "profile.details.label.auth-providers": { + "defaultMessage": "驗證提供商" + }, + "profile.details.label.email-verified": { + "defaultMessage": "電子郵件已驗證" + }, + "profile.details.label.has-password": { + "defaultMessage": "是否有密碼" + }, + "profile.details.label.has-totp": { + "defaultMessage": "是否有 TOTP" + }, + "profile.details.label.loading-github-profile": { + "defaultMessage": "載入中..." + }, + "profile.details.label.payment-methods": { + "defaultMessage": "付款方式" + }, + "profile.details.label.view-github-profile": { + "defaultMessage": "查看個人檔案" + }, + "profile.details.title": { + "defaultMessage": "使用者詳細資訊" + }, + "profile.details.tooltip.email-not-verified": { + "defaultMessage": "電子郵件尚未驗證" + }, + "profile.details.tooltip.email-verified": { + "defaultMessage": "電子郵件已驗證" + }, + "profile.error.load-description": { + "defaultMessage": "無法載入使用者個人檔案。" + }, + "profile.error.not-found": { + "defaultMessage": "找不到使用者" + }, + "profile.label.affiliate": { + "defaultMessage": "聯盟行銷" + }, "profile.label.badges": { "defaultMessage": "徽章" }, + "profile.label.collection": { + "defaultMessage": "收藏" + }, + "profile.label.download-count": { + "defaultMessage": "{count, plural, other {次下載}}" + }, + "profile.label.joined": { + "defaultMessage": "加入時間:" + }, + "profile.label.no-collections": { + "defaultMessage": "這位使用者沒有任何收藏!" + }, + "profile.label.no-collections-auth-description": { + "defaultMessage": "你還沒有任何收藏。" + }, + "profile.label.no-projects": { + "defaultMessage": "這位使用者沒有任何專案!" + }, + "profile.label.no-projects-auth-description": { + "defaultMessage": "你還沒有任何專案。" + }, + "profile.label.organizations": { + "defaultMessage": "組織" + }, + "profile.label.project-count": { + "defaultMessage": "{count, plural, other {個專案}}" + }, + "profile.official-account": { + "defaultMessage": "Modrinth 官方帳號" + }, + "profile.official-account.bio": { + "defaultMessage": "Modrinth 的官方使用者帳號。請至 取得支援,或透過電子郵件 聯絡客服團隊" + }, + "profile.unblock-user.error-description": { + "defaultMessage": "解除封鎖使用者時發生錯誤,請再試一次。" + }, + "profile.unblock-user.error-title": { + "defaultMessage": "無法解除封鎖使用者" + }, + "profile.unblock-user.success-description": { + "defaultMessage": "{username} 已解除封鎖。" + }, + "profile.unblock-user.success-title": { + "defaultMessage": "使用者已解除封鎖" + }, "project-card.date.published.tooltip": { "defaultMessage": "發布時間:{date}" }, @@ -2879,6 +2996,9 @@ "project-type.all": { "defaultMessage": "全部" }, + "project-type.collection.plural": { + "defaultMessage": "收藏" + }, "project-type.datapack.capital": { "defaultMessage": "{count, plural, other {資料包}}" }, @@ -3540,7 +3660,7 @@ "defaultMessage": "成員" }, "project.settings.notice.no-permission.description": { - "defaultMessage": "你沒有編輯這個設定的權限。" + "defaultMessage": "你沒有編輯這項設定的權限。" }, "project.settings.notice.no-permission.title": { "defaultMessage": "沒有權限" @@ -3561,7 +3681,7 @@ "defaultMessage": "版本" }, "project.settings.view.title": { - "defaultMessage": "檢視" + "defaultMessage": "檢視方式" }, "project.stats.downloads-label": { "defaultMessage": "{count, plural, other {次下載}}" @@ -3671,15 +3791,6 @@ "search.filter_type.advanced": { "defaultMessage": "進階篩選" }, - "search.filter_type.advanced.exclude_datapack": { - "defaultMessage": "排除資料包" - }, - "search.filter_type.advanced.exclude_mod": { - "defaultMessage": "排除模組" - }, - "search.filter_type.advanced.exclude_plugin": { - "defaultMessage": "排除插件" - }, "search.filter_type.environment": { "defaultMessage": "環境" }, @@ -4011,7 +4122,7 @@ "defaultMessage": "{seconds} 秒後可重新傳送" }, "servers.access-table.column.actions": { - "defaultMessage": "操作" + "defaultMessage": "動作" }, "servers.access-table.column.joined": { "defaultMessage": "加入時間" @@ -5105,9 +5216,120 @@ "settings.pats.title": { "defaultMessage": "個人存取權杖" }, + "settings.profile.bio.description": { + "defaultMessage": "簡單介紹一下你自己。" + }, + "settings.profile.bio.title": { + "defaultMessage": "關於我" + }, + "settings.profile.navigation-title": { + "defaultMessage": "個人檔案" + }, + "settings.profile.profile-picture.title": { + "defaultMessage": "個人檔案相片" + }, + "settings.profile.public-information.description": { + "defaultMessage": "你的個人檔案資訊會公開顯示在 Modrinth 上,並可透過 Modrinth API 查詢。" + }, + "settings.profile.save-error": { + "defaultMessage": "無法更新個人檔案" + }, + "settings.profile.save-error-description": { + "defaultMessage": "更新個人檔案時發生錯誤,請再試一次。" + }, + "settings.profile.sign-in-required.description": { + "defaultMessage": "登入 Modrinth 帳號即可自訂你的公開個人檔案。" + }, + "settings.profile.sign-in-required.title": { + "defaultMessage": "需要 Modrinth 帳號" + }, + "settings.profile.username.description": { + "defaultMessage": "獨特且不區分大小寫的名稱,用於識別你的個人檔案。" + }, "settings.sessions.title": { "defaultMessage": "工作階段" }, + "settings.social.blocked-users.column.actions": { + "defaultMessage": "動作" + }, + "settings.social.blocked-users.column.user": { + "defaultMessage": "使用者" + }, + "settings.social.blocked-users.description": { + "defaultMessage": "以下是你在 Modrinth 上封鎖的使用者。他們無法:" + }, + "settings.social.blocked-users.empty": { + "defaultMessage": "你沒有封鎖任何使用者。" + }, + "settings.social.blocked-users.load-error": { + "defaultMessage": "無法載入已封鎖的使用者。" + }, + "settings.social.blocked-users.loading": { + "defaultMessage": "正在載入已封鎖的使用者..." + }, + "settings.social.blocked-users.restriction.friend-requests": { + "defaultMessage": "傳送好友邀請給你" + }, + "settings.social.blocked-users.restriction.hosting": { + "defaultMessage": "邀請你管理 Modrinth Hosting 伺服器。" + }, + "settings.social.blocked-users.restriction.shared-instances": { + "defaultMessage": "邀請你加入共用實例" + }, + "settings.social.blocked-users.title": { + "defaultMessage": "封鎖名單" + }, + "settings.social.blocked-users.unblock": { + "defaultMessage": "解除封鎖" + }, + "settings.social.blocked-users.unblock-error": { + "defaultMessage": "無法解除封鎖使用者" + }, + "settings.social.blocked-users.unblock-error-description": { + "defaultMessage": "解除封鎖使用者時發生錯誤,請再試一次。" + }, + "settings.social.blocked-users.unblock-user": { + "defaultMessage": "解除封鎖 {username}" + }, + "settings.social.blocked-users.user-avatar": { + "defaultMessage": "{username} 的顯示圖片" + }, + "settings.social.friend-requests.description": { + "defaultMessage": "控制誰可以在 Modrinth 向你傳送好友邀請。" + }, + "settings.social.friend-requests.title": { + "defaultMessage": "好友邀請" + }, + "settings.social.interaction-source.coming-soon": { + "defaultMessage": "即將推出!" + }, + "settings.social.interaction-source.everyone": { + "defaultMessage": "所有人" + }, + "settings.social.interaction-source.friends": { + "defaultMessage": "好友" + }, + "settings.social.interaction-source.friends-of-friends": { + "defaultMessage": "好友的好友" + }, + "settings.social.interaction-source.no-one": { + "defaultMessage": "沒有人" + }, + "settings.social.shared-instance-invites.description": { + "defaultMessage": "控制誰可以向你傳送共用實例和 Modrinth Hosting 面板的邀請。" + }, + "settings.social.shared-instance-invites.title": { + "defaultMessage": "邀請" + }, + "settings.social.sign-in-required.description": { + "defaultMessage": "你可以透過 Modrinth 帳號控制誰可以與你互動,並管理被封鎖的使用者" + }, + "settings.social.sign-in-required.title": { + "defaultMessage": "需要 Modrinth 帳號" + }, + "settings.social.title": { + "defaultMessage": "社交" + }, "sharing.invite-players-modal.add": { "defaultMessage": "新增" }, @@ -5115,16 +5337,19 @@ "defaultMessage": "已加入" }, "sharing.invite-players-modal.already-invited": { - "defaultMessage": "這個使用者已經被邀請。" + "defaultMessage": "這位使用者已經被邀請。" + }, + "sharing.invite-players-modal.apply-button": { + "defaultMessage": "套用" }, "sharing.invite-players-modal.avatar-alt": { "defaultMessage": "{username} 的顯示圖片" }, - "sharing.invite-players-modal.cancel": { - "defaultMessage": "取消" + "sharing.invite-players-modal.custom-expiry": { + "defaultMessage": "自訂..." }, - "sharing.invite-players-modal.cancel-button": { - "defaultMessage": "取消" + "sharing.invite-players-modal.custom-expiry-value": { + "defaultMessage": "自訂:{date}" }, "sharing.invite-players-modal.edit-invite-link": { "defaultMessage": "編輯邀請連結。" @@ -5132,8 +5357,26 @@ "sharing.invite-players-modal.edit-invite-link-title": { "defaultMessage": "編輯邀請連結" }, + "sharing.invite-players-modal.expiry-in-one-day": { + "defaultMessage": "1 天" + }, + "sharing.invite-players-modal.expiry-in-one-hour": { + "defaultMessage": "1 小時" + }, + "sharing.invite-players-modal.expiry-in-seven-days": { + "defaultMessage": "7 天" + }, + "sharing.invite-players-modal.expiry-in-six-hours": { + "defaultMessage": "6 小時" + }, + "sharing.invite-players-modal.expiry-in-three-days": { + "defaultMessage": "3 天" + }, + "sharing.invite-players-modal.expiry-in-twelve-hours": { + "defaultMessage": "12 小時" + }, "sharing.invite-players-modal.expiry-label": { - "defaultMessage": "有效期限" + "defaultMessage": "有效時間" }, "sharing.invite-players-modal.friends-heading": { "defaultMessage": "你的好友 - {count}" diff --git a/packages/ui/src/providers/content-manager.ts b/packages/ui/src/providers/content-manager.ts index 936ee5ac06..b50e1122d0 100644 --- a/packages/ui/src/providers/content-manager.ts +++ b/packages/ui/src/providers/content-manager.ts @@ -1,7 +1,7 @@ export { type ContentManagerContext, - type ContentModpackData, injectContentManager, + type ManagedContentData, provideContentManager, type UploadState, } from '../layouts/shared/content-tab/providers/content-manager' diff --git a/packages/ui/src/providers/index.ts b/packages/ui/src/providers/index.ts index 9f7801eaf0..d86d8310ff 100644 --- a/packages/ui/src/providers/index.ts +++ b/packages/ui/src/providers/index.ts @@ -18,4 +18,5 @@ export * from './project-page-new' export * from './server-context' export * from './server-settings-modal' export * from './tags' +export * from './user-country' export * from './web-notifications' diff --git a/packages/ui/src/providers/popup-notifications.ts b/packages/ui/src/providers/popup-notifications.ts index 493354cc4a..2c1c545e3b 100644 --- a/packages/ui/src/providers/popup-notifications.ts +++ b/packages/ui/src/providers/popup-notifications.ts @@ -1,4 +1,4 @@ -import type { Component } from 'vue' +import { type Component, type Ref, ref } from 'vue' import { createContext } from '.' @@ -25,7 +25,6 @@ export interface PopupNotificationProgressItem { progressCurrent?: number progressTotal?: number dismissible?: boolean - onDismiss?: () => void | Promise buttons?: PopupNotificationButton[] } @@ -73,15 +72,51 @@ export interface PopupNotification { buttons?: PopupNotificationButton[] toast?: PopupNotificationToast dismissible?: boolean + onDismiss?: () => void | Promise autoCloseMs?: number | null timer?: NodeJS.Timeout } +export interface PopupNotificationDownloadState { + total: number + hidden: number +} + export abstract class AbstractPopupNotificationManager { protected readonly DEFAULT_AUTO_CLOSE_MS = 30 * 1000 + private readonly hiddenDownloadItemKeys: Ref> = ref(new Set()) abstract getNotifications(): PopupNotification[] + getDownloadState = (): PopupNotificationDownloadState => { + const itemKeys = this.getDownloadNotifications().flatMap((notification) => + this.getDownloadItemKeys(notification), + ) + return { + total: itemKeys.length, + hidden: itemKeys.filter((key) => this.hiddenDownloadItemKeys.value.has(key)).length, + } + } + + getVisibleNotifications = (): PopupNotification[] => + this.getNotifications().filter( + (notification) => + !this.isDownloadNotification(notification) || + this.getDownloadItemKeys(notification).some( + (key) => !this.hiddenDownloadItemKeys.value.has(key), + ), + ) + + getVisibleDownloadProgressItems = ( + notification: PopupNotification, + ): PopupNotificationProgressItem[] => + (notification.progressItems ?? []).filter( + (progressItem) => + !this.hiddenDownloadItemKeys.value.has( + this.getDownloadItemKey(notification.id, progressItem.id), + ), + ) + protected abstract addNotificationToStorage(notification: PopupNotification): void protected abstract removeNotificationFromStorage(id: string | number): void protected abstract clearAllNotificationsFromStorage(): void @@ -103,6 +138,9 @@ export abstract class AbstractPopupNotificationManager { const notification = notifications.find((n) => n.id === id) if (notification) { this.clearNotificationTimer(notification) + this.getDownloadItemKeys(notification).forEach((key) => + this.hiddenDownloadItemKeys.value.delete(key), + ) this.removeNotificationFromStorage(id) } } @@ -110,6 +148,45 @@ export abstract class AbstractPopupNotificationManager { clearAllNotifications = (): void => { this.getNotifications().forEach((n) => this.clearNotificationTimer(n)) this.clearAllNotificationsFromStorage() + this.hiddenDownloadItemKeys.value.clear() + } + + hideDownloadItem = (notificationId: string | number, progressItemId: string): void => { + const notification = this.getDownloadNotifications().find( + (candidate) => candidate.id === notificationId, + ) + if (!notification?.progressItems?.some((item) => item.id === progressItemId)) return + + this.hiddenDownloadItemKeys.value.add(this.getDownloadItemKey(notificationId, progressItemId)) + if ( + this.getDownloadItemKeys(notification).every((key) => + this.hiddenDownloadItemKeys.value.has(key), + ) + ) { + this.clearNotificationTimer(notification) + } + } + + toggleDownloadNotifications = (): void => { + const downloadNotifications = this.getDownloadNotifications() + const hasHiddenDownloads = downloadNotifications.some((notification) => + this.getDownloadItemKeys(notification).some((key) => + this.hiddenDownloadItemKeys.value.has(key), + ), + ) + + if (hasHiddenDownloads) { + this.hiddenDownloadItemKeys.value.clear() + downloadNotifications.forEach((notification) => this.setNotificationTimer(notification)) + return + } + + downloadNotifications.forEach((notification) => { + this.getDownloadItemKeys(notification).forEach((key) => + this.hiddenDownloadItemKeys.value.add(key), + ) + this.clearNotificationTimer(notification) + }) } setNotificationTimer = (notification: PopupNotification): void => { @@ -134,6 +211,30 @@ export abstract class AbstractPopupNotificationManager { notification.timer = undefined } } + + private isDownloadNotification(notification: PopupNotification): boolean { + return notification.type === 'download' || notification.toast?.type === 'instance-download' + } + + private getDownloadNotifications(): PopupNotification[] { + return this.getNotifications().filter((notification) => + this.isDownloadNotification(notification), + ) + } + + private getDownloadItemKeys(notification: PopupNotification): string[] { + if (!this.isDownloadNotification(notification)) return [] + if (notification.progressItems?.length) { + return notification.progressItems.map((progressItem) => + this.getDownloadItemKey(notification.id, progressItem.id), + ) + } + return [this.getDownloadItemKey(notification.id)] + } + + private getDownloadItemKey(notificationId: string | number, progressItemId?: string): string { + return JSON.stringify([typeof notificationId, notificationId, progressItemId ?? null]) + } } export const [injectPopupNotificationManager, providePopupNotificationManager] = diff --git a/packages/ui/src/providers/project-page.ts b/packages/ui/src/providers/project-page.ts index c81f83b9fd..dce8569c92 100644 --- a/packages/ui/src/providers/project-page.ts +++ b/packages/ui/src/providers/project-page.ts @@ -15,7 +15,7 @@ export interface ProjectPageContext { allMembers: Ref organization: Ref // Lazy version loading (client-side only) - versions: Ref + versions: Ref versionsLoading: Ref versionsLoaded: Ref // Lazy dependencies loading (client-side only) diff --git a/packages/ui/src/providers/user-country.ts b/packages/ui/src/providers/user-country.ts new file mode 100644 index 0000000000..a0100e0dc8 --- /dev/null +++ b/packages/ui/src/providers/user-country.ts @@ -0,0 +1,28 @@ +import { setMarkdownUserCountryResolver } from '@modrinth/utils' +import type { Ref } from 'vue' +import { hasInjectionContext } from 'vue' + +import { createContext } from './create-context' + +const [injectUserCountryContext, provideUserCountryContext] = createContext>( + 'root', + 'userCountry', +) + +let clientCountry: Ref | null = null + +export const injectUserCountry = injectUserCountryContext +export const useUserCountry = injectUserCountryContext + +export function provideUserCountry(country: Ref) { + if (typeof window !== 'undefined') { + clientCountry = country + } + + return provideUserCountryContext(country) +} + +setMarkdownUserCountryResolver(() => { + const injectedCountry = hasInjectionContext() ? injectUserCountryContext(null) : null + return injectedCountry?.value ?? clientCountry?.value +}) diff --git a/packages/ui/src/stories/add-stories.md b/packages/ui/src/stories/add-stories.md index 19f83c3ba9..2132d4f14c 100644 --- a/packages/ui/src/stories/add-stories.md +++ b/packages/ui/src/stories/add-stories.md @@ -153,16 +153,14 @@ For components that need user interaction to show: ```typescript export const Default: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { Button, NewModal }, setup() { const modalRef = ref | null>(null) return { modalRef } }, template: /* html */ `
- - - +

Modal content

@@ -199,10 +197,10 @@ Components should use relative imports, not the package alias: ```typescript // ❌ BAD - Causes circular dependency in Storybook -import { ButtonStyled } from '@modrinth/ui' +import { Button } from '@modrinth/ui' // ✅ GOOD - Use relative imports -import ButtonStyled from '../base/ButtonStyled.vue' +import Button from '../components/base/buttons/Button.vue' ``` ### 2. Object/Array Prop Defaults Must Be Factory Functions diff --git a/packages/ui/src/stories/base/Admonition.stories.ts b/packages/ui/src/stories/base/Admonition.stories.ts index 413e2a1b6d..bcd6894084 100644 --- a/packages/ui/src/stories/base/Admonition.stories.ts +++ b/packages/ui/src/stories/base/Admonition.stories.ts @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite' import { ref } from 'vue' import Admonition from '../../components/base/Admonition.vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { Button } from '../../components/base/buttons' const meta = { title: 'Base/Admonition', @@ -78,7 +78,7 @@ export const HeaderWithTimestamp: Story = { export const WithTopRightActions: Story = { render: () => ({ - components: { Admonition, ButtonStyled }, + components: { Admonition, Button }, template: /*html*/ `
Uploading server files... Something went wrong while extracting the archive. @@ -115,7 +111,7 @@ export const WithTopRightActions: Story = { export const WithProgressBar: Story = { render: () => ({ - components: { Admonition, ButtonStyled }, + components: { Admonition, Button }, template: /*html*/ `
128 KB / 1.2 MB (45%) 24 MB extracted — config/settings.yml ({ - components: { Button }, - setup() { - return { args } - }, - template: /*html*/ ` - - `, - }), -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Default: Story = {} - -export const Primary: Story = { - args: { - color: 'primary', - }, -} - -export const Danger: Story = { - args: { - color: 'danger', - }, -} - -export const AllColors: Story = { - render: () => ({ - components: { Button }, - template: /*html*/ ` -
- - - - - - - - -
- `, - }), -} - -export const Large: Story = { - args: { - large: true, - }, -} - -export const Outline: Story = { - args: { - outline: true, - }, -} - -export const Transparent: Story = { - args: { - transparent: true, - }, -} - -export const Disabled: Story = { - args: { - disabled: true, - }, -} - -export const AsLink: Story = { - args: { - link: 'https://modrinth.com', - external: true, - }, -} diff --git a/packages/ui/src/stories/base/ButtonStyled.stories.ts b/packages/ui/src/stories/base/ButtonStyled.stories.ts deleted file mode 100644 index 852ceab118..0000000000 --- a/packages/ui/src/stories/base/ButtonStyled.stories.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { DownloadIcon, HeartIcon, SettingsIcon } from '@modrinth/assets' -import type { Meta, StoryObj } from '@storybook/vue3-vite' - -import ButtonStyled from '../../components/base/ButtonStyled.vue' - -const colors = ['standard', 'brand', 'red', 'orange', 'green', 'blue', 'purple'] as const -const types = [ - 'standard', - 'outlined', - 'transparent', - 'highlight', - 'highlight-colored-text', - 'chip', -] as const -const sizes = ['small', 'standard', 'large'] as const - -const meta = { - title: 'Base/ButtonStyled', - component: ButtonStyled, - argTypes: { - color: { - control: 'select', - options: [...colors, 'medal-promo'], - }, - size: { - control: 'select', - options: [...sizes], - }, - type: { - control: 'select', - options: [...types], - }, - circular: { control: 'boolean' }, - colorFill: { - control: 'select', - options: ['auto', 'background', 'text', 'none'], - }, - hoverColorFill: { - control: 'select', - options: ['auto', 'background', 'text', 'none'], - }, - highlighted: { control: 'boolean' }, - highlightedStyle: { - control: 'select', - options: ['main-nav-primary', 'main-nav-secondary'], - }, - }, - args: { - color: 'standard', - size: 'standard', - type: 'standard', - circular: false, - colorFill: 'auto', - hoverColorFill: 'auto', - highlighted: false, - highlightedStyle: 'main-nav-primary', - }, - render: (args) => ({ - components: { ButtonStyled, DownloadIcon }, - setup() { - return { args } - }, - template: /*html*/ ` - - - - `, - }), -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Default: Story = { - args: { - type: 'standard', - }, -} - -export const AllVariants: Story = { - render: () => ({ - components: { ButtonStyled }, - setup() { - return { colors, types } - }, - template: /*html*/ ` -
- - - - - - - - - - - - - -
Color / Type{{ type }}
{{ color }} - - - -
-
- `, - }), -} - -export const AllVariantsHighlighted: Story = { - render: () => ({ - components: { ButtonStyled }, - setup() { - return { colors, types } - }, - template: /*html*/ ` -
- - - - - - - - - - - - - -
Color / Type{{ type }}
{{ color }} - - - -
-
- `, - }), -} - -export const Sizes: Story = { - render: () => ({ - components: { ButtonStyled }, - setup() { - return { sizes, types } - }, - template: /*html*/ ` -
- - - - - - - - - - - - - -
Size / Type{{ type }}
{{ size }} - - - -
-
- `, - }), -} - -export const WithIcons: Story = { - render: () => ({ - components: { ButtonStyled, DownloadIcon, HeartIcon, SettingsIcon }, - setup() { - return { types } - }, - template: /*html*/ ` -
- - - - - - - - - - - - - - - - - -
Variant{{ type }}
Icon + text - - - -
Icon only - - - -
-
- `, - }), -} - -export const Disabled: Story = { - render: () => ({ - components: { ButtonStyled }, - setup() { - return { types } - }, - template: /*html*/ ` -
- - - -
- `, - }), -} diff --git a/packages/ui/src/stories/base/EmptyState.stories.ts b/packages/ui/src/stories/base/EmptyState.stories.ts index f698148b9b..8fa5be7f23 100644 --- a/packages/ui/src/stories/base/EmptyState.stories.ts +++ b/packages/ui/src/stories/base/EmptyState.stories.ts @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { Button } from '../../components/base/buttons' import EmptyState from '../../components/base/EmptyState.vue' const meta = { @@ -42,7 +42,7 @@ export const Default: Story = { export const WithActions: StoryObj = { render: () => ({ - components: { EmptyState, ButtonStyled }, + components: { EmptyState, Button }, template: /*html*/ ` `, diff --git a/packages/ui/src/stories/base/FileTreeSelect.stories.ts b/packages/ui/src/stories/base/FileTreeSelect.stories.ts index a85d13ab5e..acaf6eb8e4 100644 --- a/packages/ui/src/stories/base/FileTreeSelect.stories.ts +++ b/packages/ui/src/stories/base/FileTreeSelect.stories.ts @@ -39,30 +39,37 @@ export const ModpackExport: StoryObj = { render: () => ({ components: { FileTreeSelect }, setup() { - const selected = ref([ - 'config/fabric_loader_dependencies.json', - 'config/crash_assistant/settings.toml', - 'config/defaultoptions/options.txt', - 'mods/sodium-fabric-0.6.13+mc1.21.6.jar', - 'mods/iris-fabric-1.8.8+mc1.21.6.jar', - 'resourcepacks/FreshAnimations_v1.9.3.zip', - 'shaderpacks/ComplementaryUnbound_r5.5.1.zip', - ]) - const selectedLabel = computed(() => `${selected.value.length} selected`) + const included = ref(['config', 'mods']) + const excluded = ref(['config/defaultoptions']) + const selectedLabel = computed( + () => `${included.value.length} includes, ${excluded.value.length} exclusions`, + ) return { + excluded, + included, items: MODPACK_FILES, - selected, selectedLabel, } }, template: /*html*/ `
- +
{{ selectedLabel }}
-
- {{ path }} +
+
+ Included + {{ path }} +
+
+ Excluded + {{ path }} +
@@ -74,12 +81,17 @@ export const EmptyRoot: StoryObj = { render: () => ({ components: { FileTreeSelect }, setup() { - const selected = ref([]) - return { selected } + const excluded = ref([]) + const included = ref([]) + return { excluded, included } }, template: /*html*/ `
- +
`, }), diff --git a/packages/ui/src/stories/base/JoinedButtons.stories.ts b/packages/ui/src/stories/base/JoinedButtons.stories.ts deleted file mode 100644 index c007e3631d..0000000000 --- a/packages/ui/src/stories/base/JoinedButtons.stories.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { PlayIcon, SlashIcon, StopCircleIcon, UpdatedIcon } from '@modrinth/assets' -import type { Meta, StoryObj } from '@storybook/vue3-vite' - -import JoinedButtons from '../../components/base/JoinedButtons.vue' - -const meta = { - title: 'Base/JoinedButtons', - component: JoinedButtons, - argTypes: { - color: { - control: 'select', - options: ['standard', 'brand', 'red', 'orange', 'green', 'blue', 'purple'], - }, - size: { - control: 'select', - options: ['small', 'standard', 'large'], - }, - disabled: { control: 'boolean' }, - primaryDisabled: { control: 'boolean' }, - dropdownDisabled: { control: 'boolean' }, - primaryMuted: { control: 'boolean' }, - }, -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Start: Story = { - args: { - color: 'brand', - size: 'large', - actions: [ - { - id: 'start', - label: 'Start', - icon: PlayIcon, - action: () => console.log('Start'), - }, - ], - }, -} - -export const StopWithKill: Story = { - args: { - color: 'red', - size: 'large', - actions: [ - { - id: 'stop', - label: 'Stop', - icon: StopCircleIcon, - action: () => console.log('Stop'), - }, - { - id: 'kill_server', - label: 'Kill server', - icon: SlashIcon, - action: () => console.log('Kill'), - }, - ], - }, -} - -export const Stopping: Story = { - args: { - color: 'red', - size: 'large', - primaryDisabled: true, - primaryMuted: true, - actions: [ - { - id: 'stop', - label: 'Stopping', - icon: StopCircleIcon, - action: () => console.log('Stop'), - }, - { - id: 'kill_server', - label: 'Kill server', - icon: SlashIcon, - action: () => console.log('Kill'), - }, - ], - }, -} - -export const Restart: Story = { - args: { - color: 'orange', - size: 'large', - actions: [ - { - id: 'restart', - label: 'Restart', - icon: UpdatedIcon, - action: () => console.log('Restart'), - }, - ], - }, -} - -export const Disabled: Story = { - args: { - color: 'red', - size: 'large', - disabled: true, - actions: [ - { - id: 'stop', - label: 'Stop', - icon: StopCircleIcon, - action: () => console.log('Stop'), - }, - { - id: 'kill_server', - label: 'Kill server', - icon: SlashIcon, - action: () => console.log('Kill'), - }, - ], - }, -} diff --git a/packages/ui/src/stories/base/OverflowMenu.stories.ts b/packages/ui/src/stories/base/OverflowMenu.stories.ts deleted file mode 100644 index 0adec75cf2..0000000000 --- a/packages/ui/src/stories/base/OverflowMenu.stories.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { MoreHorizontalIcon } from '@modrinth/assets' -import type { Meta, StoryObj } from '@storybook/vue3-vite' - -import ButtonStyled from '../../components/base/ButtonStyled.vue' -import OverflowMenu from '../../components/base/OverflowMenu.vue' - -const meta = { - title: 'Base/OverflowMenu', - component: OverflowMenu, - render: (args) => ({ - components: { OverflowMenu, MoreHorizontalIcon, ButtonStyled }, - setup() { - return { args } - }, - template: /*html*/ ` - - - - - - - - - `, - }), -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Default: Story = { - args: { - options: [ - { id: 'edit', action: () => console.log('Edit clicked') }, - { id: 'share', action: () => console.log('Share clicked') }, - { divider: true }, - { id: 'delete', action: () => console.log('Delete clicked'), color: 'danger' }, - ], - }, -} - -export const WithDifferentPlacements: StoryObj = { - render: () => ({ - components: { OverflowMenu, MoreHorizontalIcon, ButtonStyled }, - template: /*html*/ ` -
-
- bottom-end (default) - - - - - - - -
-
- bottom-start - - - - - - - -
-
- `, - }), -} diff --git a/packages/ui/src/stories/base/PageHeader.stories.ts b/packages/ui/src/stories/base/PageHeader.stories.ts index 73ad628820..a8344567da 100644 --- a/packages/ui/src/stories/base/PageHeader.stories.ts +++ b/packages/ui/src/stories/base/PageHeader.stories.ts @@ -20,9 +20,13 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite' import AutoLink from '../../components/base/AutoLink.vue' import Avatar from '../../components/base/Avatar.vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { + Button, + IconButton, + SplitButton, + TeleportOverflowMenu, +} from '../../components/base/buttons' import FormattedTag from '../../components/base/FormattedTag.vue' -import JoinedButtons from '../../components/base/JoinedButtons.vue' import PageHeader from '../../components/base/page-header/index.vue' import PageHeaderMetadata from '../../components/base/page-header/metadata/index.vue' import PageHeaderMetadataItem from '../../components/base/page-header/metadata/page-header-metadata-item.vue' @@ -31,9 +35,8 @@ import PageHeaderMetadataTagsItem from '../../components/base/page-header/metada import PageHeaderMetadataTimeItem from '../../components/base/page-header/metadata/page-header-metadata-time-item.vue' import PageHeaderActions from '../../components/base/page-header/page-header-actions.vue' import PageHeaderBadgeItem from '../../components/base/page-header/page-header-badge-item.vue' +import TagIcon from '../../components/base/TagIcon.vue' import TagItem from '../../components/base/TagItem.vue' -import TeleportOverflowMenu from '../../components/base/TeleportOverflowMenu.vue' -import LoaderIcon from '../../components/servers/icons/LoaderIcon.vue' import ServerIcon from '../../components/servers/icons/ServerIcon.vue' const noop = () => undefined @@ -87,9 +90,10 @@ const pageHeaderIcons = { const pageHeaderComponents = { AutoLink, Avatar, - ButtonStyled, + Button, FormattedTag, - JoinedButtons, + IconButton, + SplitButton, PageHeader, PageHeaderActions, PageHeaderBadgeItem, @@ -111,7 +115,7 @@ const meta = { }, decorators: [ (story) => ({ - components: { story }, + components: { story, TeleportOverflowMenu }, template: '
', }), ], @@ -157,17 +161,13 @@ export const ProjectHeader: Story = { @@ -207,12 +207,10 @@ export const CreatorHeader: Story = { @@ -222,14 +220,11 @@ export const CreatorHeader: Story = { export const AppInstanceHeader: Story = { render: () => ({ - components: { - ...pageHeaderComponents, - LoaderIcon, - }, + components: { ...pageHeaderComponents, TagIcon, TeleportOverflowMenu }, setup() { return { ...pageHeaderIcons, - LoaderIcon, + TagIcon, menuActions, noop, } @@ -243,7 +238,7 @@ export const AppInstanceHeader: Story = { @@ -397,7 +394,7 @@ export const WithHeaderSlot: StoryObj = { export const WithActionsColumn: StoryObj = { args: {}, render: () => ({ - components: { Table, ButtonStyled, EditIcon, TrashIcon }, + components: { Table, EditIcon, TrashIcon, Button, TeleportOverflowMenu }, setup() { const columns = [ { key: 'name', label: 'Name' }, @@ -421,18 +418,14 @@ export const WithActionsColumn: StoryObj = {
@@ -443,7 +436,7 @@ export const WithActionsColumn: StoryObj = { export const WithLocalizedActionsColumn: StoryObj = { args: {}, render: () => ({ - components: { Table, ButtonStyled, EditIcon, TrashIcon }, + components: { Table, EditIcon, TrashIcon, Button, TeleportOverflowMenu }, setup() { const columns = [ { key: 'name', label: 'Nombre' }, @@ -467,18 +460,14 @@ export const WithLocalizedActionsColumn: StoryObj = {
@@ -489,7 +478,7 @@ export const WithLocalizedActionsColumn: StoryObj = { export const FullFeatured: StoryObj = { args: {}, render: () => ({ - components: { Table, Badge, ButtonStyled, EditIcon, TrashIcon }, + components: { Table, Badge, EditIcon, TrashIcon, Button, TeleportOverflowMenu }, setup() { const columns = [ { key: 'name', label: 'Name', enableSorting: true }, @@ -565,18 +554,14 @@ export const FullFeatured: StoryObj = { @@ -592,7 +577,7 @@ export const FullFeatured: StoryObj = { export const VirtualizedLargeData: StoryObj = { args: {}, render: () => ({ - components: { Table, Badge }, + components: { Table, Badge, TeleportOverflowMenu }, setup() { const columns = [ { key: 'name', label: 'Name', enableSorting: true }, @@ -710,7 +695,15 @@ export const VirtualizedLargeData: StoryObj = { export const WithOverflowMenu: StoryObj = { args: {}, render: () => ({ - components: { Table, Badge, ButtonStyled, OverflowMenu, MoreVerticalIcon, EditIcon, TrashIcon }, + components: { + Table, + Badge, + MoreVerticalIcon, + EditIcon, + TrashIcon, + Button, + TeleportOverflowMenu, + }, setup() { const columns = [ { key: 'name', label: 'Name' }, @@ -737,17 +730,19 @@ export const WithOverflowMenu: StoryObj = { const getMenuOptions = (row: User) => [ { id: 'edit', + label: 'Edit', action: () => alert(`Edit user: ${row.name}`), }, { id: 'duplicate', + label: 'Duplicate', action: () => alert(`Duplicate user: ${row.name}`), }, - { divider: true }, + { type: 'divider' }, { id: 'delete', - color: 'red' as const, - hoverFilled: true, + label: 'Delete', + tone: 'red', action: () => alert(`Delete user: ${row.name}`), }, ] @@ -766,26 +761,23 @@ export const WithOverflowMenu: StoryObj = { @@ -796,7 +788,7 @@ export const WithOverflowMenu: StoryObj = { export const EmptyState: StoryObj = { args: {}, render: () => ({ - components: { Table }, + components: { Table, TeleportOverflowMenu }, setup() { const columns = [ { key: 'name', label: 'Name' }, diff --git a/packages/ui/src/stories/buttons/Button.stories.ts b/packages/ui/src/stories/buttons/Button.stories.ts new file mode 100644 index 0000000000..85bfe95332 --- /dev/null +++ b/packages/ui/src/stories/buttons/Button.stories.ts @@ -0,0 +1,213 @@ +import { DownloadIcon, ExternalIcon, HeartIcon, SettingsIcon } from '@modrinth/assets' +import type { Meta, StoryObj } from '@storybook/vue3-vite' + +import Button from '../../components/base/buttons/Button.vue' +import ButtonLink from '../../components/base/buttons/ButtonLink.vue' +import IconButton from '../../components/base/buttons/IconButton.vue' + +const types = ['base', 'colored', 'outlined', 'quiet'] as const +const sizes = ['sm', 'md', 'lg', 'xl'] as const +const colors = ['brand', 'red', 'orange', 'green', 'blue', 'purple', 'medal_promotion'] as const +const sizeColumns = [ + { value: 'sm', label: 'Small' }, + { value: 'md', label: 'Medium' }, + { value: 'lg', label: 'Large' }, + { value: 'xl', label: 'Extra large' }, +] as const +const typeRows = [ + { label: 'Base', type: 'base' }, + { label: 'Outlined', type: 'outlined' }, + { label: 'Quiet', type: 'quiet' }, + ...colors.map((color) => ({ + label: `Colored / ${color.charAt(0).toUpperCase()}${color.slice(1)}`, + type: 'colored' as const, + color, + })), + ...colors.map((color) => ({ + label: `Outlined / ${color.charAt(0).toUpperCase()}${color.slice(1)}`, + type: 'outlined' as const, + color, + })), + ...colors.map((color) => ({ + label: `Quiet / ${color.charAt(0).toUpperCase()}${color.slice(1)}`, + type: 'quiet' as const, + color, + })), +] + +const meta = { + title: 'Buttons/Button', + component: Button, + argTypes: { + type: { + control: 'select', + options: types, + }, + size: { + control: 'select', + options: sizes, + }, + color: { + control: 'select', + options: colors, + }, + nativeType: { + control: 'select', + options: ['button', 'submit', 'reset'], + }, + disabled: { control: 'boolean' }, + loading: { control: 'boolean' }, + }, + args: { + type: 'base', + size: 'md', + color: 'brand', + nativeType: 'button', + disabled: false, + loading: false, + }, + render: (args) => ({ + components: { Button, DownloadIcon }, + setup() { + return { args } + }, + template: /*html*/ ` + + `, + }), +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Playground: Story = {} + +export const AllTypes: Story = { + render: () => ({ + components: { Button, DownloadIcon }, + setup() { + return { sizeColumns, typeRows } + }, + template: /*html*/ ` +
+
+
+ {{ size.label }} +
+ + +
+ `, + }), +} + +export const Quiet: Story = { + render: () => ({ + components: { Button, DownloadIcon, IconButton, SettingsIcon }, + template: /*html*/ ` +
+ + + +
+ `, + }), +} + +export const Sizes: Story = { + render: () => ({ + components: { Button, DownloadIcon, IconButton }, + setup() { + return { sizes } + }, + template: /*html*/ ` +
+ +
+ `, + }), +} + +export const Colors: Story = { + render: () => ({ + components: { Button }, + setup() { + return { colors } + }, + template: /*html*/ ` +
+ +
+ `, + }), +} + +export const Content: Story = { + render: () => ({ + components: { Button, DownloadIcon, SettingsIcon }, + template: /*html*/ ` +
+ + + + + +
+ `, + }), +} + +export const InteractionStates: Story = { + render: () => ({ + components: { Button }, + template: /*html*/ ` +
+ + + + + + + +
+ `, + }), +} + +export const LinksAndIconButton: Story = { + render: () => ({ + components: { ButtonLink, ExternalIcon, HeartIcon, IconButton }, + template: /*html*/ ` +
+ Internal link + + Modrinth + + Disabled link + + + + +
+ `, + }), +} diff --git a/packages/ui/src/stories/buttons/ButtonGroup.stories.ts b/packages/ui/src/stories/buttons/ButtonGroup.stories.ts new file mode 100644 index 0000000000..3f234148c4 --- /dev/null +++ b/packages/ui/src/stories/buttons/ButtonGroup.stories.ts @@ -0,0 +1,82 @@ +import { PlayIcon, SettingsIcon, StopCircleIcon, TrashIcon } from '@modrinth/assets' +import type { Meta, StoryObj } from '@storybook/vue3-vite' + +import Button from '../../components/base/buttons/Button.vue' +import ButtonGroup from '../../components/base/buttons/ButtonGroup.vue' +import SplitButton from '../../components/base/buttons/SplitButton.vue' +import type { OverflowMenuOption } from '../../components/base/buttons/types' + +const splitOptions: OverflowMenuOption[] = [ + { + id: 'settings', + label: 'Server settings', + icon: SettingsIcon, + action: () => undefined, + }, + { type: 'divider' }, + { + id: 'delete', + label: 'Delete server', + icon: TrashIcon, + tone: 'red', + action: () => undefined, + }, +] + +const meta = { + title: 'Buttons/Button Group', + component: ButtonGroup, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Joined: Story = { + render: () => ({ + components: { Button, ButtonGroup }, + template: /*html*/ ` + + + + + `, + }), +} + +export const Split: Story = { + render: () => ({ + components: { PlayIcon, SplitButton }, + setup() { + return { splitOptions } + }, + template: /*html*/ ` + + Start server + + `, + }), +} + +export const IndependentDisabledStates: Story = { + render: () => ({ + components: { SplitButton, StopCircleIcon }, + setup() { + return { splitOptions } + }, + template: /*html*/ ` +
+ + Primary disabled + + + Menu disabled + +
+ `, + }), +} diff --git a/packages/ui/src/stories/buttons/FileButton.stories.ts b/packages/ui/src/stories/buttons/FileButton.stories.ts new file mode 100644 index 0000000000..2f07b27acc --- /dev/null +++ b/packages/ui/src/stories/buttons/FileButton.stories.ts @@ -0,0 +1,61 @@ +import { UploadIcon } from '@modrinth/assets' +import type { Meta, StoryObj } from '@storybook/vue3-vite' + +import FileButton from '../../components/base/buttons/FileButton.vue' + +const meta = { + title: 'Buttons/File Button', + component: FileButton, + argTypes: { + type: { + control: 'select', + options: ['base', 'colored', 'outlined', 'quiet'], + }, + size: { + control: 'select', + options: ['sm', 'md', 'lg', 'xl'], + }, + color: { + control: 'select', + options: ['brand', 'red', 'orange', 'green', 'blue', 'purple', 'medal_promotion'], + }, + }, + args: { + prompt: 'Select file', + type: 'base', + size: 'md', + multiple: false, + disabled: false, + }, + render: (args) => ({ + components: { FileButton, UploadIcon }, + setup() { + return { args } + }, + template: /*html*/ ` + + + + `, + }), +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = {} + +export const MultipleImages: Story = { + args: { + prompt: 'Select images', + accept: 'image/*', + multiple: true, + type: 'colored', + }, +} + +export const Disabled: Story = { + args: { + disabled: true, + }, +} diff --git a/packages/ui/src/stories/buttons/TeleportOverflowMenu.stories.ts b/packages/ui/src/stories/buttons/TeleportOverflowMenu.stories.ts new file mode 100644 index 0000000000..5ed21392f1 --- /dev/null +++ b/packages/ui/src/stories/buttons/TeleportOverflowMenu.stories.ts @@ -0,0 +1,104 @@ +import { + DownloadIcon, + ExternalIcon, + MoreVerticalIcon, + SettingsIcon, + TrashIcon, +} from '@modrinth/assets' +import type { Meta, StoryObj } from '@storybook/vue3-vite' + +import TeleportOverflowMenu from '../../components/base/buttons/TeleportOverflowMenu.vue' +import type { OverflowMenuOption } from '../../components/base/buttons/types' + +const options: OverflowMenuOption[] = [ + { + id: 'download', + label: 'Download', + icon: DownloadIcon, + action: () => undefined, + }, + { + id: 'settings', + label: 'Project settings', + icon: SettingsIcon, + type: 'link', + to: '/settings', + }, + { + id: 'website', + label: 'Open website', + icon: ExternalIcon, + type: 'link', + href: 'https://modrinth.com', + target: '_blank', + }, + { + id: 'unavailable', + label: 'Unavailable action', + disabled: true, + tooltip: 'This action is currently unavailable', + action: () => undefined, + }, + { type: 'divider' }, + { + id: 'delete', + label: 'Delete project', + icon: TrashIcon, + tone: 'red', + action: () => undefined, + }, +] + +const meta = { + title: 'Buttons/Teleport Overflow Menu', + component: TeleportOverflowMenu, + args: { + label: 'More actions', + options, + type: 'base', + size: 'md', + placement: 'bottom-end', + disabled: false, + hoverable: false, + }, + render: (args) => ({ + components: { MoreVerticalIcon, TeleportOverflowMenu }, + setup() { + return { args } + }, + template: /*html*/ ` + + + + `, + }), +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = {} + +export const ColoredTrigger: Story = { + args: { + type: 'colored', + }, +} + +export const OutlinedTrigger: Story = { + args: { + type: 'outlined', + }, +} + +export const QuietTrigger: Story = { + args: { + type: 'quiet', + }, +} + +export const Hoverable: Story = { + args: { + hoverable: true, + }, +} diff --git a/packages/ui/src/stories/buttons/TeleportPopoutMenu.stories.ts b/packages/ui/src/stories/buttons/TeleportPopoutMenu.stories.ts new file mode 100644 index 0000000000..d6b183197c --- /dev/null +++ b/packages/ui/src/stories/buttons/TeleportPopoutMenu.stories.ts @@ -0,0 +1,50 @@ +import { SettingsIcon } from '@modrinth/assets' +import type { Meta, StoryObj } from '@storybook/vue3-vite' + +import Button from '../../components/base/buttons/Button.vue' +import TeleportPopoutMenu from '../../components/base/buttons/TeleportPopoutMenu.vue' + +const meta = { + title: 'Buttons/Teleport Popout Menu', + component: TeleportPopoutMenu, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const ArbitraryContent: Story = { + render: () => ({ + components: { Button, SettingsIcon, TeleportPopoutMenu }, + template: /*html*/ ` + + + + + + `, + }), +} + +export const IconTrigger: Story = { + render: () => ({ + components: { SettingsIcon, TeleportPopoutMenu }, + template: /*html*/ ` + + + + + `, + }), +} diff --git a/packages/ui/src/stories/instances/ContentCardTable.stories.ts b/packages/ui/src/stories/instances/ContentCardTable.stories.ts index 486a4c909e..ca6ab56abf 100644 --- a/packages/ui/src/stories/instances/ContentCardTable.stories.ts +++ b/packages/ui/src/stories/instances/ContentCardTable.stories.ts @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite' import { fn } from 'storybook/test' import { onMounted, onUnmounted, ref } from 'vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { Button, IconButton } from '../../components/base/buttons' import ContentCardTable from '../../layouts/shared/content-tab/components/ContentCardTable.vue' import type { ContentCardTableItem } from '../../layouts/shared/content-tab/types' @@ -119,6 +119,7 @@ const etfItem: ContentCardTableItem = { const importedModItem: ContentCardTableItem = { id: 'imported123', + external: true, project: { id: 'imported123', slug: 'import-mod', @@ -539,7 +540,7 @@ export const InteractiveActions: Story = { export const WithCustomItemButtons: Story = { render: () => ({ - components: { ContentCardTable, ButtonStyled, EyeIcon, FolderOpenIcon, DownloadIcon }, + components: { ContentCardTable, EyeIcon, FolderOpenIcon, DownloadIcon, Button, IconButton }, setup() { return { items: sampleItems } }, @@ -551,23 +552,17 @@ export const WithCustomItemButtons: Story = { @delete="(id) => console.log('Delete', id)" > `, @@ -582,15 +577,13 @@ export const WithEmptyState: Story = { export const WithCustomEmptyState: Story = { render: () => ({ - components: { ContentCardTable, ButtonStyled }, + components: { ContentCardTable, Button, IconButton }, template: /*html*/ ` @@ -781,7 +774,7 @@ export const WithOverflowMenu: Story = { export const BulkActionsDemo: Story = { render: () => ({ - components: { ContentCardTable, ButtonStyled }, + components: { ContentCardTable, Button, IconButton }, setup() { const items = ref([ { ...sodiumItem, enabled: true }, @@ -825,15 +818,9 @@ export const BulkActionsDemo: Story = {
{{ selectedIds.length }} selected
export const InstanceDependency: Story = { render: () => ({ - components: { ButtonStyled, ContentDependencyWarningModal }, + components: { ContentDependencyWarningModal, Button }, setup() { const modalRef = ref | null>(null) const deleted = ref(false) @@ -186,9 +186,7 @@ export const InstanceDependency: Story = { }, template: /* html */ `
- - - +

Dependency deletion confirmed

({ - components: { ButtonStyled, ContentDependencyWarningModal }, + components: { ContentDependencyWarningModal, Button }, setup() { const modalRef = ref | null>(null) const deleted = ref(false) @@ -227,9 +225,7 @@ export const ServerDependency: Story = { }, template: /* html */ `
- - - +

Server dependency deletion confirmed

({ - components: { ButtonStyled, ContentDependencyWarningModal }, + components: { ContentDependencyWarningModal, Button }, setup() { const modalRef = ref | null>(null) const deleted = ref(false) @@ -267,9 +263,7 @@ export const BulkDependencies: Story = { }, template: /* html */ `
- - - +

Bulk dependency deletion confirmed

- -export default meta -type Story = StoryObj - -// ============================================ -// All Types Overview -// ============================================ - -export const AllTypes: Story = { - args: { - project: fabulouslyOptimizedProject, - }, - render: () => ({ - components: { ContentModpackCard }, - setup() { - const cards = [ - { - label: 'Full featured (all actions)', - project: fabulouslyOptimizedProject, - version: fabulouslyOptimizedVersion, - owner: userOwner, - categories: optimizationCategories, - hasUpdate: true, - hasContent: true, - hasUnlink: true, - }, - { - label: 'With update available only', - project: cobblemonProject, - version: cobblemonVersion, - owner: cobblemonOwner, - categories: cobblemonCategories, - hasUpdate: true, - }, - { - label: 'With content button only', - project: simplyOptimizedProject, - version: fabulouslyOptimizedVersion, - owner: userOwner, - hasContent: true, - }, - { - label: 'Minimal (project only)', - project: fabulouslyOptimizedProject, - }, - { - label: 'With version info only', - project: cobblemonProject, - version: cobblemonVersion, - }, - { - label: 'With owner only', - project: simplyOptimizedProject, - owner: userOwner, - }, - { - label: 'Disabled state', - project: fabulouslyOptimizedProject, - version: fabulouslyOptimizedVersion, - owner: userOwner, - categories: optimizationCategories, - disabled: true, - }, - ] - - return { cards } - }, - template: /*html*/ ` -
- -
- `, - }), -} - -// ============================================ -// Basic Stories -// ============================================ - -export const Default: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - onUpdate: fn(), - onContent: fn(), - onUnlink: fn(), - }, -} - -export const MinimalProjectOnly: Story = { - args: { - project: cobblemonProject, - }, -} - -export const WithVersion: Story = { - args: { - project: simplyOptimizedProject, - version: fabulouslyOptimizedVersion, - }, -} - -export const WithUserOwner: Story = { - args: { - project: simplyOptimizedProject, - version: fabulouslyOptimizedVersion, - owner: userOwner, - categories: [ - { name: 'Adventure', icon: 'adventure', project_type: 'modpack', header: 'categories' }, - ], - }, -} - -export const WithOrganizationOwner: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - }, -} - -// ============================================ -// Action Button Stories -// ============================================ - -export const WithUpdateButton: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - onUpdate: fn(), - }, -} - -export const WithContentButton: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - onContent: fn(), - }, -} - -export const WithUnlinkButton: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - onUnlink: fn(), - }, -} - -export const WithAllActions: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - onUpdate: fn(), - onContent: fn(), - onUnlink: fn(), - overflowOptions: [ - { id: 'view', action: () => console.log('View') }, - { id: 'settings', action: () => console.log('Settings') }, - { divider: true }, - { id: 'remove', action: () => console.log('Remove'), color: 'red' }, - ], - }, -} - -// ============================================ -// State Stories -// ============================================ - -export const Disabled: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - disabled: true, - }, -} - -export const LongTitle: Story = { - args: { - project: { - ...cobblemonProject, - title: 'Super Long Modpack Title That Should Display Properly On All Screen Sizes', - description: - 'This is an extremely long description that should wrap properly and not break the layout. It contains lots of information about what this modpack includes and what makes it special compared to other modpacks available on the platform.', - }, - version: cobblemonVersion, - owner: { - ...userOwner, - name: 'Really Long Organization Name Studios', - }, - categories: [ - { name: 'Adventure', icon: 'adventure', project_type: 'modpack', header: 'categories' }, - { name: 'Technology', icon: 'technology', project_type: 'modpack', header: 'categories' }, - { name: 'Magic', icon: 'magic', project_type: 'modpack', header: 'categories' }, - { name: 'Exploration', icon: 'exploration', project_type: 'modpack', header: 'categories' }, - { name: 'Multiplayer', icon: 'multiplayer', project_type: 'modpack', header: 'categories' }, - ], - onUpdate: fn(), - onContent: fn(), - }, -} - -export const NoDescription: Story = { - args: { - project: { - ...cobblemonProject, - description: undefined, - }, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - }, -} - -export const NoStats: Story = { - args: { - project: { - ...cobblemonProject, - downloads: undefined, - followers: undefined, - }, - version: cobblemonVersion, - owner: userOwner, - }, -} - -// ============================================ -// Categories Stories -// ============================================ - -export const WithClickableCategories: Story = { - render: (args) => ({ - components: { ContentModpackCard }, - setup() { - const clickedCategory = ref(null) - const categories: ContentModpackCardCategory[] = [ - { - name: 'Adventure', - icon: 'adventure', - project_type: 'modpack', - header: 'categories', - action: () => (clickedCategory.value = 'Adventure'), - }, - { - name: 'Lightweight', - icon: 'lightweight', - project_type: 'modpack', - header: 'categories', - action: () => (clickedCategory.value = 'Lightweight'), - }, - { - name: 'Multiplayer', - icon: 'multiplayer', - project_type: 'modpack', - header: 'categories', - action: () => (clickedCategory.value = 'Multiplayer'), - }, - ] - return { args, categories, clickedCategory } - }, - template: /*html*/ ` -
- -
- Clicked category: {{ clickedCategory || 'None' }} -
-
- `, - }), - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - }, -} - -// ============================================ -// Overflow Menu Stories -// ============================================ - -export const WithOverflowMenu: Story = { - render: (args) => ({ - components: { ContentModpackCard }, - setup() { - return { args } - }, - template: /*html*/ ` - - - - - - `, - }), - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - overflowOptions: [ - { id: 'view', action: () => console.log('View') }, - { id: 'settings', action: () => console.log('Settings') }, - { divider: true }, - { id: 'remove', action: () => console.log('Remove'), color: 'red' }, - ], - }, -} - -// ============================================ -// Interactive Stories -// ============================================ - -export const WithContentModal: Story = { - args: { - project: cobblemonProject, - }, - render: () => ({ - components: { ContentModpackCard, NewModal, ContentCardItem }, - setup() { - const modalRef = ref | null>(null) - const modpackContent = [ - { - project: { - id: '1', - slug: 'sodium', - title: 'Sodium', - icon_url: - 'https://cdn.modrinth.com/data/AANobbMI/295862f4724dc3f78df3447ad6072b2dcd3ef0c9_96.webp', - }, - version: { id: 'v1', version_number: '0.8.2', file_name: 'sodium-fabric-0.8.2.jar' }, - }, - { - project: { - id: '2', - slug: 'modmenu', - title: 'Mod Menu', - icon_url: - 'https://cdn.modrinth.com/data/mOgUt4GM/5a20ed1450a0e1e79a1fe04e61bb4e5878bf1d20.png', - }, - version: { id: 'v2', version_number: '16.0.0', file_name: 'modmenu-16.0.0.jar' }, - }, - { - project: { - id: '3', - slug: 'fabric-api', - title: 'Fabric API', - icon_url: 'https://cdn.modrinth.com/data/P7dR8mSH/icon.png', - }, - version: { id: 'v3', version_number: '0.141.3', file_name: 'fabric-api-0.141.3.jar' }, - }, - ] - - return { - cobblemonProject, - cobblemonVersion, - userOwner, - optimizationCategories, - modalRef, - modpackContent, - } - }, - template: /*html*/ ` -
- - -
- -
-
-
- `, - }), -} - -// ============================================ -// Responsive Stories -// ============================================ - -export const ResponsiveView: Story = { - args: { - project: cobblemonProject, - }, - render: () => ({ - components: { ContentModpackCard }, - setup() { - return { - cobblemonProject, - cobblemonVersion, - userOwner, - optimizationCategories, - } - }, - template: /*html*/ ` -
-
-

Desktop (full width)

-
- -
-
-
-

Mobile (<640px)

-
- -
-
-
- `, - }), -} - -// ============================================ -// Edge Cases -// ============================================ - -export const NoIcon: Story = { - args: { - project: { - ...cobblemonProject, - icon_url: undefined, - }, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - }, -} - -export const NoOwnerAvatar: Story = { - args: { - project: cobblemonProject, - version: cobblemonVersion, - owner: { - ...userOwner, - avatar_url: undefined, - }, - categories: optimizationCategories, - }, -} - -export const HighDownloadCounts: Story = { - args: { - project: { - ...cobblemonProject, - downloads: 1234567890, - followers: 9876543, - }, - version: cobblemonVersion, - owner: userOwner, - categories: optimizationCategories, - }, -} diff --git a/packages/ui/src/stories/instances/ContentUpdaterModal.stories.ts b/packages/ui/src/stories/instances/ContentUpdaterModal.stories.ts index 909463c837..129f602d60 100644 --- a/packages/ui/src/stories/instances/ContentUpdaterModal.stories.ts +++ b/packages/ui/src/stories/instances/ContentUpdaterModal.stories.ts @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite' import { fn } from 'storybook/test' import { ref } from 'vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { Button } from '../../components/base/buttons' import ContentUpdaterModal from '../../layouts/shared/content-tab/components/modals/content-updater-modal/index.vue' // Real version data from Modrinth API - Sodium (mod) @@ -265,7 +265,7 @@ type Story = StoryObj export const ModExample: Story = { render: (args) => ({ - components: { ContentUpdaterModal, ButtonStyled }, + components: { ContentUpdaterModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -277,9 +277,7 @@ export const ModExample: Story = { }, template: /*html*/ `
- - - + ({ - components: { ContentUpdaterModal, ButtonStyled }, + components: { ContentUpdaterModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -318,9 +316,7 @@ export const ModpackExample: Story = { }, template: /*html*/ `
- - - + ({ - components: { ContentUpdaterModal, ButtonStyled }, + components: { ContentUpdaterModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -355,9 +351,7 @@ export const WithIncompatibleVersions: Story = { }, template: /*html*/ `
- - - + ({ - components: { ContentUpdaterModal, ButtonStyled }, + components: { ContentUpdaterModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -389,9 +383,7 @@ export const AllVersionTypes: Story = { }, template: /*html*/ `
- - - + ({ + components: { story }, + template: '
', + }), + ], + args: { + showViewContent: true, + showSettings: true, + showPrimaryAction: true, + onViewContent: fn(), + onSettings: fn(), + onPrimaryAction: fn(), + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Modpack: Story = { + args: { + data: modpackCard, + }, +} + +export const Server: Story = { + args: { + data: serverCard, + }, +} + +export const SharedInstance: Story = { + args: { + data: sharedInstanceCard, + }, +} + +export const NarrowWidth: Story = { + args: { + data: serverCard, + }, + render: (args) => ({ + components: { ManagedContentCard }, + setup: () => ({ args }), + template: /*html*/ ` +
+ +
+ `, + }), +} + +export const LongManagerName: Story = { + args: { + data: { + ...sharedInstanceCard, + manager: { + ...sharedInstanceCard.manager, + name: 'A shared-instance manager with a very long display name', + }, + }, + }, +} + +export const MissingManagerIcon: Story = { + args: { + data: { + ...serverCard, + manager: { + name: 'Modrinth SMP', + }, + }, + }, +} + +export const ImportedModpack: Story = { + args: { + data: { + kind: 'modpack', + manager: { + name: 'Imported from Prism Launcher', + }, + summary: figmaSummary, + }, + showPrimaryAction: false, + }, +} + +export const LoadingCounts: Story = { + args: { + data: { + ...modpackCard, + summary: undefined, + }, + }, +} + +export const ZeroContent: Story = { + args: { + data: { + ...sharedInstanceCard, + summary: [], + updateAvailable: false, + }, + showPrimaryAction: false, + }, +} + +export const ApplyingUpdate: Story = { + args: { + data: serverCard, + disabled: true, + disabledText: 'Updating...', + }, +} + +export const AccountLocked: Story = { + args: { + data: { + ...sharedInstanceCard, + updateAvailable: false, + }, + showPrimaryAction: false, + }, +} + +export const EveryContentType: Story = { + args: { + data: { + ...serverCard, + summary: [ + { type: 'mod', count: 52 }, + { type: 'plugin', count: 4 }, + { type: 'datapack', count: 3 }, + { type: 'resourcepack', count: 2 }, + { type: 'shader', count: 1 }, + ], + }, + }, +} diff --git a/packages/ui/src/stories/instances/ModpackContentModal.stories.ts b/packages/ui/src/stories/instances/ManagedContentModal.stories.ts similarity index 73% rename from packages/ui/src/stories/instances/ModpackContentModal.stories.ts rename to packages/ui/src/stories/instances/ManagedContentModal.stories.ts index d86dafbe05..40fd718614 100644 --- a/packages/ui/src/stories/instances/ModpackContentModal.stories.ts +++ b/packages/ui/src/stories/instances/ManagedContentModal.stories.ts @@ -1,11 +1,10 @@ import type { Meta, StoryObj } from '@storybook/vue3-vite' import { ref } from 'vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' -import ModpackContentModal from '../../layouts/shared/content-tab/components/modals/ModpackContentModal.vue' +import { Button } from '../../components/base/buttons' +import ManagedContentModal from '../../layouts/shared/content-tab/components/managed-content-modal/index.vue' import type { ContentItem } from '../../layouts/shared/content-tab/types' -// Sample modpack content items (representing mods included in a modpack) const sodiumItem: ContentItem = { file_name: 'sodium-fabric-0.8.2+mc1.21.1.jar', file_path: '', @@ -201,7 +200,6 @@ const entityTextureFeaturesItem: ContentItem = { update_version_id: null, } -// Shader pack item const complementaryShaderItem: ContentItem = { file_name: 'ComplementaryReimagined_r5.3.zip', file_path: '', @@ -256,7 +254,6 @@ const bslShaderItem: ContentItem = { update_version_id: null, } -// Resource pack items const faithfulItem: ContentItem = { file_name: 'Faithful 32x - 1.21.zip', file_path: '', @@ -339,7 +336,6 @@ const stayTrueItem: ContentItem = { update_version_id: null, } -// Mixed content (mods + shaders + resource packs) const mixedModpackContent: ContentItem[] = [ sodiumItem, lithiumItem, @@ -355,7 +351,6 @@ const mixedModpackContent: ContentItem[] = [ stayTrueItem, ] -// Mods only const modsOnlyContent: ContentItem[] = [ sodiumItem, lithiumItem, @@ -366,7 +361,6 @@ const modsOnlyContent: ContentItem[] = [ entityTextureFeaturesItem, ] -// Large modpack content (40+ items for testing scrolling) const largeModpackContent: ContentItem[] = [ ...mixedModpackContent, ...Array.from({ length: 35 }, (_, i) => ({ @@ -393,37 +387,31 @@ const largeModpackContent: ContentItem[] = [ ] const meta = { - title: 'Instances/ModpackContentModal', - component: ModpackContentModal, + title: 'Instances/ManagedContentModal', + component: ManagedContentModal, parameters: { layout: 'centered', }, -} satisfies Meta +} satisfies Meta export default meta type Story = StoryObj -// ============================================ -// Basic Examples -// ============================================ - export const Default: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) + const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show(mixedModpackContent) return { modalRef, openModal } }, template: /*html*/ `
- - - - View Modpack Content (Mixed) +
`, @@ -432,35 +420,28 @@ export const Default: Story = { export const ModsOnly: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) + const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show(modsOnlyContent) return { modalRef, openModal } }, template: /*html*/ `
- - - - + +
`, }), } -// ============================================ -// Loading State -// ============================================ - export const LoadingState: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) + const modalRef = ref | null>(null) const openModal = () => { modalRef.value?.showLoading() - // Simulate loading delay setTimeout(() => { modalRef.value?.show(mixedModpackContent) }, 2000) @@ -469,78 +450,60 @@ export const LoadingState: Story = { }, template: /*html*/ `
- - - - View Content (With Loading) +
`, }), } -// ============================================ -// Empty State -// ============================================ - export const EmptyContent: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) + const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show([]) return { modalRef, openModal } }, template: /*html*/ `
- - - - + +
`, }), } -// ============================================ -// Large Content List -// ============================================ - export const LargeModpack: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) + const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show(largeModpackContent) return { modalRef, openModal } }, template: /*html*/ `
- - - - View Large Modpack (47 items) +
`, }), } -// ============================================ -// Search Functionality -// ============================================ - export const SearchDemo: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) + const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show(mixedModpackContent) return { modalRef, openModal } }, @@ -549,24 +512,18 @@ export const SearchDemo: Story = {

Click the button and try searching for "sodium", "shader", or "faithful" to test the search functionality.

- - - - + +
`, }), } -// ============================================ -// Filter Demo -// ============================================ - export const FilterDemo: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) + const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show(mixedModpackContent) return { modalRef, openModal } }, @@ -575,25 +532,18 @@ export const FilterDemo: Story = {

Click the button and try the filter chips (Mods, Shaders, Resource Packs) to filter content by type.

- - - - + +
`, }), } -// ============================================ -// Mixed Owner Types -// ============================================ - export const MixedOwnerTypes: Story = { render: () => ({ - components: { ModpackContentModal, ButtonStyled }, + components: { ManagedContentModal, Button }, setup() { - const modalRef = ref | null>(null) - // Mix of user and organization owners + const modalRef = ref | null>(null) const mixedContent = [ sodiumItem, // User owner fabricApiItem, // Organization owner @@ -608,10 +558,8 @@ export const MixedOwnerTypes: Story = {

Shows content with different owner types: users (circular avatar) and organizations (rounded + icon).

- - - - + +
`, }), diff --git a/packages/ui/src/stories/modal/ConfirmLeaveModal.stories.ts b/packages/ui/src/stories/modal/ConfirmLeaveModal.stories.ts index 9509d27ac1..ac33eb8886 100644 --- a/packages/ui/src/stories/modal/ConfirmLeaveModal.stories.ts +++ b/packages/ui/src/stories/modal/ConfirmLeaveModal.stories.ts @@ -1,7 +1,7 @@ import type { StoryObj } from '@storybook/vue3-vite' import { ref } from 'vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { Button } from '../../components/base/buttons' import ConfirmLeaveModal from '../../components/modal/ConfirmLeaveModal.vue' const meta = { @@ -14,7 +14,7 @@ type Story = StoryObj export const Default: Story = { render: () => ({ - components: { ConfirmLeaveModal, ButtonStyled }, + components: { ConfirmLeaveModal, Button }, setup() { const modalRef = ref | null>(null) const result = ref('') @@ -27,9 +27,7 @@ export const Default: Story = { }, template: /* html */ `
- - - +

{{ result }}

@@ -39,7 +37,7 @@ export const Default: Story = { export const CustomMessages: Story = { render: () => ({ - components: { ConfirmLeaveModal, ButtonStyled }, + components: { ConfirmLeaveModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.prompt() @@ -47,9 +45,7 @@ export const CustomMessages: Story = { }, template: /* html */ `
- - - + ({ - components: { ConfirmLeaveModal, ButtonStyled }, + components: { ConfirmLeaveModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.prompt() @@ -73,9 +69,7 @@ export const WarningAdmonition: Story = { }, template: /* html */ `
- - - + export const Default: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -22,9 +22,7 @@ export const Default: Story = { }, template: `
- - - +

This is the modal content.

You can put any content here.

@@ -36,7 +34,7 @@ export const Default: Story = { export const WithActions: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -44,19 +42,13 @@ export const WithActions: Story = { }, template: `
- - - +

Are you sure you want to proceed with this action?

@@ -67,7 +59,7 @@ export const WithActions: Story = { export const DangerFade: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -75,19 +67,13 @@ export const DangerFade: Story = { }, template: `
- - - +

Are you sure you want to delete this item? This action cannot be undone.

@@ -98,7 +84,7 @@ export const DangerFade: Story = { export const WarningFade: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -106,19 +92,13 @@ export const WarningFade: Story = { }, template: `
- - - +

This action may have unintended consequences. Please review before proceeding.

@@ -129,7 +109,7 @@ export const WarningFade: Story = { export const Scrollable: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -137,9 +117,7 @@ export const Scrollable: Story = { }, template: `
- - - +

@@ -148,9 +126,7 @@ export const Scrollable: Story = {

@@ -161,7 +137,7 @@ export const Scrollable: Story = { export const MergedHeader: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -169,9 +145,7 @@ export const MergedHeader: Story = { }, template: `
- - - +

Custom Header Area

@@ -185,7 +159,7 @@ export const MergedHeader: Story = { export const NotClosable: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -193,17 +167,13 @@ export const NotClosable: Story = { }, template: `
- - - +

This modal cannot be closed by clicking outside or pressing escape.

Only the action button can close it.

@@ -214,7 +184,7 @@ export const NotClosable: Story = { export const NoPadding: Story = { render: () => ({ - components: { NewModal, ButtonStyled }, + components: { NewModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => modalRef.value?.show() @@ -222,16 +192,12 @@ export const NoPadding: Story = { }, template: `
- - - +

This modal has no default padding on the content area.

diff --git a/packages/ui/src/stories/modal/ShareModal.stories.ts b/packages/ui/src/stories/modal/ShareModal.stories.ts index 10b07701f4..28c81af2ae 100644 --- a/packages/ui/src/stories/modal/ShareModal.stories.ts +++ b/packages/ui/src/stories/modal/ShareModal.stories.ts @@ -1,7 +1,7 @@ import type { StoryObj } from '@storybook/vue3-vite' import { ref } from 'vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { Button } from '../../components/base/buttons' import ShareModal from '../../components/modal/ShareModal.vue' const meta = { @@ -20,7 +20,7 @@ export const LinkShare: Story = { link: true, }, render: (args) => ({ - components: { ShareModal, ButtonStyled }, + components: { ShareModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => { @@ -30,9 +30,7 @@ export const LinkShare: Story = { }, template: `
- - - +
`, @@ -47,7 +45,7 @@ export const TextShare: Story = { link: false, }, render: (args) => ({ - components: { ShareModal, ButtonStyled }, + components: { ShareModal, Button }, setup() { const modalRef = ref | null>(null) const openModal = () => { @@ -57,9 +55,7 @@ export const TextShare: Story = { }, template: `
- - - +
`, diff --git a/packages/ui/src/stories/modal/TabbedModal.stories.ts b/packages/ui/src/stories/modal/TabbedModal.stories.ts index aee894f212..5d85e192ef 100644 --- a/packages/ui/src/stories/modal/TabbedModal.stories.ts +++ b/packages/ui/src/stories/modal/TabbedModal.stories.ts @@ -14,7 +14,7 @@ import { import type { StoryObj } from '@storybook/vue3-vite' import { defineComponent, h, ref } from 'vue' -import ButtonStyled from '../../components/base/ButtonStyled.vue' +import { Button } from '../../components/base/buttons' import UnsavedChangesPopup from '../../components/base/UnsavedChangesPopup.vue' import TabbedModal from '../../components/modal/TabbedModal.vue' @@ -42,7 +42,7 @@ export default meta export const Default: StoryObj = { render: () => ({ - components: { TabbedModal, ButtonStyled }, + components: { TabbedModal, Button }, setup() { const modalRef = ref | null>(null) const tabs = [ @@ -66,9 +66,7 @@ export const Default: StoryObj = { }, template: /* html */ `
- - - +
`, @@ -77,7 +75,7 @@ export const Default: StoryObj = { export const WithTitleSlot: StoryObj = { render: () => ({ - components: { TabbedModal, ButtonStyled, SettingsIcon }, + components: { TabbedModal, SettingsIcon, Button }, setup() { const modalRef = ref | null>(null) const tabs = [ @@ -96,9 +94,7 @@ export const WithTitleSlot: StoryObj = { }, template: /* html */ `
- - - + ``` -**App** — uses Tauri `invoke`: +The app uses Tauri `invoke`: ```vue @@ -83,14 +91,14 @@ import { provideContentManager, ContentPageLayout } from '@modrinth/ui' import { invoke } from '@tauri-apps/api/core' const items = ref([]) -await invoke('get_instance_content', { instanceId }).then(/* map to ContentItem[] */) +await invoke('get_instance_content', { instanceId }).then(/* Map the result to ContentItem[]. */) provideContentManager({ items, deleteItem: async (item) => { await invoke('delete_content', { instanceId, path: item.file_path }) }, - // ... rest of the contract + // Implement the remaining contract fields. }) @@ -99,29 +107,33 @@ provideContentManager({ ``` -### Optional capabilities +### Optional Capabilities -The DI contract uses optional fields for features that not every platform supports. The layout checks for them before rendering the corresponding UI: +Use optional contract fields for capabilities that are not available on all platforms. + +Check that an optional field exists before you show its UI: ```ts -// Contract +// Contract fields. bulkUpdateItems?: (items: ContentItem[]) => Promise shareItems?: (items: ContentItem[], format: string) => void -// Layout checks before showing UI +// Show the UI only when the capability exists. v-if="ctx.bulkUpdateItems && hasOutdatedProjects" ``` -### Props vs DI +### Props and DI -| Use | When | -| --------- | ------------------------------------------------------------------------------------------ | -| **DI** | Data depends on _how_ it's fetched — API calls, file operations, navigation (per-platform) | -| **Props** | Data is the same regardless of platform — configuration flags, display options | +| Use | Condition | +| ----- | -------------------------------------------------------------------------- | +| DI | Use when API calls, file operations, or navigation differ by platform. | +| Props | Use when configuration and display data are the same on all platforms. | ## Wrapped Pages (`layouts/wrapped/`) -For pages where the **logic is identical** on both platforms — same API source, same data fetching, same state management. These are full page-level Vue components that directly implement routes: +Use a wrapped page when both platforms use the same API source, data logic, and state logic. + +A wrapped page is a complete page-level Vue component. Its directory structure matches the route structure: ``` wrapped/hosting/manage/ @@ -132,7 +144,9 @@ wrapped/hosting/manage/ └── [id]/onboarding.vue ``` -Wrapped pages handle their own data fetching (typically via TanStack Query and `api-client`) and are consumed as simple component imports in both frontends: +Wrapped pages get their own data. They usually use TanStack Query and `api-client`. + +Import the wrapped page as a simple component in both frontends: ```vue @@ -145,32 +159,48 @@ import { ServersManageContentPage } from '@modrinth/ui' ``` -### Platform route shells: prefetch with `ensureQueryData` +### Prefetch Data in Platform Route Shells -#### Wrapped layout: `ReadyTransition` and `useReadyState` +#### `ReadyTransition` and `useReadyState` -Many wrapped pages wrap the main UI in [`ReadyTransition`](../../packages/ui/src/components/base/ReadyTransition.vue) with `:pending` driven by [`useReadyState`](../../packages/ui/src/composables/use-ready-state.ts) on the **primary** TanStack query (true only on the first load while that query has no cached data yet—background refetches stay “ready”). That avoids flashing empty content before data exists. +Many wrapped pages put the main UI in [`ReadyTransition`](../../packages/ui/src/components/base/ReadyTransition.vue). + +The `:pending` prop usually comes from [`useReadyState`](../../packages/ui/src/composables/use-ready-state.ts) for the primary TanStack query. + +The state is true only during the first load when the cache has no data. Background refetches keep the page ready. + +This behavior prevents empty content from appearing before the data exists. ```vue - + ``` ```ts -const primaryQuery = useQuery({ /* ... */ }) +const primaryQuery = useQuery({ /* Query options. */ }) const readyPending = useReadyState(primaryQuery) -// or useReadyState({ isLoading, data }) when not using the full query object + +// Use this form when the complete query object is not available. +const readyPendingFromState = useReadyState({ isLoading, data }) ``` -Shell prefetch (below) warms the cache so that on navigation the query often **already has data** when the layout mounts; `pending` stays false and `ReadyTransition` can skip the enter animation on that fast path (see `ReadyTransition` docs and stories). +Shell prefetch adds data to the cache before the layout mounts. On this fast path, `pending` stays false. -#### Rule: `ensureQueryData` in each platform route shell +`ReadyTransition` can then omit its enter animation. Refer to the `ReadyTransition` documentation and stories for details. -When a wrapped layout uses that pattern, the **thin platform page** that imports the layout must **prefetch the same primary query** in ` @@ -41,50 +42,54 @@ const modal = ref | null>(null) -

Modal content here.

+

Modal content.

``` -Call `show(event?)` to open the modal. Passing the `MouseEvent` triggers an animation originating from the click position. Call `hide()` to close it programmatically. +Call `show(event?)` to open the modal. A `MouseEvent` starts the animation at the click position. + +Call `hide()` to close the modal from code. ## Props -| Prop | Type | Default | Description | -| --------------------- | ------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------ | -| `header` | `string` | — | Title text displayed in the header bar | -| `hideHeader` | `boolean` | `false` | Hides the entire header (title + close button) | -| `mergeHeader` | `boolean` | `false` | Removes the header bar; renders a floating close button over the content | -| `closable` | `boolean` | `true` | Shows the close button and enables ESC / click-outside dismissal | -| `disableClose` | `boolean` | `false` | Disables all close actions (close button, ESC, click-outside). The close button appears disabled | -| `closeOnEsc` | `boolean` | `true` | Allow closing with the Escape key | -| `closeOnClickOutside` | `boolean` | `true` | Allow closing by clicking the overlay | -| `scrollable` | `boolean` | `false` | Enables scroll tracking with top/bottom fade indicators | -| `maxContentHeight` | `string` | `’70vh’` | Max height of the scrollable content area (only applies when `scrollable`) | -| `noPadding` | `boolean` | `false` | Removes padding from the content area for edge-to-edge layouts | -| `maxWidth` | `string` | `’60rem’` | Maximum width of the modal | -| `width` | `string` | `fit-content` | Width of the modal body | -| `noblur` | `boolean` | — | Disables backdrop blur. Defaults to the value from `injectModalBehavior` | -| `fade` | `’standard’ \| ‘warning’ \| ‘danger’` | `’standard’` | Overlay color variant | -| `danger` | `boolean` | `false` | **Deprecated** — use `fade="danger"` instead | -| `onShow` | `() => void` | — | Called when the modal opens | -| `onHide` | `() => void` | — | Called when the modal closes | +| Prop | Type | Default | Description | +| --------------------- | ----------------------------------------- | ------------- | ------------------------------------------------------------------ | +| `header` | `string` | None | Sets the title in the header bar. | +| `hideHeader` | `boolean` | `false` | Hides the title and close button. | +| `mergeHeader` | `boolean` | `false` | Replaces the header bar with a floating close button. | +| `closable` | `boolean` | `true` | Enables the close button, Escape key, and overlay click. | +| `disableClose` | `boolean` | `false` | Disables all close actions and shows a disabled close button. | +| `closeOnEsc` | `boolean` | `true` | Enables the Escape key as a close action. | +| `closeOnClickOutside` | `boolean` | `true` | Enables an overlay click as a close action. | +| `scrollable` | `boolean` | `false` | Enables scroll tracking and edge-fade indicators. | +| `maxContentHeight` | `string` | `'70vh'` | Sets the maximum scrollable-content height. | +| `noPadding` | `boolean` | `false` | Removes content padding for edge-to-edge layouts. | +| `maxWidth` | `string` | `'60rem'` | Sets the maximum modal width. | +| `width` | `string` | `fit-content` | Sets the modal-body width. | +| `noblur` | `boolean` | None | Disables the backdrop blur. The DI behavior supplies the default. | +| `fade` | `'standard' \| 'warning' \| 'danger'` | `'standard'` | Sets the overlay color variant. | +| `danger` | `boolean` | `false` | Deprecated. Use `fade="danger"`. | +| `onShow` | `() => void` | None | Runs when the modal opens. | +| `onHide` | `() => void` | None | Runs when the modal closes. | + +`maxContentHeight` has an effect only when `scrollable` is true. ## Slots -### Default slot +### Default Slot -The main content area. Rendered inside a padded, optionally scrollable container. +The default slot contains the main content. `NewModal` puts it in a padded container that can scroll. ```vue -

Are you sure you want to proceed?

+

Are you sure that you want to continue?

``` -### `title` slot +### `title` Slot -Replaces the default header text. Use this when you need custom markup in the header (e.g. an icon next to the title or a badge). +The `title` slot replaces the default header text. Use it for custom header markup, such as an icon or badge. ```vue @@ -92,45 +97,47 @@ Replaces the default header text. Use this when you need custom markup in the he Custom Title -

Content here.

+

Content.

``` -### `actions` slot +### `actions` Slot -Renders a bottom action bar below the content area (with `p-4 pt-0` padding). Use this for confirm/cancel buttons. +The `actions` slot makes an action bar below the content. The bar uses `p-4 pt-0` padding. + +Use this slot for confirmation and cancellation buttons: ```vue -

This action cannot be undone.

+

You cannot reverse this action.

``` ## Scrollable Content -Set `scrollable` to enable scroll tracking. The modal renders animated fade gradients at the top and bottom edges when content is scrolled, giving users a visual cue that more content exists. +Set `scrollable` to enable scroll tracking. Fade gradients appear at the top and bottom when more content exists. ```vue - + ``` -The `checkScrollState` method is exposed via ref — call it after dynamically changing content to re-evaluate whether fade indicators should appear. +Call the exposed `checkScrollState` method after a dynamic content change. The method recalculates the fade-indicator state. -When `scrollable` is `false` (the default), content uses `overflow-y: auto` without fade indicators. +When `scrollable` is false, the content uses `overflow-y: auto` without fade indicators. False is the default value. -## Merged Header Mode +## Merged Header -When `mergeHeader` is set, the header bar is hidden and a floating close button is rendered in the top-right corner of the modal. Content receives extra top padding to avoid overlapping the button. This is useful for modals with hero images or full-bleed content at the top. +When `mergeHeader` is true, the header bar is hidden. A floating close button appears in the top-right corner. + +The content gets more top padding. This padding prevents overlap with the button. + +Use this mode for a hero image or full-width content at the top: ```vue @@ -141,35 +148,39 @@ When `mergeHeader` is set, the header bar is hidden and a floating close button ``` -## Modal Stacking +## Modal Stack -`NewModal` integrates with a modal stack (`useModalStack`). Multiple modals can be open simultaneously — only the topmost modal responds to the Escape key. The document body scroll is locked when any modal is open and restored when the last modal closes. +`NewModal` uses `useModalStack`. Multiple modals can be open at the same time. + +Only the top modal responds to the Escape key. The first open modal locks document-body scrolling. + +The last modal restores document-body scrolling when it closes. ## Exposed Methods -| Method | Description | -| -------------------- | ------------------------------------------------------- | -| `show(event?)` | Opens the modal. Pass `MouseEvent` for origin animation | -| `hide()` | Closes the modal | -| `checkScrollState()` | Re-evaluates scroll fade indicators (when `scrollable`) | +| Method | Description | +| -------------------- | ------------------------------------------------------------- | +| `show(event?)` | Opens the modal. Pass a `MouseEvent` for the origin animation. | +| `hide()` | Closes the modal. | +| `checkScrollState()` | Recalculates fade indicators when `scrollable` is true. | # Multistage Modals -The `MultiStageModal` component (`packages/ui/src/components/base/MultiStageModal.vue`) provides a wizard-like modal with progress tracking, conditional stages, and per-stage button configuration. +`MultiStageModal` (`packages/ui/src/components/base/MultiStageModal.vue`) supplies progress, conditional stages, and button configurations for each stage. ## Architecture A multistage modal has three parts: -1. **Context** — A DI provider that holds all state, business logic, and stage configs -2. **Stage configs** — Data objects describing each stage (title, component, buttons, skip conditions) -3. **Stage components** — Vue components rendered inside the modal, consuming the context +1. The context contains all state, application logic, and stage configurations. +2. Stage configurations define the title, component, buttons, and skip conditions for each stage. +3. Stage components inject the context and render inside the modal. -## Building a Multistage Modal +## Create a Multistage Modal -### 1. Define the context +### 1. Define the Context -Create a DI provider with all the state your wizard needs. Include the modal ref and stage configs. +Make a DI provider that contains the modal state. Include the modal reference and stage configurations. ```ts // providers/my-feature/my-modal.ts @@ -179,15 +190,15 @@ import type { MultiStageModal, StageConfigInput } from '@modrinth/ui' import { createContext } from '@modrinth/ui' export interface MyModalContext { - // State + // State. formData: Ref isSubmitting: Ref - // Modal control + // Modal control. modal: ShallowRef | null> stageConfigs: StageConfigInput[] - // Business logic + // Application logic. handleSubmit: () => Promise } @@ -214,9 +225,11 @@ export function createMyModalContext( } ``` -### 2. Define stage configs +### 2. Define Stage Configurations -Each stage is a `StageConfigInput` where `T` is your context type. Most fields accept either a static value or a function receiving the context (`MaybeCtxFn`). +Each stage is a `StageConfigInput`, where `T` is the context type. + +Most fields accept a static value or a function that receives the context. The function type is `MaybeCtxFn`. ```ts // providers/my-feature/stages/details-stage.ts @@ -231,7 +244,7 @@ export const detailsStageConfig: StageConfigInput = { stageContent: markRaw(DetailsStage), title: 'Details', - // Conditional behavior based on context + // Set behavior from the context. skip: (ctx) => ctx.shouldSkipDetails.value, cannotNavigateForward: (ctx) => !ctx.formData.value.name, disableClose: (ctx) => ctx.isSubmitting.value, @@ -251,36 +264,36 @@ export const detailsStageConfig: StageConfigInput = { } ``` -**Stage config fields:** +Stage configuration fields: -| Field | Type | Purpose | -| ----------------------- | ------------------------------------------ | ------------------------------------------------ | -| `id` | `string` | Unique stage identifier (used with `setStage()`) | -| `stageContent` | `Component` | Vue component to render (wrap with `markRaw()`) | -| `title` | `MaybeCtxFn` | Stage title in breadcrumbs | -| `skip` | `MaybeCtxFn` | Skip this stage conditionally | -| `nonProgressStage` | `MaybeCtxFn` | Exclude from progress bar (for edit sub-flows) | -| `hideStageInBreadcrumb` | `MaybeCtxFn` | Hide from breadcrumb nav | -| `cannotNavigateForward` | `MaybeCtxFn` | Block forward navigation (validation) | -| `disableClose` | `MaybeCtxFn` | Disable closing the modal | -| `leftButtonConfig` | `MaybeCtxFn` | Left action button | -| `rightButtonConfig` | `MaybeCtxFn` | Right action button | -| `maxWidth` | `MaybeCtxFn` | Per-stage max width (default `560px`) | +| Field | Type | Purpose | +| ----------------------- | ------------------------------------------ | ------------------------------------------------- | +| `id` | `string` | Supplies the unique stage identifier. | +| `stageContent` | `Component` | Supplies the Vue component. Use `markRaw()`. | +| `title` | `MaybeCtxFn` | Supplies the breadcrumb title. | +| `skip` | `MaybeCtxFn` | Skips the stage when the value is true. | +| `nonProgressStage` | `MaybeCtxFn` | Removes the stage from the progress bar. | +| `hideStageInBreadcrumb` | `MaybeCtxFn` | Removes the stage from breadcrumb navigation. | +| `cannotNavigateForward` | `MaybeCtxFn` | Prevents forward navigation. | +| `disableClose` | `MaybeCtxFn` | Disables modal close actions. | +| `leftButtonConfig` | `MaybeCtxFn` | Configures the left action button. | +| `rightButtonConfig` | `MaybeCtxFn` | Configures the right action button. | +| `maxWidth` | `MaybeCtxFn` | Sets the stage width. The default is `560px`. | -**Button config fields:** +Button configuration fields: -| Field | Purpose | -| -------------- | ----------------------- | -| `label` | Button text | -| `icon` | Icon component | -| `iconPosition` | `'before'` or `'after'` | -| `color` | ButtonStyled color prop | -| `disabled` | Disable the button | -| `onClick` | Click handler | +| Field | Purpose | +| -------------- | --------------------------------------- | +| `label` | Supplies the button text. | +| `icon` | Supplies the icon component. | +| `iconPosition` | Uses `'before'` or `'after'`. | +| `color` | Supplies the `Button` color prop. | +| `disabled` | Disables the button when true. | +| `onClick` | Supplies the click handler. | -### 3. Create stage components +### 3. Create Stage Components -Stage components inject the context and render their UI: +Inject the context into each stage component. Then, render the applicable UI: ```vue @@ -298,9 +311,9 @@ const { formData } = injectMyModalContext() ``` -### 4. Create the wrapper component +### 4. Create the Wrapper Component -The wrapper provides context and renders `MultiStageModal`: +Provide the context from the wrapper. Then, render `MultiStageModal`: ```vue @@ -323,20 +336,20 @@ defineExpose({ show: () => modal.value?.show() }) ## Modal API -`MultiStageModal` exposes via ref: +`MultiStageModal` exposes these methods and properties through its reference: -| Method/Property | Description | -| --------------------- | ----------------------------------- | -| `show()` | Open the modal | -| `hide()` | Close the modal | -| `setStage(indexOrId)` | Jump to stage by index or string id | -| `nextStage()` | Advance to next non-skipped stage | -| `prevStage()` | Go back to previous stage | -| `currentStageIndex` | Ref to current stage index | +| Method or property | Description | +| ---------------------- | -------------------------------------------- | +| `show()` | Opens the modal. | +| `hide()` | Closes the modal. | +| `setStage(indexOrId)` | Goes to a stage by index or string ID. | +| `nextStage()` | Goes to the next applicable stage. | +| `prevStage()` | Goes to the previous stage. | +| `currentStageIndex` | Contains the current stage index as a `Ref`. | -## Non-Progress Stages (Edit Sub-Flows) +## Non-Progress Stages -For stages that shouldn't appear in the progress bar (e.g. editing a specific field from a summary page): +Use a non-progress stage for an edit flow that must not appear in the progress bar: ```ts export const editLoadersStageConfig: StageConfigInput = { @@ -355,16 +368,18 @@ export const editLoadersStageConfig: StageConfigInput = { } ``` -Navigate to it with `modal.value?.setStage('edit-loaders')` — it won't affect the progress indicator. +Call `modal.value?.setStage('edit-loaders')` to open the stage. This stage does not change the progress indicator. ## Reference Implementation -The version creation/edit modal is the most complete example: +The version create-and-edit modal is the most complete example: -| File | Purpose | -| ------------------------------------------------------------- | --------------------------------- | -| `apps/frontend/src/providers/version/manage-version-modal.ts` | Context creation + business logic | -| `apps/frontend/src/providers/version/stages/index.ts` | Stage config barrel export | -| `apps/frontend/src/providers/version/stages/*-stage.ts` | Individual stage configs | +| File | Purpose | +| ------------------------------------------------------------- | -------------------------------------- | +| `apps/frontend/src/providers/version/manage-version-modal.ts` | Contains context and application logic. | +| `apps/frontend/src/providers/version/stages/index.ts` | Exports all stage configurations. | +| `apps/frontend/src/providers/version/stages/*-stage.ts` | Contains each stage configuration. | -The context includes computed properties for conditional UI, watchers for auto-fetching dependencies, loading states for granular button disabling, and both "create" and "edit" flows sharing the same stages with different button configs. +The context has computed properties for conditional UI. It also has dependency watchers and granular button loading states. + +The create and edit flows use the same stages with different button configurations. diff --git a/standards/frontend/SURFACE_SYSTEM.md b/standards/frontend/SURFACE_SYSTEM.md index 79b656a21a..8aa3aa2383 100644 --- a/standards/frontend/SURFACE_SYSTEM.md +++ b/standards/frontend/SURFACE_SYSTEM.md @@ -1,25 +1,31 @@ # Surface System -Use `surface-*` variables to describe UI elevation and separation. The scale is ordered from the page base up through stronger raised surfaces and strokes. +Use `surface-*` variables to show UI elevation and separation. The scale starts at the page base and ends at strong strokes. ## Layers -| Token | Use | -| ----------- | ------------------------------------------------------------------- | -| `surface-1` | Page background. | -| `surface-2` | Default raised surfaces, table rows, and standard card backgrounds. | -| `surface-3` | Header bands, inputs, dropdown surfaces, and card hover states. | -| `surface-4` | Standard strokes and outlines, including table outlines. | -| `surface-5` | Strong strokes for surfaces that need extra separation. | +| Token | Use | +| ----------- | ----------------------------------------------------------------- | +| `surface-1` | Use for the page background. | +| `surface-2` | Use for raised surfaces, table rows, and standard card backgrounds. | +| `surface-3` | Use for header bands, inputs, dropdowns, and card hover states. | +| `surface-4` | Use for standard strokes, outlines, and table outlines. | +| `surface-5` | Use for strong strokes that need more separation. | ## Strokes -Use `surface-4` for normal outlines and dividers. Tables should use `surface-4` for their outer border and row separators. +Use `surface-4` for standard outlines and dividers. Use it for table borders and row separators. -Reserve `surface-5` for stronger outlines, such as modal frames, high-emphasis separators, or hover states on elements that already sit on `surface-4`. +Use `surface-5` for modal frames, strong separators, and hover states above `surface-4`. ## Backgrounds -Use `surface-1` for page backgrounds and `surface-2` for ordinary raised content. Use `surface-3` for header strips, inputs, and temporary elevation such as hover states. Use `surface-4` sparingly as a stronger raised background, usually for controls or badges that need to sit above nearby content. +Use `surface-1` for page backgrounds. Use `surface-2` for standard raised content. -Avoid using legacy aliased background variables for new UI. Prefer explicit `bg-surface-*` and `border-surface-*` utilities so the layer intent is visible in the component. +Use `surface-3` for header strips, inputs, and temporary elevation. A hover state is an example of temporary elevation. + +Use `surface-4` only for controls or badges that must appear above adjacent content. + +Do not use legacy aliased background variables in new UI. Use explicit `bg-surface-*` and `border-surface-*` utilities. + +These utilities show the intended layer in the component. diff --git a/standards/maintaining/CHANGELOG.md b/standards/maintaining/CHANGELOG.md index 421aaf2098..9d72bb8868 100644 --- a/standards/maintaining/CHANGELOG.md +++ b/standards/maintaining/CHANGELOG.md @@ -1,111 +1,136 @@ # Changelog Style Guide -## The core rule +## Core Rule -**Each bullet describes one user-visible change, written from the user's perspective, in plain language, as a single sentence.** +Each bullet describes one user-visible change. Write one plain-language sentence from the perspective of the user. -If you can't explain the change without referencing internal code, components, or refactors, it probably doesn't belong in the changelog. +Do not add a change that you can explain only with internal code, component, or refactor details. -## Voice and tense +## Voice and Tense -- **Past tense, implied subject.** The section heading (`## Added`, `## Fixed`, `## Changed`) supplies the verb's mood - bullets read as a continuation of it. - - Good: `Fixed a missing gap between the project filter tabs and the project list.` - - Good: `Added support for Java 25.` - - Avoid: `We fixed...`, `This fixes...`, `Fixes...` (present tense), `Will fix...` -- **No first person.** Don't say "we" or "our" inside a bullet. The exception is featured release callouts that link to a blog post (`We've overhauled the Content tab...`). -- **No second person except for direct user actions.** "You" is fine when describing what the user can now do (`Joining a server from the app downloads the required content and launches you directly into the server.`), but don't address the user gratuitously. +- Use the past tense with an implicit subject. The section heading supplies the context for the bullet. + - Correct: `Fixed a missing gap between the project filter tabs and the project list.` + - Correct: `Added support for Java 25.` + - Incorrect: `We fixed...`, `This fixes...`, `Fixes...`, or `Will fix...`. +- Do not use the first person. A featured release that links to a blog post is an exception. +- Use the second person only for a direct user action. -## Section/verb agreement +Example of a direct action: `Joining a server downloads the required content and opens the server.` -The opening verb must match the section it lives under. Don't put "Fixed X" bullets inside `## Added`. +## Section and Verb Agreement -| Section | Typical opening verbs | -| ------------- | ------------------------------------------------------------------------------- | -| `## Added` | Added, Introduced, New | -| `## Changed` | Refreshed, Redesigned, Moved, Renamed, Updated, Consolidated, Improved, Rebuilt | -| `## Fixed` | Fixed | -| `## Security` | Fixed (security framing) | +Make the first verb agree with its section. Do not put a `Fixed` bullet in `## Added`. -In `## Added`, the leading "Added" is often dropped because it's redundant with the heading: +| Section | Typical first words | +| ------------- | -------------------------------------------------------------------------- | +| `## Added` | Added, Introduced, New | +| `## Changed` | Refreshed, Redesigned, Moved, Renamed, Updated, Consolidated, Improved | +| `## Fixed` | Fixed | +| `## Security` | Fixed, with a clear security context | -- `- Server stats inside server settings modal, in info card.` -- `- Confirmation modal for resubscribing to a server.` +You can omit `Added` in the `## Added` section because the heading supplies it: -In `## Fixed`, the leading "Fixed" is **kept** in most entries - it reads more clearly. Be consistent within a single entry. +- `Server statistics in an information card inside the server settings modal.` +- `Confirmation modal for server resubscription.` -## What to write about +Keep `Fixed` in most `## Fixed` bullets because it makes the text clear. Use one pattern in each entry. -Describe the **observable behavior**, not the implementation. +## Content -- Good: `Server CPU and memory graphs no longer freeze on the last value after a hard crash or out-of-memory kill.` -- Bad: `Refactored the metrics polling hook to clear stale state on socket disconnect.` +Describe the result that the user can see. Do not describe the implementation. -- Good: `Historical log files are now fetched in the background when opening the Logs page, so switching between them is instant.` -- Bad: `Moved log file fetching into a background worker.` +- Correct: `Server CPU and memory graphs no longer freeze after a hard crash or out-of-memory termination.` +- Incorrect: `Refactored the metrics polling hook to clear stale state after a socket disconnection.` -If a refactor has no user-visible effect, **don't list it**. Internal cleanup, dependency bumps, and code moves don't belong in the changelog unless they produce a noticeable difference (perf, reliability, consistency). +- Correct: `Historical log files now load in the background, so selection between files is immediate.` +- Incorrect: `Moved log file fetching into a background worker.` -## Specificity +Do not list a refactor that has no user-visible result. -Be specific enough that a user reading the changelog can recognize the thing you're talking about. +You can list an internal change when it gives a visible improvement in performance, reliability, or consistency. + +## Specific Terms + +Give sufficient detail for the user to identify the applicable item. - Vague: `Fixed a bug on the project page.` -- Better: `Fixed project versions table overflowing outside of table. Version tags will now truncate.` +- Specific: `Fixed project version rows that extended past the table. Version tags now truncate.` - Vague: `Improved the UI.` -- Better: `Refreshed the server cards UI for consistency.` +- Specific: `Refreshed the server cards for visual consistency.` -Name the page, tab, modal, or feature you're talking about. "The Content tab", "the server panel header", "the Worlds tab", "the project page" - these give the reader a concrete anchor. +Name the applicable page, tab, modal, or feature. Examples include the Content tab, server panel header, Worlds tab, and project page. ## Length -- **One sentence per bullet.** If you need two sentences, you probably have two bullets, or one bullet plus a sub-bullet. -- Aim for under ~25 words. Long bullets are usually a sign that the change is being over-explained or is actually multiple changes. -- Sub-bullets (indented with a tab) are allowed when one change has several facets - see the `## Added` section in the v0.12.0 app release for a good example. +- Write one sentence in each bullet. +- Use a second bullet when the change needs a second sentence. +- Use fewer than 25 words when possible. +- Use tab-indented sub-bullets when one change has multiple related parts. + +Refer to the `## Added` section in the v0.12.0 app release for a sub-bullet example. ## Punctuation -- **End every bullet with a period.** This is inconsistent in the historical file, but periods are the more common pattern and the one to follow going forward. -- Use sentence case, not Title Case. -- Use straight quotes, not curly quotes (`"foo"` not `"foo"`). -- Use proper code formatting for filenames, flags, and literal strings: `` `.log` ``, `` `Restart` ``. +- End each bullet with a period. +- Use sentence case, not title case. +- Use straight quotation marks, not curly quotation marks: `"foo"`. +- Use code formatting for filenames, flags, and literal strings: `.log` and `Restart`. -## Naming things +Historical entries do not always use periods. Use periods in all new entries. -- Use the public, branded name: **Modrinth App**, **Modrinth Hosting**, **Modrinth** - not "the app", "servers", "Modrinth Servers" (deprecated). Capitalize product names. -- Refer to UI surfaces by the label the user sees: **Content tab**, **Worlds tab**, **Files tab**, **Logs page**, **server panel**, **project page**, **Discover page**. -- Capitalize tab and page names when referring to them by name (`the Content tab`), but not when used generically (`browse content`). +## Product and UI Names -## Don't +- Use the public names `Modrinth App`, `Modrinth Hosting`, and `Modrinth`. +- Do not use deprecated names, such as `Modrinth Servers`. +- Use the labels that appear in the UI. +- Capitalize a tab or page name when you refer to its label. +- Use lowercase when you refer to a generic action, such as `browse content`. -- **Don't blame.** Avoid "fixed a regression introduced in v0.12.0" - just describe the fix. -- **Don't reference PRs, issues, or commits.** The changelog is for users, not contributors - the exception is notable third-party contributions, where you should credit the contributor by linking their GitHub profile (e.g. `Added support for Java 25. Thanks to [@username](https://github.com/username)!`). Sharing credit for community contributions is encouraged. -- **Don't reference internal team members or processes.** No "as requested by support", no "per the design review". -- **Don't apologize or editorialize.** Skip "unfortunately", "finally", "long-awaited", "we know this has been a pain point". State the change. -- **Don't use vague intensifiers.** "Significantly improved", "much better", "vastly faster" - quantify if you can, otherwise drop the adverb. -- **Don't list every sub-fix of a bigger change separately.** If you redesigned the server panel header, write one bullet about the redesign rather than six bullets about each moved element. -- **Don't use "issue with" / "issue where" as filler.** `Fixed an issue where buttons were misaligned` → `Fixed misaligned buttons.` +Examples of UI labels include Content tab, Worlds tab, Files tab, Logs page, server panel, project page, and Discover page. -## Examples - rewriting weak bullets +## Prohibited Content + +- Do not assign blame. Describe the correction without the release that caused the problem. +- Do not refer to pull requests, issues, or commits. +- Do not refer to internal team members or processes. +- Do not apologize or add an opinion about the change. +- Do not use vague intensifiers. Give a measurement when possible, or remove the adverb. +- Do not list each small correction from one larger change. +- Do not use `issue with` or `issue where` as filler. + +You can credit a notable community contribution with a link to the contributor's GitHub profile. + +Example: `Added support for Java 25. Thanks to [@username](https://github.com/username)!` + +Replace `Fixed an issue with misaligned buttons` with `Fixed misaligned buttons.` + +## Weak-Bullet Rewrites | Weak | Better | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| `Fixed a bug.` | `Fixed project icons becoming extremely bright on hover.` | -| `Various improvements to the server panel.` | Split into specific bullets, or drop entirely. | +| `Fixed a bug.` | `Fixed excessive brightness on project icons during hover.` | +| `Various improvements to the server panel.` | Divide it into specific bullets, or remove it. | | `Refactored the logs page to use a new component.` | `Redesigned the Logs page to match the Modrinth Hosting server panel.` | -| `Fixed an issue where the server address wasn't copyable.` | `Server address in the panel header can now be clicked to copy it to your clipboard.` | -| `Made some changes to the content tab.` | Either drop, or list each user-visible change as its own bullet. | -| `Fixed UX issues.` | Name the specific UX issue. | +| `Fixed an issue where the server address was not copyable.` | `The server address in the panel header now copies to the clipboard when selected.` | +| `Made some changes to the Content tab.` | List each user-visible change, or remove the bullet. | +| `Fixed UX issues.` | Name the specific user-experience problem. | -## Featured release bullets +## Featured Release Bullets -When an entry has a linked blog post heading (e.g. `## [Introducing Server Projects](/news/article/...)`), the bullets underneath summarize the *highlights* in 1–4 lines, then link out. They don't need to be exhaustive - that's what the blog post is for. +A featured release has a linked blog-post heading, such as `## [Introducing Server Projects](/news/article/...)`. -## Quick checklist before committing a bullet +Use one to four lines below the heading to summarize the primary changes. Then, link to the blog post. -1. Would a non-developer user understand it? -2. Does it describe behavior, not implementation? -3. Is the verb in the right tense for its section? -4. Does it name the specific surface (tab/page/modal)? -5. Is it one sentence, ending in a period? -6. Is there a vague word ("issue", "bug", "various", "some") I can replace with something concrete? +The bullets do not need to contain all details. The blog post contains the complete information. + +## Bullet Checklist + +Before you commit a bullet, make sure that it meets these requirements: + +1. A user who is not a developer can understand it. +2. It describes behavior, not implementation. +3. Its verb uses the correct tense for the section. +4. It identifies the applicable tab, page, modal, or feature. +5. It contains one sentence and ends with a period. +6. It replaces vague words with specific terms.