Remove showIf and make visibility properties take booleans

This commit is contained in:
thepaperpilot 2023-02-15 20:00:36 -06:00
parent be5c3435c6
commit 665dbcc8cb
29 changed files with 180 additions and 130 deletions

View file

@ -1,9 +1,9 @@
<template> <template>
<div <div
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="[ :style="[
{ {
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined, visibility: isHidden(visibility) ? 'hidden' : undefined,
backgroundImage: (earned && image && `url(${image})`) || '' backgroundImage: (earned && image && `url(${image})`) || ''
}, },
unref(style) ?? [] unref(style) ?? []
@ -27,7 +27,7 @@ import "components/common/features.css";
import MarkNode from "components/MarkNode.vue"; import MarkNode from "components/MarkNode.vue";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import type { CoercableComponent } from "features/feature"; import type { CoercableComponent } from "features/feature";
import { Visibility } from "features/feature"; import { Visibility, isHidden, isVisible } from "features/feature";
import { computeOptionalComponent, processedPropType } from "util/vue"; import { computeOptionalComponent, processedPropType } from "util/vue";
import type { StyleValue } from "vue"; import type { StyleValue } from "vue";
import { defineComponent, toRefs, unref } from "vue"; import { defineComponent, toRefs, unref } from "vue";
@ -35,7 +35,7 @@ import { defineComponent, toRefs, unref } from "vue";
export default defineComponent({ export default defineComponent({
props: { props: {
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
display: processedPropType<CoercableComponent>(Object, String, Function), display: processedPropType<CoercableComponent>(Object, String, Function),
@ -62,7 +62,9 @@ export default defineComponent({
return { return {
component: computeOptionalComponent(display), component: computeOptionalComponent(display),
unref, unref,
Visibility Visibility,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -4,6 +4,7 @@ import {
Component, Component,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
isVisible,
OptionsFunc, OptionsFunc,
Replace, Replace,
setDefault, setDefault,
@ -32,7 +33,7 @@ const toast = useToast();
export const AchievementType = Symbol("Achievement"); export const AchievementType = Symbol("Achievement");
export interface AchievementOptions { export interface AchievementOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
shouldEarn?: () => boolean; shouldEarn?: () => boolean;
display?: Computable<CoercableComponent>; display?: Computable<CoercableComponent>;
mark?: Computable<boolean | string>; mark?: Computable<boolean | string>;
@ -66,7 +67,7 @@ export type Achievement<T extends AchievementOptions> = Replace<
export type GenericAchievement = Replace< export type GenericAchievement = Replace<
Achievement<AchievementOptions>, Achievement<AchievementOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;
@ -104,7 +105,7 @@ export function createAchievement<T extends AchievementOptions>(
if (settings.active !== player.id) return; if (settings.active !== player.id) return;
if ( if (
!genericAchievement.earned.value && !genericAchievement.earned.value &&
unref(genericAchievement.visibility) === Visibility.Visible && isVisible(genericAchievement.visibility) &&
genericAchievement.shouldEarn?.() genericAchievement.shouldEarn?.()
) { ) {
genericAchievement.earned.value = true; genericAchievement.earned.value = true;

View file

@ -71,7 +71,7 @@ export type GenericAction = Replace<
Action<ActionOptions>, Action<ActionOptions>,
{ {
autoStart: ProcessedComputable<boolean>; autoStart: ProcessedComputable<boolean>;
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
canClick: ProcessedComputable<boolean>; canClick: ProcessedComputable<boolean>;
} }
>; >;

View file

@ -1,11 +1,11 @@
<template> <template>
<div <div
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="[ :style="[
{ {
width: unref(width) + 'px', width: unref(width) + 'px',
height: unref(height) + 'px', height: unref(height) + 'px',
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
unref(style) ?? {} unref(style) ?? {}
]" ]"
@ -44,7 +44,7 @@
<script lang="ts"> <script lang="ts">
import MarkNode from "components/MarkNode.vue"; import MarkNode from "components/MarkNode.vue";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import { CoercableComponent, Visibility } from "features/feature"; import { CoercableComponent, isHidden, isVisible, Visibility } from "features/feature";
import type { DecimalSource } from "util/bignum"; import type { DecimalSource } from "util/bignum";
import Decimal from "util/bignum"; import Decimal from "util/bignum";
import { Direction } from "util/common"; import { Direction } from "util/common";
@ -72,7 +72,7 @@ export default defineComponent({
}, },
display: processedPropType<CoercableComponent>(Object, String, Function), display: processedPropType<CoercableComponent>(Object, String, Function),
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
style: processedPropType<StyleValue>(Object, String, Array), style: processedPropType<StyleValue>(Object, String, Array),
@ -136,7 +136,9 @@ export default defineComponent({
barStyle, barStyle,
component, component,
unref, unref,
Visibility Visibility,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -22,7 +22,7 @@ import { unref } from "vue";
export const BarType = Symbol("Bar"); export const BarType = Symbol("Bar");
export interface BarOptions { export interface BarOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
width: Computable<number>; width: Computable<number>;
height: Computable<number>; height: Computable<number>;
direction: Computable<Direction>; direction: Computable<Direction>;
@ -66,7 +66,7 @@ export type Bar<T extends BarOptions> = Replace<
export type GenericBar = Replace< export type GenericBar = Replace<
Bar<BarOptions>, Bar<BarOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;

View file

@ -1,7 +1,7 @@
<template> <template>
<panZoom <panZoom
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
v-show="unref(visibility) === Visibility.Visible" v-show="isHidden(visibility)"
:style="[ :style="[
{ {
width, width,
@ -60,7 +60,7 @@ import type {
} from "features/boards/board"; } from "features/boards/board";
import { getNodeProperty } from "features/boards/board"; import { getNodeProperty } from "features/boards/board";
import type { StyleValue } from "features/feature"; import type { StyleValue } from "features/feature";
import { Visibility } from "features/feature"; import { isHidden, isVisible, Visibility } from "features/feature";
import type { ProcessedComputable } from "util/computed"; import type { ProcessedComputable } from "util/computed";
import { computed, ref, Ref, toRefs, unref } from "vue"; import { computed, ref, Ref, toRefs, unref } from "vue";
import BoardLinkVue from "./BoardLink.vue"; import BoardLinkVue from "./BoardLink.vue";
@ -70,7 +70,7 @@ const _props = defineProps<{
nodes: Ref<BoardNode[]>; nodes: Ref<BoardNode[]>;
types: Record<string, GenericNodeType>; types: Record<string, GenericNodeType>;
state: Ref<BoardData>; state: Ref<BoardData>;
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
width?: ProcessedComputable<string>; width?: ProcessedComputable<string>;
height?: ProcessedComputable<string>; height?: ProcessedComputable<string>;
style?: ProcessedComputable<StyleValue>; style?: ProcessedComputable<StyleValue>;

View file

@ -129,7 +129,7 @@ export type GenericNodeType = Replace<
export interface BoardNodeActionOptions { export interface BoardNodeActionOptions {
id: string; id: string;
visibility?: NodeComputable<Visibility>; visibility?: NodeComputable<Visibility | boolean>;
icon: NodeComputable<string>; icon: NodeComputable<string>;
fillColor?: NodeComputable<string>; fillColor?: NodeComputable<string>;
tooltip: NodeComputable<string>; tooltip: NodeComputable<string>;
@ -155,12 +155,12 @@ export type BoardNodeAction<T extends BoardNodeActionOptions> = Replace<
export type GenericBoardNodeAction = Replace< export type GenericBoardNodeAction = Replace<
BoardNodeAction<BoardNodeActionOptions>, BoardNodeAction<BoardNodeActionOptions>,
{ {
visibility: NodeComputable<Visibility>; visibility: NodeComputable<Visibility | boolean>;
} }
>; >;
export interface BoardOptions { export interface BoardOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
height?: Computable<string>; height?: Computable<string>;
width?: Computable<string>; width?: Computable<string>;
classes?: Computable<Record<string, boolean>>; classes?: Computable<Record<string, boolean>>;
@ -199,7 +199,7 @@ export type Board<T extends BoardOptions> = Replace<
export type GenericBoard = Replace< export type GenericBoard = Replace<
Board<BoardOptions>, Board<BoardOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
state: ProcessedComputable<BoardData>; state: ProcessedComputable<BoardData>;
links: ProcessedComputable<BoardNodeLink[] | null>; links: ProcessedComputable<BoardNodeLink[] | null>;
} }

View file

@ -1,9 +1,9 @@
<template> <template>
<div <div
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="[ :style="[
{ {
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
notifyStyle, notifyStyle,
unref(style) ?? {} unref(style) ?? {}
@ -36,7 +36,7 @@ import MarkNode from "components/MarkNode.vue";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import type { GenericChallenge } from "features/challenges/challenge"; import type { GenericChallenge } from "features/challenges/challenge";
import type { StyleValue } from "features/feature"; import type { StyleValue } from "features/feature";
import { jsx, Visibility } from "features/feature"; import { isHidden, isVisible, jsx, Visibility } from "features/feature";
import { getHighNotifyStyle, getNotifyStyle } from "game/notifications"; import { getHighNotifyStyle, getNotifyStyle } from "game/notifications";
import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue"; import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue";
import type { Component, PropType, UnwrapRef } from "vue"; import type { Component, PropType, UnwrapRef } from "vue";
@ -62,7 +62,7 @@ export default defineComponent({
Function Function
), ),
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
style: processedPropType<StyleValue>(String, Object, Array), style: processedPropType<StyleValue>(String, Object, Array),
@ -167,6 +167,8 @@ export default defineComponent({
notifyStyle, notifyStyle,
comp, comp,
Visibility, Visibility,
isVisible,
isHidden,
unref unref
}; };
} }

View file

@ -2,7 +2,15 @@ import { isArray } from "@vue/shared";
import Toggle from "components/fields/Toggle.vue"; import Toggle from "components/fields/Toggle.vue";
import ChallengeComponent from "features/challenges/Challenge.vue"; import ChallengeComponent from "features/challenges/Challenge.vue";
import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature";
import { Component, GatherProps, getUniqueID, jsx, setDefault, Visibility } from "features/feature"; import {
Component,
GatherProps,
getUniqueID,
isVisible,
jsx,
setDefault,
Visibility
} from "features/feature";
import type { GenericReset } from "features/reset"; import type { GenericReset } from "features/reset";
import type { Resource } from "features/resources/resource"; import type { Resource } from "features/resources/resource";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
@ -25,7 +33,7 @@ import { computed, unref, watch } from "vue";
export const ChallengeType = Symbol("ChallengeType"); export const ChallengeType = Symbol("ChallengeType");
export interface ChallengeOptions { export interface ChallengeOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
canStart?: Computable<boolean>; canStart?: Computable<boolean>;
reset?: GenericReset; reset?: GenericReset;
canComplete?: Computable<boolean | DecimalSource>; canComplete?: Computable<boolean | DecimalSource>;
@ -81,7 +89,7 @@ export type Challenge<T extends ChallengeOptions> = Replace<
export type GenericChallenge = Replace< export type GenericChallenge = Replace<
Challenge<ChallengeOptions>, Challenge<ChallengeOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
canStart: ProcessedComputable<boolean>; canStart: ProcessedComputable<boolean>;
canComplete: ProcessedComputable<boolean | DecimalSource>; canComplete: ProcessedComputable<boolean | DecimalSource>;
completionLimit: ProcessedComputable<DecimalSource>; completionLimit: ProcessedComputable<DecimalSource>;
@ -145,7 +153,7 @@ export function createChallenge<T extends ChallengeOptions>(
genericChallenge.reset?.reset(); genericChallenge.reset?.reset();
} else if ( } else if (
unref(genericChallenge.canStart) && unref(genericChallenge.canStart) &&
unref(genericChallenge.visibility) === Visibility.Visible && isVisible(genericChallenge.visibility) &&
!genericChallenge.maxed.value !genericChallenge.maxed.value
) { ) {
genericChallenge.reset?.reset(); genericChallenge.reset?.reset();
@ -179,7 +187,7 @@ export function createChallenge<T extends ChallengeOptions>(
}; };
processComputable(challenge as T, "visibility"); processComputable(challenge as T, "visibility");
setDefault(challenge, "visibility", Visibility.Visible); setDefault(challenge, "visibility", Visibility.Visible);
const visibility = challenge.visibility as ProcessedComputable<Visibility>; const visibility = challenge.visibility as ProcessedComputable<Visibility | boolean>;
challenge.visibility = computed(() => { challenge.visibility = computed(() => {
if (settings.hideChallenges === true && unref(challenge.maxed)) { if (settings.hideChallenges === true && unref(challenge.maxed)) {
return Visibility.None; return Visibility.None;

View file

@ -1,8 +1,8 @@
<template> <template>
<button <button
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="[ :style="[
{ visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined }, { visibility: isHidden(visibility) ? 'hidden' : undefined },
unref(style) ?? [] unref(style) ?? []
]" ]"
@click="onClick" @click="onClick"
@ -33,7 +33,7 @@ import MarkNode from "components/MarkNode.vue";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import type { GenericClickable } from "features/clickables/clickable"; import type { GenericClickable } from "features/clickables/clickable";
import type { StyleValue } from "features/feature"; import type { StyleValue } from "features/feature";
import { jsx, Visibility } from "features/feature"; import { isHidden, isVisible, jsx, Visibility } from "features/feature";
import { import {
coerceComponent, coerceComponent,
isCoercableComponent, isCoercableComponent,
@ -55,7 +55,7 @@ export default defineComponent({
required: true required: true
}, },
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
style: processedPropType<StyleValue>(Object, String, Array), style: processedPropType<StyleValue>(Object, String, Array),
@ -116,6 +116,8 @@ export default defineComponent({
stop, stop,
comp, comp,
Visibility, Visibility,
isVisible,
isHidden,
unref unref
}; };
} }

View file

@ -22,7 +22,7 @@ import { computed, Ref, ref, unref } from "vue";
export const ClickableType = Symbol("Clickable"); export const ClickableType = Symbol("Clickable");
export interface ClickableOptions { export interface ClickableOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
canClick?: Computable<boolean>; canClick?: Computable<boolean>;
classes?: Computable<Record<string, boolean>>; classes?: Computable<Record<string, boolean>>;
style?: Computable<StyleValue>; style?: Computable<StyleValue>;
@ -62,7 +62,7 @@ export type Clickable<T extends ClickableOptions> = Replace<
export type GenericClickable = Replace< export type GenericClickable = Replace<
Clickable<ClickableOptions>, Clickable<ClickableOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
canClick: ProcessedComputable<boolean>; canClick: ProcessedComputable<boolean>;
} }
>; >;

View file

@ -1,7 +1,7 @@
import Decimal from "util/bignum"; import Decimal from "util/bignum";
import { DoNotCache } from "util/computed"; import { DoNotCache, ProcessedComputable } from "util/computed";
import type { CSSProperties, DefineComponent } from "vue"; import type { CSSProperties, DefineComponent } from "vue";
import { isRef } from "vue"; import { isRef, unref } from "vue";
/** /**
* A symbol to use as a key for a vue component a feature can be rendered with * A symbol to use as a key for a vue component a feature can be rendered with
@ -67,6 +67,16 @@ export enum Visibility {
None None
} }
export function isVisible(visibility: ProcessedComputable<Visibility | boolean>) {
const currVisibility = unref(visibility);
return currVisibility !== Visibility.None && currVisibility !== false;
}
export function isHidden(visibility: ProcessedComputable<Visibility | boolean>) {
const currVisibility = unref(visibility);
return currVisibility === Visibility.Hidden;
}
/** /**
* Takes a function and marks it as JSX so it won't get auto-wrapped into a ComputedRef. * Takes a function and marks it as JSX so it won't get auto-wrapped into a ComputedRef.
* The function may also return empty string as empty JSX tags cause issues. * The function may also return empty string as empty JSX tags cause issues.
@ -76,11 +86,6 @@ export function jsx(func: () => JSX.Element | ""): JSXFunction {
return func as JSXFunction; return func as JSXFunction;
} }
/** Utility function to convert a boolean value into a Visbility value */
export function showIf(condition: boolean, otherwise = Visibility.None): Visibility {
return condition ? Visibility.Visible : otherwise;
}
/** Utility function to set a property on an object if and only if it doesn't already exist */ /** Utility function to set a property on an object if and only if it doesn't already exist */
export function setDefault<T, K extends keyof T>( export function setDefault<T, K extends keyof T>(
object: T, object: T,

View file

@ -1,8 +1,8 @@
<template> <template>
<div <div
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="{ :style="{
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}" }"
class="table-grid" class="table-grid"
> >
@ -19,7 +19,7 @@
<script lang="ts"> <script lang="ts">
import "components/common/table.css"; import "components/common/table.css";
import themes from "data/themes"; import themes from "data/themes";
import { Visibility } from "features/feature"; import { isHidden, isVisible, Visibility } from "features/feature";
import type { GridCell } from "features/grids/grid"; import type { GridCell } from "features/grids/grid";
import settings from "game/settings"; import settings from "game/settings";
import { processedPropType } from "util/vue"; import { processedPropType } from "util/vue";
@ -29,7 +29,7 @@ import GridCellVue from "./GridCell.vue";
export default defineComponent({ export default defineComponent({
props: { props: {
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
rows: { rows: {
@ -54,7 +54,7 @@ export default defineComponent({
return { visibility, onClick, onHold, display, title, style, canClick, id }; return { visibility, onClick, onHold, display, title, style, canClick, id };
} }
return { unref, gatherCellProps, Visibility, mergeAdjacent }; return { unref, gatherCellProps, Visibility, mergeAdjacent, isVisible, isHidden };
} }
}); });
</script> </script>

View file

@ -1,10 +1,10 @@
<template> <template>
<button <button
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:class="{ feature: true, tile: true, can: unref(canClick), locked: !unref(canClick) }" :class="{ feature: true, tile: true, can: unref(canClick), locked: !unref(canClick) }"
:style="[ :style="[
{ {
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
unref(style) ?? {} unref(style) ?? {}
]" ]"
@ -26,7 +26,7 @@
import "components/common/features.css"; import "components/common/features.css";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import type { CoercableComponent, StyleValue } from "features/feature"; import type { CoercableComponent, StyleValue } from "features/feature";
import { Visibility } from "features/feature"; import { isHidden, isVisible, Visibility } from "features/feature";
import { import {
computeComponent, computeComponent,
computeOptionalComponent, computeOptionalComponent,
@ -39,7 +39,7 @@ import { defineComponent, toRefs, unref } from "vue";
export default defineComponent({ export default defineComponent({
props: { props: {
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
onClick: Function as PropType<(e?: MouseEvent | TouchEvent) => void>, onClick: Function as PropType<(e?: MouseEvent | TouchEvent) => void>,
@ -76,7 +76,9 @@ export default defineComponent({
titleComponent, titleComponent,
component, component,
Visibility, Visibility,
unref unref,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -171,7 +171,7 @@ function getCellHandler(id: string): ProxyHandler<GenericGrid> {
export interface GridCell { export interface GridCell {
id: string; id: string;
visibility: Visibility; visibility: Visibility | boolean;
canClick: boolean; canClick: boolean;
startState: State; startState: State;
state: State; state: State;
@ -184,10 +184,10 @@ export interface GridCell {
} }
export interface GridOptions { export interface GridOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
rows: Computable<number>; rows: Computable<number>;
cols: Computable<number>; cols: Computable<number>;
getVisibility?: CellComputable<Visibility>; getVisibility?: CellComputable<Visibility | boolean>;
getCanClick?: CellComputable<boolean>; getCanClick?: CellComputable<boolean>;
getStartState: Computable<State> | ((id: string | number) => State); getStartState: Computable<State> | ((id: string | number) => State);
getStyle?: CellComputable<StyleValue>; getStyle?: CellComputable<StyleValue>;
@ -229,8 +229,8 @@ export type Grid<T extends GridOptions> = Replace<
export type GenericGrid = Replace< export type GenericGrid = Replace<
Grid<GridOptions>, Grid<GridOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
getVisibility: ProcessedComputable<Visibility>; getVisibility: ProcessedComputable<Visibility | boolean>;
getCanClick: ProcessedComputable<boolean>; getCanClick: ProcessedComputable<boolean>;
} }
>; >;

View file

@ -1,11 +1,11 @@
<template> <template>
<div <div
class="infobox" class="infobox"
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="[ :style="[
{ {
borderColor: unref(color), borderColor: unref(color),
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
unref(style) ?? {} unref(style) ?? {}
]" ]"
@ -33,7 +33,7 @@ import CollapseTransition from "@ivanv/vue-collapse-transition/src/CollapseTrans
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import themes from "data/themes"; import themes from "data/themes";
import type { CoercableComponent } from "features/feature"; import type { CoercableComponent } from "features/feature";
import { Visibility } from "features/feature"; import { isHidden, isVisible, Visibility } from "features/feature";
import settings from "game/settings"; import settings from "game/settings";
import { computeComponent, processedPropType } from "util/vue"; import { computeComponent, processedPropType } from "util/vue";
import type { PropType, Ref, StyleValue } from "vue"; import type { PropType, Ref, StyleValue } from "vue";
@ -42,7 +42,7 @@ import { computed, defineComponent, toRefs, unref } from "vue";
export default defineComponent({ export default defineComponent({
props: { props: {
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
display: { display: {
@ -83,7 +83,9 @@ export default defineComponent({
bodyComponent, bodyComponent,
stacked, stacked,
unref, unref,
Visibility Visibility,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -16,7 +16,7 @@ import { unref } from "vue";
export const InfoboxType = Symbol("Infobox"); export const InfoboxType = Symbol("Infobox");
export interface InfoboxOptions { export interface InfoboxOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
color?: Computable<string>; color?: Computable<string>;
style?: Computable<StyleValue>; style?: Computable<StyleValue>;
titleStyle?: Computable<StyleValue>; titleStyle?: Computable<StyleValue>;
@ -51,7 +51,7 @@ export type Infobox<T extends InfoboxOptions> = Replace<
export type GenericInfobox = Replace< export type GenericInfobox = Replace<
Infobox<InfoboxOptions>, Infobox<InfoboxOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;

View file

@ -1,9 +1,9 @@
<template> <template>
<div <div
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="[ :style="[
{ {
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
unref(style) ?? {} unref(style) ?? {}
]" ]"
@ -18,7 +18,7 @@
import "components/common/features.css"; import "components/common/features.css";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import type { StyleValue } from "features/feature"; import type { StyleValue } from "features/feature";
import { jsx, Visibility } from "features/feature"; import { isHidden, isVisible, jsx, Visibility } from "features/feature";
import type { GenericMilestone } from "features/milestones/milestone"; import type { GenericMilestone } from "features/milestones/milestone";
import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue"; import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue";
import type { Component, UnwrapRef } from "vue"; import type { Component, UnwrapRef } from "vue";
@ -27,7 +27,7 @@ import { defineComponent, shallowRef, toRefs, unref, watchEffect } from "vue";
export default defineComponent({ export default defineComponent({
props: { props: {
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
display: { display: {
@ -92,7 +92,9 @@ export default defineComponent({
return { return {
comp, comp,
unref, unref,
Visibility Visibility,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -6,7 +6,15 @@ import type {
Replace, Replace,
StyleValue StyleValue
} from "features/feature"; } from "features/feature";
import { Component, GatherProps, getUniqueID, jsx, setDefault, Visibility } from "features/feature"; import {
Component,
GatherProps,
getUniqueID,
isVisible,
jsx,
setDefault,
Visibility
} from "features/feature";
import MilestoneComponent from "features/milestones/Milestone.vue"; import MilestoneComponent from "features/milestones/Milestone.vue";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
import "game/notifications"; import "game/notifications";
@ -40,7 +48,7 @@ export enum MilestoneDisplay {
} }
export interface MilestoneOptions { export interface MilestoneOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
shouldEarn?: () => boolean; shouldEarn?: () => boolean;
style?: Computable<StyleValue>; style?: Computable<StyleValue>;
classes?: Computable<Record<string, boolean>>; classes?: Computable<Record<string, boolean>>;
@ -79,7 +87,7 @@ export type Milestone<T extends MilestoneOptions> = Replace<
export type GenericMilestone = Replace< export type GenericMilestone = Replace<
Milestone<MilestoneOptions>, Milestone<MilestoneOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;
@ -118,7 +126,7 @@ export function createMilestone<T extends MilestoneOptions>(
processComputable(milestone as T, "visibility"); processComputable(milestone as T, "visibility");
setDefault(milestone, "visibility", Visibility.Visible); setDefault(milestone, "visibility", Visibility.Visible);
const visibility = milestone.visibility as ProcessedComputable<Visibility>; const visibility = milestone.visibility as ProcessedComputable<Visibility | boolean>;
milestone.visibility = computed(() => { milestone.visibility = computed(() => {
const display = unref((milestone as GenericMilestone).display); const display = unref((milestone as GenericMilestone).display);
switch (settings.msDisplay) { switch (settings.msDisplay) {
@ -163,7 +171,7 @@ export function createMilestone<T extends MilestoneOptions>(
if (settings.active !== player.id) return; if (settings.active !== player.id) return;
if ( if (
!genericMilestone.earned.value && !genericMilestone.earned.value &&
unref(genericMilestone.visibility) === Visibility.Visible && isVisible(genericMilestone.visibility) &&
genericMilestone.shouldEarn?.() genericMilestone.shouldEarn?.()
) { ) {
genericMilestone.earned.value = true; genericMilestone.earned.value = true;

View file

@ -50,7 +50,7 @@ export type RepeatableDisplay =
/** An object that configures a {@link Repeatable}. */ /** An object that configures a {@link Repeatable}. */
export interface RepeatableOptions { export interface RepeatableOptions {
/** Whether this repeatable should be visible. */ /** Whether this repeatable should be visible. */
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
/** The requirement(s) to increase this repeatable. */ /** The requirement(s) to increase this repeatable. */
requirements: Requirements; requirements: Requirements;
/** The maximum amount obtainable for this repeatable. */ /** The maximum amount obtainable for this repeatable. */
@ -113,7 +113,7 @@ export type Repeatable<T extends RepeatableOptions> = Replace<
export type GenericRepeatable = Replace< export type GenericRepeatable = Replace<
Repeatable<RepeatableOptions>, Repeatable<RepeatableOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
limit: ProcessedComputable<DecimalSource>; limit: ProcessedComputable<DecimalSource>;
} }
>; >;

View file

@ -1,11 +1,11 @@
<template> <template>
<button <button
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
@click="selectTab" @click="selectTab"
class="tabButton" class="tabButton"
:style="[ :style="[
{ {
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
glowColorStyle, glowColorStyle,
unref(style) ?? {} unref(style) ?? {}
@ -21,7 +21,7 @@
<script lang="ts"> <script lang="ts">
import type { CoercableComponent, StyleValue } from "features/feature"; import type { CoercableComponent, StyleValue } from "features/feature";
import { Visibility } from "features/feature"; import { isHidden, isVisible, Visibility } from "features/feature";
import { getNotifyStyle } from "game/notifications"; import { getNotifyStyle } from "game/notifications";
import { computeComponent, processedPropType, unwrapRef } from "util/vue"; import { computeComponent, processedPropType, unwrapRef } from "util/vue";
import { computed, defineComponent, toRefs, unref } from "vue"; import { computed, defineComponent, toRefs, unref } from "vue";
@ -29,7 +29,7 @@ import { computed, defineComponent, toRefs, unref } from "vue";
export default defineComponent({ export default defineComponent({
props: { props: {
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
display: { display: {
@ -50,7 +50,7 @@ export default defineComponent({
const glowColorStyle = computed(() => { const glowColorStyle = computed(() => {
const color = unwrapRef(glowColor); const color = unwrapRef(glowColor);
if (!color) { if (color != null) {
return {}; return {};
} }
if (unref(floating)) { if (unref(floating)) {
@ -68,7 +68,9 @@ export default defineComponent({
component, component,
glowColorStyle, glowColorStyle,
unref, unref,
Visibility Visibility,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -1,11 +1,11 @@
<template> <template>
<div <div
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
class="tab-family-container" class="tab-family-container"
:class="{ ...unref(classes), ...tabClasses }" :class="{ ...unref(classes), ...tabClasses }"
:style="[ :style="[
{ {
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
unref(style) ?? [], unref(style) ?? [],
tabStyle ?? [] tabStyle ?? []
@ -37,7 +37,7 @@
import Sticky from "components/layout/Sticky.vue"; import Sticky from "components/layout/Sticky.vue";
import themes from "data/themes"; import themes from "data/themes";
import type { CoercableComponent, StyleValue } from "features/feature"; import type { CoercableComponent, StyleValue } from "features/feature";
import { Visibility } from "features/feature"; import { isHidden, isVisible, Visibility } from "features/feature";
import type { GenericTab } from "features/tabs/tab"; import type { GenericTab } from "features/tabs/tab";
import TabButton from "features/tabs/TabButton.vue"; import TabButton from "features/tabs/TabButton.vue";
import type { GenericTabButton } from "features/tabs/tabFamily"; import type { GenericTabButton } from "features/tabs/tabFamily";
@ -49,7 +49,7 @@ import { computed, defineComponent, shallowRef, toRefs, unref, watchEffect } fro
export default defineComponent({ export default defineComponent({
props: { props: {
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
activeTab: { activeTab: {
@ -123,7 +123,9 @@ export default defineComponent({
Visibility, Visibility,
component, component,
gatherButtonProps, gatherButtonProps,
unref unref,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -1,5 +1,12 @@
import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; import type { CoercableComponent, OptionsFunc, Replace, StyleValue } from "features/feature";
import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; import {
Component,
GatherProps,
getUniqueID,
isVisible,
setDefault,
Visibility
} from "features/feature";
import TabButtonComponent from "features/tabs/TabButton.vue"; import TabButtonComponent from "features/tabs/TabButton.vue";
import TabFamilyComponent from "features/tabs/TabFamily.vue"; import TabFamilyComponent from "features/tabs/TabFamily.vue";
import type { Persistent } from "game/persistence"; import type { Persistent } from "game/persistence";
@ -20,7 +27,7 @@ export const TabButtonType = Symbol("TabButton");
export const TabFamilyType = Symbol("TabFamily"); export const TabFamilyType = Symbol("TabFamily");
export interface TabButtonOptions { export interface TabButtonOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
tab: Computable<GenericTab | CoercableComponent>; tab: Computable<GenericTab | CoercableComponent>;
display: Computable<CoercableComponent>; display: Computable<CoercableComponent>;
classes?: Computable<Record<string, boolean>>; classes?: Computable<Record<string, boolean>>;
@ -48,12 +55,12 @@ export type TabButton<T extends TabButtonOptions> = Replace<
export type GenericTabButton = Replace< export type GenericTabButton = Replace<
TabButton<TabButtonOptions>, TabButton<TabButtonOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;
export interface TabFamilyOptions { export interface TabFamilyOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
classes?: Computable<Record<string, boolean>>; classes?: Computable<Record<string, boolean>>;
style?: Computable<StyleValue>; style?: Computable<StyleValue>;
buttonContainerClasses?: Computable<Record<string, boolean>>; buttonContainerClasses?: Computable<Record<string, boolean>>;
@ -81,7 +88,7 @@ export type TabFamily<T extends TabFamilyOptions> = Replace<
export type GenericTabFamily = Replace< export type GenericTabFamily = Replace<
TabFamily<TabFamilyOptions>, TabFamily<TabFamilyOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;
@ -123,15 +130,10 @@ export function createTabFamily<T extends TabFamilyOptions>(
tabFamily.selected = selected; tabFamily.selected = selected;
tabFamily.activeTab = computed(() => { tabFamily.activeTab = computed(() => {
const tabs = unref(processedTabFamily.tabs); const tabs = unref(processedTabFamily.tabs);
if ( if (selected.value in tabs && isVisible(tabs[selected.value].visibility)) {
selected.value in tabs &&
unref(tabs[selected.value].visibility) === Visibility.Visible
) {
return unref(tabs[selected.value].tab); return unref(tabs[selected.value].tab);
} }
const firstTab = Object.values(tabs).find( const firstTab = Object.values(tabs).find(tab => isVisible(tab.visibility));
tab => unref(tab.visibility) === Visibility.Visible
);
if (firstTab) { if (firstTab) {
return unref(firstTab.tab); return unref(firstTab.tab);
} }

View file

@ -1,7 +1,7 @@
<template> <template>
<div <div
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="{ visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined }" :style="{ visibility: isHidden(visibility) ? 'hidden' : undefined }"
:class="{ :class="{
treeNode: true, treeNode: true,
can: unref(canClick), can: unref(canClick),
@ -37,7 +37,7 @@
import MarkNode from "components/MarkNode.vue"; import MarkNode from "components/MarkNode.vue";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import type { CoercableComponent, StyleValue } from "features/feature"; import type { CoercableComponent, StyleValue } from "features/feature";
import { Visibility } from "features/feature"; import { isHidden, isVisible, Visibility } from "features/feature";
import { import {
computeOptionalComponent, computeOptionalComponent,
isCoercableComponent, isCoercableComponent,
@ -51,7 +51,7 @@ export default defineComponent({
props: { props: {
display: processedPropType<CoercableComponent>(Object, String, Function), display: processedPropType<CoercableComponent>(Object, String, Function),
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
style: processedPropType<StyleValue>(String, Object, Array), style: processedPropType<StyleValue>(String, Object, Array),
@ -87,7 +87,9 @@ export default defineComponent({
comp, comp,
unref, unref,
Visibility, Visibility,
isCoercableComponent isCoercableComponent,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -23,7 +23,7 @@ export const TreeNodeType = Symbol("TreeNode");
export const TreeType = Symbol("Tree"); export const TreeType = Symbol("Tree");
export interface TreeNodeOptions { export interface TreeNodeOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
canClick?: Computable<boolean>; canClick?: Computable<boolean>;
color?: Computable<string>; color?: Computable<string>;
display?: Computable<CoercableComponent>; display?: Computable<CoercableComponent>;
@ -60,7 +60,7 @@ export type TreeNode<T extends TreeNodeOptions> = Replace<
export type GenericTreeNode = Replace< export type GenericTreeNode = Replace<
TreeNode<TreeNodeOptions>, TreeNode<TreeNodeOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
canClick: ProcessedComputable<boolean>; canClick: ProcessedComputable<boolean>;
} }
>; >;
@ -141,7 +141,7 @@ export interface TreeBranch extends Omit<Link, "startNode" | "endNode"> {
} }
export interface TreeOptions { export interface TreeOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
nodes: Computable<GenericTreeNode[][]>; nodes: Computable<GenericTreeNode[][]>;
leftSideNodes?: Computable<GenericTreeNode[]>; leftSideNodes?: Computable<GenericTreeNode[]>;
rightSideNodes?: Computable<GenericTreeNode[]>; rightSideNodes?: Computable<GenericTreeNode[]>;
@ -175,7 +175,7 @@ export type Tree<T extends TreeOptions> = Replace<
export type GenericTree = Replace< export type GenericTree = Replace<
Tree<TreeOptions>, Tree<TreeOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;

View file

@ -1,9 +1,9 @@
<template> <template>
<button <button
v-if="unref(visibility) !== Visibility.None" v-if="isVisible(visibility)"
:style="[ :style="[
{ {
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined visibility: isHidden(visibility) ? 'hidden' : undefined
}, },
unref(style) ?? {} unref(style) ?? {}
]" ]"
@ -29,7 +29,7 @@ import "components/common/features.css";
import MarkNode from "components/MarkNode.vue"; import MarkNode from "components/MarkNode.vue";
import Node from "components/Node.vue"; import Node from "components/Node.vue";
import type { StyleValue } from "features/feature"; import type { StyleValue } from "features/feature";
import { jsx, Visibility } from "features/feature"; import { isHidden, isVisible, jsx, Visibility } from "features/feature";
import type { GenericUpgrade } from "features/upgrades/upgrade"; import type { GenericUpgrade } from "features/upgrades/upgrade";
import { displayRequirements, Requirements } from "game/requirements"; import { displayRequirements, Requirements } from "game/requirements";
import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue"; import { coerceComponent, isCoercableComponent, processedPropType, unwrapRef } from "util/vue";
@ -43,7 +43,7 @@ export default defineComponent({
required: true required: true
}, },
visibility: { visibility: {
type: processedPropType<Visibility>(Number), type: processedPropType<Visibility | boolean>(Number, Boolean),
required: true required: true
}, },
style: processedPropType<StyleValue>(String, Object, Array), style: processedPropType<StyleValue>(String, Object, Array),
@ -115,7 +115,9 @@ export default defineComponent({
return { return {
component, component,
unref, unref,
Visibility Visibility,
isVisible,
isHidden
}; };
} }
}); });

View file

@ -38,7 +38,7 @@ import { computed, Ref, unref } from "vue";
export const UpgradeType = Symbol("Upgrade"); export const UpgradeType = Symbol("Upgrade");
export interface UpgradeOptions { export interface UpgradeOptions {
visibility?: Computable<Visibility>; visibility?: Computable<Visibility | boolean>;
classes?: Computable<Record<string, boolean>>; classes?: Computable<Record<string, boolean>>;
style?: Computable<StyleValue>; style?: Computable<StyleValue>;
display?: Computable< display?: Computable<
@ -79,7 +79,7 @@ export type Upgrade<T extends UpgradeOptions> = Replace<
export type GenericUpgrade = Replace< export type GenericUpgrade = Replace<
Upgrade<UpgradeOptions>, Upgrade<UpgradeOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
} }
>; >;

View file

@ -1,5 +1,5 @@
import { isArray } from "@vue/shared"; import { isArray } from "@vue/shared";
import { CoercableComponent, jsx, setDefault, Visibility } from "features/feature"; import { CoercableComponent, isVisible, jsx, setDefault, Visibility } from "features/feature";
import { displayResource, Resource } from "features/resources/resource"; import { displayResource, Resource } from "features/resources/resource";
import Decimal, { DecimalSource } from "lib/break_eternity"; import Decimal, { DecimalSource } from "lib/break_eternity";
import { import {
@ -35,7 +35,7 @@ export interface Requirement {
/** /**
* Whether or not this requirement should be displayed in Vue Features. {@link displayRequirements} will respect this property. * Whether or not this requirement should be displayed in Vue Features. {@link displayRequirements} will respect this property.
*/ */
visibility: ProcessedComputable<Visibility.Visible | Visibility.None>; visibility: ProcessedComputable<Visibility.Visible | Visibility.None | boolean>;
/** /**
* Whether or not this requirement has been met. * Whether or not this requirement has been met.
*/ */
@ -73,7 +73,7 @@ export interface CostRequirementOptions {
/** /**
* Pass-through to {@link Requirement.visibility}. * Pass-through to {@link Requirement.visibility}.
*/ */
visibility?: Computable<Visibility.Visible | Visibility.None>; visibility?: Computable<Visibility.Visible | Visibility.None | boolean>;
/** /**
* Pass-through to {@link Requirement.requiresPay}. If not set to false, the default {@link pay} function will remove {@link cost} from {@link resource}. * Pass-through to {@link Requirement.requiresPay}. If not set to false, the default {@link pay} function will remove {@link cost} from {@link resource}.
*/ */
@ -193,10 +193,10 @@ export function createCostRequirement<T extends CostRequirementOptions>(
* @param feature The feature to check the visibility of * @param feature The feature to check the visibility of
*/ */
export function createVisibilityRequirement(feature: { export function createVisibilityRequirement(feature: {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility | boolean>;
}): Requirement { }): Requirement {
return createLazyProxy(() => ({ return createLazyProxy(() => ({
requirementMet: computed(() => unref(feature.visibility) === Visibility.Visible), requirementMet: computed(() => isVisible(feature.visibility)),
visibility: Visibility.None, visibility: Visibility.None,
requiresPay: false requiresPay: false
})); }));
@ -256,7 +256,7 @@ export function maxRequirementsMet(requirements: Requirements): DecimalSource {
*/ */
export function displayRequirements(requirements: Requirements, amount: DecimalSource = 1) { export function displayRequirements(requirements: Requirements, amount: DecimalSource = 1) {
if (isArray(requirements)) { if (isArray(requirements)) {
requirements = requirements.filter(r => unref(r.visibility) === Visibility.Visible); requirements = requirements.filter(r => isVisible(r.visibility));
if (requirements.length === 1) { if (requirements.length === 1) {
requirements = requirements[0]; requirements = requirements[0];
} }

View file

@ -3,7 +3,13 @@ import Col from "components/layout/Column.vue";
import Row from "components/layout/Row.vue"; import Row from "components/layout/Row.vue";
import themes from "data/themes"; import themes from "data/themes";
import type { CoercableComponent, GenericComponent, JSXFunction } from "features/feature"; import type { CoercableComponent, GenericComponent, JSXFunction } from "features/feature";
import { Component as ComponentKey, GatherProps, jsx, Visibility } from "features/feature"; import {
Component as ComponentKey,
GatherProps,
isVisible,
jsx,
Visibility
} from "features/feature";
import settings from "game/settings"; import settings from "game/settings";
import type { ProcessedComputable } from "util/computed"; import type { ProcessedComputable } from "util/computed";
import { DoNotCache } from "util/computed"; import { DoNotCache } from "util/computed";
@ -191,7 +197,7 @@ export function setupHoldToClick(
} }
export function getFirstFeature< export function getFirstFeature<
T extends VueFeature & { visibility: ProcessedComputable<Visibility> } T extends VueFeature & { visibility: ProcessedComputable<Visibility | boolean> }
>( >(
features: T[], features: T[],
filter: (feature: T) => boolean filter: (feature: T) => boolean
@ -201,9 +207,7 @@ export function getFirstFeature<
hasCollapsedContent: Ref<boolean>; hasCollapsedContent: Ref<boolean>;
} { } {
const filteredFeatures = computed(() => const filteredFeatures = computed(() =>
features.filter( features.filter(feature => isVisible(feature.visibility) && filter(feature))
feature => unref(feature.visibility) === Visibility.Visible && filter(feature)
)
); );
return { return {
firstFeature: computed(() => filteredFeatures.value[0]), firstFeature: computed(() => filteredFeatures.value[0]),