mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-05 22:36:05 +02:00
add "Add age-restricted instance display logic to Location component" (#1629)
This commit is contained in:
+36
-22
@@ -2,29 +2,39 @@
|
|||||||
<div class="cursor-pointer">
|
<div class="cursor-pointer">
|
||||||
<div v-if="!text" class="text-transparent">-</div>
|
<div v-if="!text" class="text-transparent">-</div>
|
||||||
<div v-show="text" class="flex items-center">
|
<div v-show="text" class="flex items-center">
|
||||||
<div v-if="region" :class="['flags', 'mr-1.5', 'shrink-0', region]"></div>
|
<template v-if="isAgeRestricted">
|
||||||
<TooltipWrapper :content="tooltipContent" :disabled="tooltipDisabled" :delay-duration="300" side="top">
|
<TooltipWrapper :content="t('dialog.user.info.instance_age_restricted_tooltip')" :delay-duration="300" side="top">
|
||||||
<div
|
<div class="inline-flex items-center gap-1 text-muted-foreground">
|
||||||
:class="locationClasses"
|
<Lock class="size-3.5 shrink-0" />
|
||||||
class="inline-flex min-w-0 flex-nowrap items-center overflow-hidden truncate"
|
<span>{{ t('dialog.user.info.instance_age_restricted') }}</span>
|
||||||
@click="handleShowWorldDialog">
|
</div>
|
||||||
<Spinner v-if="isTraveling" class="mr-1 shrink-0" />
|
</TooltipWrapper>
|
||||||
<span class="min-w-0 flex-1 truncate">
|
</template>
|
||||||
<span>{{ text }}</span>
|
<template v-else>
|
||||||
<span v-if="showInstanceIdInLocation && instanceName" class="ml-1">{{
|
<div v-if="region" :class="['flags', 'mr-1.5', 'shrink-0', region]"></div>
|
||||||
` · #${instanceName}`
|
<TooltipWrapper :content="tooltipContent" :disabled="tooltipDisabled" :delay-duration="300" side="top">
|
||||||
}}</span>
|
<div
|
||||||
<span v-if="groupName" class="ml-0.5 cursor-pointer" @click.stop="handleShowGroupDialog">
|
:class="locationClasses"
|
||||||
({{ groupName }})
|
class="inline-flex min-w-0 flex-nowrap items-center overflow-hidden truncate"
|
||||||
|
@click="handleShowWorldDialog">
|
||||||
|
<Spinner v-if="isTraveling" class="mr-1 shrink-0" />
|
||||||
|
<span class="min-w-0 flex-1 truncate">
|
||||||
|
<span>{{ text }}</span>
|
||||||
|
<span v-if="showInstanceIdInLocation && instanceName" class="ml-1">{{
|
||||||
|
` · #${instanceName}`
|
||||||
|
}}</span>
|
||||||
|
<span v-if="groupName" class="ml-0.5 cursor-pointer" @click.stop="handleShowGroupDialog">
|
||||||
|
({{ groupName }})
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</TooltipWrapper>
|
||||||
</TooltipWrapper>
|
|
||||||
|
|
||||||
<TooltipWrapper v-if="isClosed" :content="closedTooltip" :disabled="disableTooltip">
|
<TooltipWrapper v-if="isClosed" :content="closedTooltip" :disabled="disableTooltip">
|
||||||
<AlertTriangle class="inline-block ml-2 text-muted-foreground shrink-0" />
|
<AlertTriangle class="inline-block ml-2 text-muted-foreground shrink-0" />
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<Lock v-if="strict" class="inline-block ml-2 text-muted-foreground shrink-0" />
|
<Lock v-if="strict" class="inline-block ml-2 text-muted-foreground shrink-0" />
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -56,7 +66,7 @@
|
|||||||
const { verifyShortName } = useSearchStore();
|
const { verifyShortName } = useSearchStore();
|
||||||
const { cachedInstances } = useInstanceStore();
|
const { cachedInstances } = useInstanceStore();
|
||||||
const { lastInstanceApplied } = storeToRefs(useInstanceStore());
|
const { lastInstanceApplied } = storeToRefs(useInstanceStore());
|
||||||
const { showInstanceIdInLocation } = storeToRefs(useAppearanceSettingsStore());
|
const { showInstanceIdInLocation, isAgeGatedInstancesVisible } = storeToRefs(useAppearanceSettingsStore());
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
location: String,
|
location: String,
|
||||||
@@ -86,11 +96,13 @@
|
|||||||
const text = ref('');
|
const text = ref('');
|
||||||
const region = ref('');
|
const region = ref('');
|
||||||
const strict = ref(false);
|
const strict = ref(false);
|
||||||
|
const ageGate = ref(false);
|
||||||
const isTraveling = ref(false);
|
const isTraveling = ref(false);
|
||||||
const groupName = ref('');
|
const groupName = ref('');
|
||||||
const isClosed = ref(false);
|
const isClosed = ref(false);
|
||||||
const instanceName = ref('');
|
const instanceName = ref('');
|
||||||
|
|
||||||
|
const isAgeRestricted = computed(() => !isAgeGatedInstancesVisible.value && ageGate.value);
|
||||||
const isLocationLink = computed(() => props.link && props.location !== 'private' && props.location !== 'offline');
|
const isLocationLink = computed(() => props.link && props.location !== 'private' && props.location !== 'offline');
|
||||||
const locationClasses = computed(() => [
|
const locationClasses = computed(() => [
|
||||||
'x-location',
|
'x-location',
|
||||||
@@ -135,6 +147,7 @@
|
|||||||
text.value = '';
|
text.value = '';
|
||||||
region.value = '';
|
region.value = '';
|
||||||
strict.value = false;
|
strict.value = false;
|
||||||
|
ageGate.value = false;
|
||||||
isTraveling.value = false;
|
isTraveling.value = false;
|
||||||
groupName.value = '';
|
groupName.value = '';
|
||||||
isClosed.value = false;
|
isClosed.value = false;
|
||||||
@@ -166,6 +179,7 @@
|
|||||||
updateGroupName(L, instanceId);
|
updateGroupName(L, instanceId);
|
||||||
updateRegion(L);
|
updateRegion(L);
|
||||||
strict.value = L.strict;
|
strict.value = L.strict;
|
||||||
|
ageGate.value = L.ageGate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ const stubs = {
|
|||||||
AlertTriangle: { template: '<span class="alert-triangle" />' }
|
AlertTriangle: { template: '<span class="alert-triangle" />' }
|
||||||
};
|
};
|
||||||
|
|
||||||
function mountLocation(props = {}) {
|
function mountLocation(props = {}, appearanceOverrides = {}) {
|
||||||
return mount(Location, {
|
return mount(Location, {
|
||||||
props,
|
props,
|
||||||
global: {
|
global: {
|
||||||
@@ -139,7 +139,9 @@ function mountLocation(props = {}) {
|
|||||||
World: {},
|
World: {},
|
||||||
Search: {},
|
Search: {},
|
||||||
AppearanceSettings: {
|
AppearanceSettings: {
|
||||||
showInstanceIdInLocation: false
|
showInstanceIdInLocation: false,
|
||||||
|
isAgeGatedInstancesVisible: false,
|
||||||
|
...appearanceOverrides
|
||||||
},
|
},
|
||||||
Group: {}
|
Group: {}
|
||||||
}
|
}
|
||||||
@@ -150,6 +152,7 @@ function mountLocation(props = {}) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
describe('Location.vue', () => {
|
describe('Location.vue', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
@@ -342,4 +345,34 @@ describe('Location.vue', () => {
|
|||||||
expect(wrapper.text()).toContain('Second Name');
|
expect(wrapper.text()).toContain('Second Name');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('age-restricted display', () => {
|
||||||
|
test('shows Restricted with lock when ageGate instance and setting is hidden', () => {
|
||||||
|
const wrapper = mountLocation(
|
||||||
|
{ location: 'wrld_12345:67890~ageGate', hint: 'Test World' },
|
||||||
|
{ isAgeGatedInstancesVisible: false }
|
||||||
|
);
|
||||||
|
expect(wrapper.text()).toContain('Restricted');
|
||||||
|
expect(wrapper.find('.lucide-lock').exists()).toBe(true);
|
||||||
|
expect(wrapper.text()).not.toContain('Test World');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('shows normal location when ageGate instance and setting is visible', () => {
|
||||||
|
const wrapper = mountLocation(
|
||||||
|
{ location: 'wrld_12345:67890~ageGate', hint: 'Test World' },
|
||||||
|
{ isAgeGatedInstancesVisible: true }
|
||||||
|
);
|
||||||
|
expect(wrapper.text()).toContain('Test World');
|
||||||
|
expect(wrapper.text()).not.toContain('Restricted');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('shows normal location for non-ageGate instance even when setting is hidden', () => {
|
||||||
|
const wrapper = mountLocation(
|
||||||
|
{ location: 'wrld_12345:67890', hint: 'Normal World' },
|
||||||
|
{ isAgeGatedInstancesVisible: false }
|
||||||
|
);
|
||||||
|
expect(wrapper.text()).toContain('Normal World');
|
||||||
|
expect(wrapper.text()).not.toContain('Restricted');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1342,6 +1342,8 @@
|
|||||||
"vrcplus_hides_avatar": "When a VRC+ profile photo is set, avatar info is hidden. This also hides avatar changes in the feed",
|
"vrcplus_hides_avatar": "When a VRC+ profile photo is set, avatar info is hidden. This also hides avatar changes in the feed",
|
||||||
"instance_full": "full",
|
"instance_full": "full",
|
||||||
"instance_closed": "Instance closed",
|
"instance_closed": "Instance closed",
|
||||||
|
"instance_age_restricted": "Restricted",
|
||||||
|
"instance_age_restricted_tooltip": "In an age-restricted instance",
|
||||||
"close_instance": "Close Instance",
|
"close_instance": "Close Instance",
|
||||||
"instance_age_gated": "Age Gated",
|
"instance_age_gated": "Age Gated",
|
||||||
"open_previous_instance": "Open Previous Instances",
|
"open_previous_instance": "Open Previous Instances",
|
||||||
|
|||||||
Reference in New Issue
Block a user