continue script setup refactoring

This commit is contained in:
Alexander Drozdov
2025-01-06 13:37:58 +02:00
parent 4c44316816
commit 0073f3ccd9
8 changed files with 171 additions and 205 deletions

View File

@@ -1,18 +1,18 @@
<template>
<div class="max-w-md p-2">
<div class="mb-4 flex">
<div class="flex flex-col gap-4 p-2 max-w-md">
<div class="flex">
<label class="flex-1">{{ t('item.open_on_wiki') }}</label>
<hotkey-input v-model="wikiKey" class="w-48" />
</div>
<div class="mb-4 flex">
<div class="flex">
<label class="flex-1">{{ t('item.open_on_poedb') }}</label>
<hotkey-input v-model="poedbKey" class="w-48" />
</div>
<div v-if="isEnglish" class="mb-4 flex">
<div v-if="isEnglish" class="flex">
<label class="flex-1">Open base item on Craft of Exile</label>
<hotkey-input v-model="craftOfExileKey" class="w-48" />
</div>
<div class="mb-4 flex">
<div class="flex">
<label class="flex-1">{{ t('item.find_in_stash') }}</label>
<hotkey-input v-model="stashSearchKey" class="w-48" />
</div>
@@ -20,27 +20,25 @@
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
export default {
name: 'item.info'
}
</script>
<script setup lang="ts">
import { defineProps, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { configProp, configModelValue, findWidget } from '../settings/utils.js'
import type { ItemCheckWidget } from './widget.js'
import HotkeyInput from '../settings/HotkeyInput.vue'
export default defineComponent({
name: 'item.info',
components: { HotkeyInput },
props: configProp(),
setup (props) {
const { t } = useI18n()
const props = defineProps(configProp())
return {
t,
isEnglish: computed(() => props.config.language === 'en'),
wikiKey: configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'wikiKey'),
poedbKey: configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'poedbKey'),
craftOfExileKey: configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'craftOfExileKey'),
stashSearchKey: configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'stashSearchKey')
}
}
})
const isEnglish = computed(() => props.config.language === 'en')
const wikiKey = configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'wikiKey')
const poedbKey = configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'poedbKey')
const craftOfExileKey = configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'craftOfExileKey')
const stashSearchKey = configModelValue(() => findWidget<ItemCheckWidget>('item-check', props.config)!, 'stashSearchKey')
const { t } = useI18n()
</script>

View File

@@ -1,6 +1,6 @@
<template>
<div class="max-w-md p-2">
<div class="mb-4 flex">
<div class="flex flex-col gap-4 p-2 max-w-md">
<div class="flex">
<label class="flex-1">{{ t('item_search.ocr_gems_key') }}</label>
<hotkey-input v-model="ocrGemsKey" class="w-48" />
</div>
@@ -8,23 +8,21 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default {
name: 'item_search.name'
}
</script>
<script setup lang="ts">
import { defineProps } from 'vue'
import { useI18n } from 'vue-i18n'
import { configProp, configModelValue, findWidget } from '../settings/utils.js'
import { ItemSearchWidget } from './widget.js'
import HotkeyInput from '../settings/HotkeyInput.vue'
export default defineComponent({
name: 'item_search.name',
components: { HotkeyInput },
props: configProp(),
setup (props) {
const { t } = useI18n()
const props = defineProps(configProp())
return {
t,
ocrGemsKey: configModelValue(() => findWidget<ItemSearchWidget>('item-search', props.config)!, 'ocrGemsKey')
}
}
})
const ocrGemsKey = configModelValue(() => findWidget<ItemSearchWidget>('item-search', props.config)!, 'ocrGemsKey')
const { t } = useI18n()
</script>

View File

