fix: various fixes related to content tab on app and panel (#5605)
* fix: content filtering client only * fix: browse content bug Fixes #5570 * fix: Applying Mods & Updates filters at the same time doesn't work Fixes #5602 * fix: Browsing content: going back resets filters and installed state Fixes #5598 * fix: Mod tile background flickers when toggling enabled/disabled state Fixes #5600 * fix: Overhaul of "Content" tab on instances broke a lot Fixes #5567 * fix: Latest App update replacing all mods icons with a datapack/rescourcepack Fixes #5556 * fix: billing page api-client ditch useBaseFetch * fix: remove org icon from project card items * fix: lint
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
import {
|
||||
DownloadIcon,
|
||||
MoreVerticalIcon,
|
||||
OrganizationIcon,
|
||||
SpinnerIcon,
|
||||
TrashExclamationIcon,
|
||||
TrashIcon,
|
||||
@@ -88,7 +87,7 @@ const deleteHovered = ref(false)
|
||||
:class="{ 'opacity-50': disabled }"
|
||||
>
|
||||
<div
|
||||
class="flex min-w-0 items-center gap-4"
|
||||
class="flex min-w-0 items-center gap-4 transition-[filter,opacity] duration-200"
|
||||
:class="[
|
||||
hideActions ? 'flex-1' : 'flex-1 @[800px]:w-[350px] @[800px]:shrink-0 @[800px]:flex-none',
|
||||
enabled === false && !disabled ? 'grayscale opacity-50' : '',
|
||||
@@ -158,10 +157,6 @@ const deleteHovered = ref(false)
|
||||
class="flex shrink-0 items-center gap-1 !decoration-secondary"
|
||||
:class="{ 'hover:underline': owner.link }"
|
||||
>
|
||||
<OrganizationIcon
|
||||
v-if="owner.type === 'organization'"
|
||||
class="size-4 text-secondary"
|
||||
/>
|
||||
<Avatar
|
||||
:src="owner.avatar_url"
|
||||
:alt="owner.name"
|
||||
@@ -193,7 +188,7 @@ const deleteHovered = ref(false)
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="hidden flex-col gap-0.5 @[800px]:flex"
|
||||
class="hidden flex-col gap-0.5 transition-[filter,opacity] duration-200 @[800px]:flex"
|
||||
:class="[
|
||||
hideActions ? 'flex-1' : 'flex-1 min-w-0',
|
||||
enabled === false && !disabled ? 'grayscale opacity-50' : '',
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { useSessionStorage } from '@vueuse/core'
|
||||
import type { Ref } from 'vue'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import type { ContentItem } from '../types'
|
||||
|
||||
const CLIENT_ONLY_ENVIRONMENTS = new Set([
|
||||
'client_only',
|
||||
'client_only_server_optional',
|
||||
'singleplayer_only',
|
||||
])
|
||||
const CLIENT_ONLY_ENVIRONMENTS = new Set(['client_only', 'singleplayer_only'])
|
||||
|
||||
export function isClientOnlyEnvironment(env?: string | null): boolean {
|
||||
return !!env && CLIENT_ONLY_ENVIRONMENTS.has(env)
|
||||
@@ -24,10 +21,13 @@ export interface ContentFilterConfig {
|
||||
showClientOnlyFilter?: boolean
|
||||
isPackLocked?: Ref<boolean>
|
||||
formatProjectType?: (type: string) => string
|
||||
persistKey?: string
|
||||
}
|
||||
|
||||
export function useContentFilters(items: Ref<ContentItem[]>, config?: ContentFilterConfig) {
|
||||
const selectedFilters = ref<string[]>([])
|
||||
const selectedFilters = config?.persistKey
|
||||
? useSessionStorage<string[]>(`content-filters:${config.persistKey}`, [])
|
||||
: ref<string[]>([])
|
||||
|
||||
const filterOptions = computed<ContentFilterOption[]>(() => {
|
||||
const options: ContentFilterOption[] = []
|
||||
@@ -83,14 +83,23 @@ export function useContentFilters(items: Ref<ContentItem[]>, config?: ContentFil
|
||||
|
||||
function applyFilters(source: ContentItem[]): ContentItem[] {
|
||||
if (selectedFilters.value.length === 0) return source
|
||||
|
||||
const attributeFilters = new Set(['updates', 'disabled', 'client-only'])
|
||||
const typeFilters = selectedFilters.value.filter((f) => !attributeFilters.has(f))
|
||||
const activeAttributes = selectedFilters.value.filter((f) => attributeFilters.has(f))
|
||||
|
||||
return source.filter((item) => {
|
||||
for (const filter of selectedFilters.value) {
|
||||
if (filter === 'updates' && item.has_update) return true
|
||||
if (filter === 'disabled' && !item.enabled) return true
|
||||
if (filter === 'client-only' && isClientOnlyEnvironment(item.environment)) return true
|
||||
if (item.project_type === filter) return true
|
||||
if (typeFilters.length > 0 && !typeFilters.includes(item.project_type)) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
|
||||
for (const filter of activeAttributes) {
|
||||
if (filter === 'updates' && !item.has_update) return false
|
||||
if (filter === 'disabled' && item.enabled) return false
|
||||
if (filter === 'client-only' && !isClientOnlyEnvironment(item.environment)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -229,6 +229,7 @@ const { selectedFilters, filterOptions, toggleFilter, applyFilters } = useConten
|
||||
showClientOnlyFilter: ctx.showClientOnlyFilter ?? false,
|
||||
isPackLocked: ctx.isPackLocked,
|
||||
formatProjectType,
|
||||
persistKey: ctx.filterPersistKey,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -103,6 +103,9 @@ export interface ContentManagerContext {
|
||||
|
||||
// Table item mapping (link generation differs per platform)
|
||||
mapToTableItem: (item: ContentItem) => ContentCardTableItem
|
||||
|
||||
// Filter persistence key — when set, selected filters are saved/restored via sessionStorage
|
||||
filterPersistKey?: string
|
||||
}
|
||||
|
||||
export const [injectContentManager, provideContentManager] = createContext<ContentManagerContext>(
|
||||
|
||||
@@ -872,7 +872,7 @@ provideContentManager({
|
||||
})
|
||||
return filteredReasons.length > 0 ? formatMessage(filteredReasons[0].reason) : null
|
||||
}),
|
||||
getItemId: (item) => item.file_name,
|
||||
getItemId: (item) => item.file_path ?? item.file_name,
|
||||
contentTypeLabel: type,
|
||||
toggleEnabled: handleToggleEnabled,
|
||||
deleteItem: handleDeleteItem,
|
||||
@@ -898,7 +898,7 @@ provideContentManager({
|
||||
mapToTableItem: (item) => {
|
||||
const projectType = item.project_type ?? type.value
|
||||
return {
|
||||
id: item.file_name,
|
||||
id: item.file_path ?? item.file_name,
|
||||
project: item.project,
|
||||
projectLink: item.project?.id ? `/${projectType}/${item.project.id}` : undefined,
|
||||
version: item.version,
|
||||
@@ -912,6 +912,7 @@ provideContentManager({
|
||||
enabled: item.enabled,
|
||||
}
|
||||
},
|
||||
filterPersistKey: `server:${serverId}:${worldId.value}`,
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user