@@ -34,8 +34,7 @@ import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { ItemRarity, ParsedItem } from '@/parser'
import { prepareMapStats } from './prepare-map-stats'
import { STAT_BY_MATCH_STR } from '@/assets/data'
import { MapCheckConfig } from './common.js'
import { type MapCheckConfig, isOutdated } from './common.js'
import MapStatButton from './MapStatButton.vue'
import FullscreenImage from '@/web/ui/FullscreenImage.vue'
@@ -48,12 +47,9 @@ const props = defineProps<{
const { t } = useI18n()
const hasOutdatedTranslation = computed<boolean>(() => {
const idx = props.config.profile - 1
const { profile } = props.config
return props.config.selectedStats
.some(entry =>
entry.decision[idx] !== '-' &&
entry.decision[idx] !== 's' &&
STAT_BY_MATCH_STR(entry.matcher) == null)
.some(entry => isOutdated(profile, entry))
})
const mapName = computed(() => props.item.info.name)

View File

@@ -23,7 +23,7 @@
import { defineComponent, computed, PropType } from 'vue'
import { useI18n } from 'vue-i18n'
import UiRadio from '@/web/ui/UiRadio.vue'
import { StatMatcher, StatTag, decisionHasColor, decisionCreate, MapCheckConfig } from './common.js'
import { StatMatcher, StatTag, decisionHasColor, decisionCreate, MapCheckStat } from './common.js'
export default defineComponent({
emits: [],
@@ -34,7 +34,7 @@ export default defineComponent({
required: true
},
selectedStats: {
type: Array as PropType<MapCheckConfig['selectedStats']>,
type: Array as PropType<MapCheckStat[]>,
required: true
},
profile: {

View File

@@ -1,10 +1,14 @@
import { STAT_BY_MATCH_STR } from '@/assets/data'
export interface MapCheckConfig {
profile: number
showNewStats: boolean
selectedStats: Array<{
matcher: string
decision: string
}>
selectedStats: MapCheckStat[]
}
export interface MapCheckStat {
matcher: string
decision: string
}
export enum StatTag {
@@ -44,3 +48,8 @@ export function decisionCreate (value: string, profileName: number, updateSet =
split[idx] = value
return split.join('')
}
export function isOutdated (profileName: number, stat: MapCheckStat): boolean {
return decisionHasColor(stat.decision, profileName) &&
STAT_BY_MATCH_STR(stat.matcher) == null
}

View File

@@ -1,9 +1,9 @@
<template>
<div class="flex flex-col overflow-hidden h-full">
<div class="p-1 flex">
<div class="flex p-1">
<input :placeholder="t('Search') + '...'" v-model="search" class="bg-gray-900 rounded px-1">
<ui-toggle v-model="onlySelected" class="mx-2">{{ t(':search_selected') }}</ui-toggle>
<ui-toggle v-model="showNewStats" class="ml-12">{{ t(':new_mods_icon') }}</ui-toggle>
<UiToggle v-model="onlySelected" class="mx-2">{{ t(':search_selected') }}</UiToggle>
<UiToggle v-model="showNewStats" class="ml-12">{{ t(':new_mods_icon') }}</UiToggle>
</div>
<div class="flex items-baseline py-1 shadow">
<div class="flex-1 px-2 leading-none">{{ t(':search_stat_col', [filteredStats.length]) }}</div>
@@ -30,15 +30,12 @@
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import { useI18nNs } from '@/web/i18n'
import UiToggle from '@/web/ui/UiToggle.vue'
import { configProp, findWidget } from '../settings/utils'
import type { ItemCheckWidget } from '../item-check/widget.js'
import { STATS_ITERATOR, STAT_BY_MATCH_STR } from '@/assets/data'
import SettingsMatcherEntry from './SettingsMatcherEntry.vue'
import VirtualScroll from '../ui/VirtualScroll.vue'
import { StatMatcher, StatTag, decisionHasColor } from './common.js'
import { STATS_ITERATOR } from '@/assets/data'
import { StatMatcher, StatTag, decisionHasColor, isOutdated } from './common.js'
export default {
name: 'map_check.name'
}
function tagToShowOrder (tag?: StatTag): number {
switch (tag) {
@@ -48,89 +45,82 @@ function tagToShowOrder (tag?: StatTag): number {
return 0
}
export default defineComponent({
name: 'map_check.name',
components: {
SettingsMatcherEntry,
VirtualScroll,
UiToggle
},
props: configProp(),
setup (props) {
const search = ref('')
const onlySelected = ref(false)
function findAllAreaMods (): StatMatcher[] {
const out: StatMatcher[] = []
for (const stat of STATS_ITERATOR('AreaMods')) {
if (!stat.fromAreaMods && !stat.fromUberAreaMods && !stat.fromHeistAreaMods) continue
const widget = computed(() => findWidget<ItemCheckWidget>('item-check', props.config)!)
const tag = (stat.fromHeistAreaMods && !stat.fromAreaMods) ? StatTag.HeistExclusive
: (stat.fromUberAreaMods && !stat.fromAreaMods) ? StatTag.UberMapExclusive : undefined
const areaStatsDb = computed(() => {
const out: StatMatcher[] = []
for (const stat of STATS_ITERATOR('AreaMods')) {
if (!stat.fromAreaMods && !stat.fromUberAreaMods && !stat.fromHeistAreaMods) continue
const tag = (stat.fromHeistAreaMods && !stat.fromAreaMods) ? StatTag.HeistExclusive
: (stat.fromUberAreaMods && !stat.fromAreaMods) ? StatTag.UberMapExclusive : undefined
for (const c of stat.matchers) {
out.push({ matchStr: c.string, tag })
}
}
out.sort((a, b) =>
(tagToShowOrder(a.tag) - tagToShowOrder(b.tag)) ||
a.matchStr.localeCompare(b.matchStr))
return out
})
const selectedProfileMatchers = computed(() => {
const { profile } = widget.value.maps
return new Set(
widget.value.maps.selectedStats
.filter((entry) => decisionHasColor(entry.decision, profile))
.map(entry => entry.matcher))
})
const showNewStats = computed<boolean>({
get () { return widget.value.maps.showNewStats },
set (value) { widget.value.maps.showNewStats = value }
})
const outdatedTranslationList = computed<StatMatcher[]>(() => {
const { profile } = widget.value.maps
return widget.value.maps.selectedStats
.filter(entry =>
decisionHasColor(entry.decision, profile) &&
STAT_BY_MATCH_STR(entry.matcher) == null)
.map(entry => ({ matchStr: entry.matcher, tag: StatTag.Outdated }))
})
const { t } = useI18nNs('map_check')
return {
t,
search,
onlySelected,
showNewStats,
filteredStats: computed<StatMatcher[]>(() => {
const q = search.value.toLowerCase().split(' ')
const filtered = areaStatsDb.value
.filter(stat => {
const searchStr = stat.matchStr.toLowerCase()
if (!q.every(part => searchStr.includes(part))) return false
if (onlySelected.value) {
return selectedProfileMatchers.value.has(stat.matchStr)
}
return true
})
return [
...outdatedTranslationList.value,
...filtered
]
}),
selectedStats: computed(() => widget.value.maps.selectedStats),
profile: computed(() => widget.value.maps.profile),
fontSize: computed(() => props.config.fontSize)
for (const c of stat.matchers) {
out.push({ matchStr: c.string, tag })
}
}
})
out.sort((a, b) =>
(tagToShowOrder(a.tag) - tagToShowOrder(b.tag)) ||
a.matchStr.localeCompare(b.matchStr))
return out
}
</script>
<script setup lang="ts">
import { computed, defineProps, ref } from 'vue'
import { useI18nNs } from '@/web/i18n'
import { configProp, findWidget, configModelValue } from '../settings/utils'
import type { ItemCheckWidget } from '../item-check/widget.js'
import UiToggle from '@/web/ui/UiToggle.vue'
import VirtualScroll from '@/web/ui/VirtualScroll.vue'
import SettingsMatcherEntry from './SettingsMatcherEntry.vue'
const props = defineProps(configProp())
const widget = computed(() => findWidget<ItemCheckWidget>('item-check', props.config)!)
const selectedProfileMatchers = computed(() => {
const { profile } = widget.value.maps
const matchers = new Set<string>()
for (const entry of widget.value.maps.selectedStats) {
if (decisionHasColor(entry.decision, profile)) {
matchers.add(entry.matcher)
}
}
return matchers
})
const outdatedTranslationList = computed<StatMatcher[]>(() => {
const { profile } = widget.value.maps
return widget.value.maps.selectedStats
.filter(entry => isOutdated(profile, entry))
.map(entry => ({ matchStr: entry.matcher, tag: StatTag.Outdated }))
})
const areaStatsDb = computed(() => findAllAreaMods())
const search = ref('')
const onlySelected = ref(false)
const filteredStats = computed<StatMatcher[]>(() => {
const q = search.value.toLowerCase().split(' ')
const filtered = areaStatsDb.value
.filter(stat => {
const searchStr = stat.matchStr.toLowerCase()
if (!q.every(part => searchStr.includes(part))) return false
if (onlySelected.value) {
return selectedProfileMatchers.value.has(stat.matchStr)
}
return true
})
return [
...outdatedTranslationList.value,
...filtered
]
})
const selectedStats = computed(() => widget.value.maps.selectedStats)
const profile = computed(() => widget.value.maps.profile)
const fontSize = computed(() => props.config.fontSize)
const showNewStats = configModelValue(() => widget.value.maps, 'showNewStats')
const { t } = useI18nNs('map_check')
</script>

View File

@@ -11,35 +11,22 @@
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue'
<script setup lang="ts">
import { defineProps, shallowRef, computed } from 'vue'
export default defineComponent({
name: 'FullscreenImage',
props: {
src: {
type: String,
required: true
},
disabled: {
type: Boolean,
default: false
}
},
setup (props) {
const isHovered = ref(false)
return {
isHovered,
resolvedSrc: computed(() => {
if (props.src.includes('://')) {
return props.src
} else {
return (props.src.length < 32)
? `${import.meta.env.BASE_URL}images/${props.src}`
: `/uploads/${props.src}`
}
})
}
const props = defineProps<{
src: string
disabled?: boolean
}>()
const isHovered = shallowRef(false)
const resolvedSrc = computed(() => {
if (props.src.includes('://')) {
return props.src
} else {
return (props.src.length < 32)
? `${import.meta.env.BASE_URL}images/${props.src}`
: `/uploads/${props.src}`
}
})
</script>

View File

@@ -9,43 +9,31 @@
</span>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
<script setup lang="ts">
import { computed, defineProps } from 'vue'
export default defineComponent({
props: {
text: {
type: String,
required: true
},
roll: {
type: Number,
default: undefined
const props = defineProps<{
text: string
roll?: number
}>()
const parts = computed(() => {
const res = [] as Array<{ text: string, placeholder?: boolean }>
props.text.split(/(?<![#])[+-]?[#]/gm).forEach((text, idx, parts) => {
if (text !== '') {
res.push({ text })
}
},
setup (props) {
return {
parts: computed(() => {
const res = [] as Array<{ text: string, placeholder?: boolean }>
props.text.split(/(?<![#])[+-]?[#]/gm).forEach((text, idx, parts) => {
if (text !== '') {
res.push({ text })
}
if (idx !== (parts.length - 1)) {
if (props.roll == null) {
res.push({ text: '#' })
} else {
res.push({
text: String(props.roll),
placeholder: true
})
}
}
if (idx !== (parts.length - 1)) {
if (props.roll == null) {
res.push({ text: '#' })
} else {
res.push({
text: String(props.roll),
placeholder: true
})
return res
})
}
}
}
})
return res
})
</script>