mirror of
https://github.com/Kvan7/Exiled-Exchange-2.git
synced 2026-09-25 22:25:58 +00:00
vue3
This commit is contained in:
@@ -22,51 +22,59 @@
|
||||
</widget>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Widget from './Widget'
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, inject, PropType } from 'vue'
|
||||
import Widget from './Widget.vue'
|
||||
import { MainProcess } from '@/ipc/main-process-bindings'
|
||||
import { TOGGLE_DELVE_GRID } from '@/ipc/ipc-event'
|
||||
import { Widget as IWidget, WidgetManager } from './interfaces'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
components: { Widget },
|
||||
inject: ['wm'],
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
type: Object as PropType<IWidget>,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
created () {
|
||||
setup (props) {
|
||||
const wm = inject<WidgetManager>('wm')!
|
||||
|
||||
MainProcess.addEventListener(TOGGLE_DELVE_GRID, () => {
|
||||
if (this.config.wmWants === 'hide') {
|
||||
this.wm.show(this.config.wmId)
|
||||
if (props.config.wmWants === 'hide') {
|
||||
wm.show(props.config.wmId)
|
||||
} else {
|
||||
this.wm.hide(this.config.wmId)
|
||||
wm.hide(props.config.wmId)
|
||||
}
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
anchor () {
|
||||
const height = Math.round(this.wm.height * 808 / 1080)
|
||||
|
||||
const anchor = computed(() => {
|
||||
const height = Math.round(wm.height * 808 / 1080)
|
||||
const width = Math.round(height * 1030 / 808)
|
||||
const top = Math.round(this.wm.height * 67 / 1080)
|
||||
const cell = Math.round(this.wm.height * 97 / 1080)
|
||||
const top = Math.round(wm.height * 67 / 1080)
|
||||
const cell = Math.round(wm.height * 97 / 1080)
|
||||
|
||||
return {
|
||||
pos: 'tc',
|
||||
y: (top / this.wm.height) * 100,
|
||||
y: (top / wm.height) * 100,
|
||||
x: 50,
|
||||
height,
|
||||
width,
|
||||
cell
|
||||
}
|
||||
},
|
||||
cellSize () {
|
||||
})
|
||||
|
||||
const cellSize = computed(() => {
|
||||
return {
|
||||
width: `${this.anchor.cell}px`,
|
||||
height: `${this.anchor.cell}px`
|
||||
width: `${anchor.value.cell}px`,
|
||||
height: `${anchor.value.cell}px`
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
anchor,
|
||||
cellSize
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -36,51 +36,53 @@
|
||||
</widget>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Widget from './Widget'
|
||||
<script lang="ts">
|
||||
import { defineComponent, inject, PropType } from 'vue'
|
||||
import Widget from './Widget.vue'
|
||||
import DndContainer from 'vuedraggable'
|
||||
import { MainProcess } from '@/ipc/main-process-bindings'
|
||||
import { WidgetManager, StashSearchWidget } from './interfaces'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
components: { Widget, DndContainer },
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
type: Object as PropType<StashSearchWidget>,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
inject: ['wm'],
|
||||
data () {
|
||||
if (this.config.wmFlags[0] === 'uninitialized') {
|
||||
this.config.wmFlags = ['invisible-on-blur']
|
||||
this.$set(this.config, 'anchor', {
|
||||
setup (props) {
|
||||
const wm = inject<WidgetManager>('wm')!
|
||||
|
||||
if (props.config.wmFlags[0] === 'uninitialized') {
|
||||
props.config.wmFlags = ['invisible-on-blur']
|
||||
props.config.anchor = {
|
||||
pos: 'tl',
|
||||
x: 30,
|
||||
y: 30
|
||||
})
|
||||
this.$set(this.config, 'entries', [{
|
||||
}
|
||||
props.config.entries = [{
|
||||
id: 1, text: 'Currency'
|
||||
}])
|
||||
this.wm.show(this.config.wmId)
|
||||
}]
|
||||
wm.show(props.config.wmId)
|
||||
}
|
||||
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
removeEntry (id) {
|
||||
this.config.entries = this.config.entries.filter(_ => _.id !== id)
|
||||
},
|
||||
addEntry () {
|
||||
this.config.entries.push({
|
||||
id: Math.max(0, ...this.config.entries.map(_ => _.id)) + 1,
|
||||
text: ''
|
||||
})
|
||||
},
|
||||
stashSearch (text) {
|
||||
MainProcess.stashSearch(text)
|
||||
return {
|
||||
removeEntry (id: number) {
|
||||
props.config.entries = props.config.entries.filter(_ => _.id !== id)
|
||||
},
|
||||
addEntry () {
|
||||
props.config.entries.push({
|
||||
id: Math.max(0, ...props.config.entries.map(_ => _.id)) + 1,
|
||||
text: ''
|
||||
})
|
||||
},
|
||||
stashSearch (text: string) {
|
||||
MainProcess.stashSearch(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<i18n>
|
||||
|
||||
@@ -13,75 +13,81 @@
|
||||
</widget>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Widget from './Widget'
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, inject, ref, onUnmounted, computed } from 'vue'
|
||||
import Widget from './Widget.vue'
|
||||
import { Duration } from 'luxon'
|
||||
import { WidgetManager, StopwatchWidget } from './interfaces'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
components: { Widget },
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
type: Object as PropType<StopwatchWidget>,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
inject: ['wm'],
|
||||
data () {
|
||||
if (this.config.wmFlags[0] === 'uninitialized') {
|
||||
this.config.wmFlags = []
|
||||
this.$set(this.config, 'anchor', {
|
||||
setup (props) {
|
||||
const wm = inject<WidgetManager>('wm')!
|
||||
|
||||
if (props.config.wmFlags[0] === 'uninitialized') {
|
||||
props.config.wmFlags = []
|
||||
props.config.anchor = {
|
||||
pos: 'cc',
|
||||
x: 50,
|
||||
y: 50
|
||||
})
|
||||
this.wm.show(this.config.wmId)
|
||||
}
|
||||
wm.show(props.config.wmId)
|
||||
}
|
||||
|
||||
return {
|
||||
isRunning: false,
|
||||
millis: 0,
|
||||
prevTick: 0
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.timerId_ = setInterval(this.updateTime, 1000)
|
||||
},
|
||||
destroyed () {
|
||||
clearInterval(this.timerId_)
|
||||
},
|
||||
computed: {
|
||||
formatted () {
|
||||
const dur = Duration.fromMillis(this.millis).shiftTo('hours', 'minutes', 'seconds')
|
||||
const isRunning = ref(false)
|
||||
const millis = ref(0)
|
||||
const prevTick = ref(0)
|
||||
|
||||
const timerId = setInterval(updateTime, 1000)
|
||||
onUnmounted(() => {
|
||||
clearInterval(timerId)
|
||||
})
|
||||
|
||||
const formatted = computed(() => {
|
||||
const dur = Duration.fromMillis(millis.value).shiftTo('hours', 'minutes', 'seconds')
|
||||
|
||||
return {
|
||||
h: String(dur.hours).padStart(2, '0'),
|
||||
m: String(dur.minutes).padStart(2, '0'),
|
||||
s: String(Math.floor(dur.seconds)).padStart(2, '0')
|
||||
}
|
||||
})
|
||||
|
||||
function start () {
|
||||
isRunning.value = true
|
||||
prevTick.value = Date.now()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
start () {
|
||||
this.isRunning = true
|
||||
this.prevTick = Date.now()
|
||||
},
|
||||
stop () {
|
||||
this.updateTime()
|
||||
this.isRunning = false
|
||||
},
|
||||
restart () {
|
||||
this.prevTick = Date.now()
|
||||
this.millis = 0
|
||||
},
|
||||
updateTime () {
|
||||
if (this.isRunning) {
|
||||
function stop () {
|
||||
updateTime()
|
||||
isRunning.value = false
|
||||
}
|
||||
function restart () {
|
||||
prevTick.value = Date.now()
|
||||
millis.value = 0
|
||||
}
|
||||
function updateTime () {
|
||||
if (isRunning.value) {
|
||||
const now = Date.now()
|
||||
this.millis += now - this.prevTick
|
||||
this.prevTick = now
|
||||
millis.value += now - prevTick.value
|
||||
prevTick.value = now
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
formatted,
|
||||
isRunning,
|
||||
start,
|
||||
stop,
|
||||
restart
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="postcss" module>
|
||||
|
||||
@@ -25,6 +25,7 @@ export interface Anchor {
|
||||
}
|
||||
|
||||
export interface WidgetManager {
|
||||
height: number
|
||||
active: boolean
|
||||
widgets: Widget[]
|
||||
show (wmId: number): void
|
||||
@@ -53,3 +54,15 @@ export interface MapCheckWidget extends Widget {
|
||||
valueDesirable: string
|
||||
}>
|
||||
}
|
||||
|
||||
export interface StopwatchWidget extends Widget {
|
||||
anchor: Anchor
|
||||
}
|
||||
|
||||
export interface StashSearchWidget extends Widget {
|
||||
anchor: Anchor
|
||||
entries: Array<{
|
||||
id: number
|
||||
text: string
|
||||
}>
|
||||
}
|
||||
|
||||
@@ -11,26 +11,24 @@
|
||||
<div id="price-window" class="layout-column flex-shrink-0 text-gray-200 pointer-events-auto" style="width: 28.75rem;">
|
||||
<app-titlebar @close="closePriceCheck" :title="title">
|
||||
<div class="flex">
|
||||
<ui-popper v-if="exaltedCost" trigger="clickToToggle" boundaries-selector="#price-window">
|
||||
<template slot="reference">
|
||||
<button class="titlebar-btn"><i class="fas fa-exchange-alt mt-px"></i> {{ exaltedCost }}</button>
|
||||
<ui-popover v-if="exaltedCost" trigger="click" boundary="#price-window">
|
||||
<template #target>
|
||||
<button class="titlebar-btn">
|
||||
<i class="fas fa-exchange-alt mt-px"></i> {{ exaltedCost }}
|
||||
</button>
|
||||
</template>
|
||||
<div class="popper">
|
||||
<div class="flex items-center justify-center flex-1">
|
||||
<div class="w-8 h-8 flex items-center justify-center">
|
||||
<img src="@/assets/images/exa.png" class="max-w-full max-h-full">
|
||||
</div>
|
||||
<i class="fas fa-arrow-right text-gray-600 px-2"></i>
|
||||
<span class="px-1 text-base">{{ Math.round(exaltedCost) }} <span class="font-sans">×</span></span>
|
||||
<div class="w-8 h-8 flex items-center justify-center">
|
||||
<img src="@/assets/images/chaos.png" class="max-w-full max-h-full">
|
||||
</div>
|
||||
</div>
|
||||
<template #content>
|
||||
<item-quick-price
|
||||
:min="exaltedCost"
|
||||
:max="exaltedCost"
|
||||
:item-img="require('@/assets/images/exa.png')"
|
||||
currency="chaos"
|
||||
/>
|
||||
<div v-for="i in 9" :key="i">
|
||||
<div class="text-left pl-1">{{ i / 10 }} exa ⇒ {{ Math.round(exaltedCost * i / 10) }} c</div>
|
||||
<div class="pl-1">{{ i / 10 }} exa ⇒ {{ Math.round(exaltedCost * i / 10) }} c</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui-popper>
|
||||
</template>
|
||||
</ui-popover>
|
||||
<button v-if="isLoading"
|
||||
class="titlebar-btn" title="Update price data"><i class="fas fa-sync-alt fa-spin"></i></button>
|
||||
</div>
|
||||
@@ -40,16 +38,16 @@
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex-grow layout-column">
|
||||
<app-bootstrap />
|
||||
<template>
|
||||
<template v-if="true">
|
||||
<check-position-circle
|
||||
v-if="showCheckPos"
|
||||
:position="checkPosition" style="z-index: -1;" />
|
||||
<unidentified-resolver :item="item" @identify="item = $event" />
|
||||
<checked-item :item="item" />
|
||||
<div v-if="isBrowserShown" class="bg-gray-900 px-6 py-2 truncate">
|
||||
<i18n path="Press {0} to switch between browser and game.">
|
||||
<i18n-t path="Press {0} to switch between browser and game.">
|
||||
<span class="bg-gray-400 text-gray-900 rounded px-1">{{ overlayKey }}</span>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -81,6 +79,7 @@ import RelatedItems from './related-items/RelatedItems'
|
||||
import RateLimiterState from './trade/RateLimiterState'
|
||||
import UnidentifiedResolver from './unidentified-resolver/UnidentifiedResolver'
|
||||
import CheckPositionCircle from './CheckPositionCircle'
|
||||
import ItemQuickPrice from '@/web/ui/ItemQuickPrice'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -89,7 +88,8 @@ export default {
|
||||
AppBootstrap,
|
||||
RelatedItems,
|
||||
RateLimiterState,
|
||||
CheckPositionCircle
|
||||
CheckPositionCircle,
|
||||
ItemQuickPrice
|
||||
},
|
||||
inject: ['wm'],
|
||||
provide () {
|
||||
|
||||
@@ -79,7 +79,7 @@ export default defineComponent({
|
||||
const showContrib = ref(false)
|
||||
const feedbackSent = ref(false)
|
||||
|
||||
watch(props.item, async (item) => {
|
||||
watch(() => props.item, async (item) => {
|
||||
try {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<img :src="item.icon" :alt="item.name" class="max-w-full max-h-full">
|
||||
</div>
|
||||
<i class="fas fa-arrow-right text-gray-600 px-2"></i>
|
||||
<span class="px-1 text-base whitespace-no-wrap overflow-hidden">{{ price(item).val | displayRounding(true) }} {{ price(item).curr === 'e' ? 'exa' : 'chaos' }}</span>
|
||||
<span class="px-1 text-base whitespace-no-wrap overflow-hidden">{{ price(item).val }} {{ price(item).curr === 'e' ? 'exa' : 'chaos' }}</span>
|
||||
</div>
|
||||
<div class="text-left text-gray-600 mb-1 whitespace-no-wrap overflow-hidden">{{ item.name }}</div>
|
||||
</div>
|
||||
@@ -20,7 +20,7 @@
|
||||
<img :src="item.icon" :alt="item.name" class="max-w-full max-h-full">
|
||||
</div>
|
||||
<i class="fas fa-arrow-right text-gray-600 px-2"></i>
|
||||
<span class="px-1 text-base whitespace-no-wrap overflow-hidden">{{ price(item).val | displayRounding(true) }} {{ price(item).curr === 'e' ? 'exa' : 'chaos' }}</span>
|
||||
<span class="px-1 text-base whitespace-no-wrap overflow-hidden">{{ price(item).val }} {{ price(item).curr === 'e' ? 'exa' : 'chaos' }}</span>
|
||||
</div>
|
||||
<div class="text-left text-gray-600 mb-1 whitespace-no-wrap overflow-hidden">{{ item.name }}</div>
|
||||
</div>
|
||||
@@ -28,41 +28,49 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, PropType } from 'vue'
|
||||
import { ITEM_DROP } from '@/assets/data'
|
||||
import { Prices, displayRounding } from '../Prices'
|
||||
import { Prices, displayRounding, ItemInfo } from '../Prices'
|
||||
import { getDetailsId } from '../trends/getDetailsId'
|
||||
import { ParsedItem } from '@/parser'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
type: Object as PropType<ParsedItem>,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
filters: { displayRounding },
|
||||
computed: {
|
||||
detailsId () {
|
||||
if (!this.item) return
|
||||
setup (props) {
|
||||
const detailsId = computed(() => {
|
||||
if (props.item) {
|
||||
return getDetailsId(props.item)
|
||||
}
|
||||
})
|
||||
|
||||
return getDetailsId(this.item)
|
||||
},
|
||||
result () {
|
||||
if (!this.detailsId) return
|
||||
const result = computed(() => {
|
||||
if (!detailsId.value) return
|
||||
|
||||
if (!ITEM_DROP.has(this.detailsId)) return null
|
||||
if (!ITEM_DROP.has(detailsId.value)) return null
|
||||
|
||||
const r = ITEM_DROP.get(this.detailsId)
|
||||
const r = ITEM_DROP.get(detailsId.value)!
|
||||
return {
|
||||
related: r.query.map(id => Prices.findByDetailsId(id)),
|
||||
items: r.items.map(id => Prices.findByDetailsId(id))
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
price (item) {
|
||||
return Prices.autoCurrency(item.receive.chaosValue, 'c')
|
||||
})
|
||||
|
||||
return {
|
||||
result,
|
||||
price (item: ItemInfo) {
|
||||
const _ = Prices.autoCurrency(item.receive.chaosValue, 'c')
|
||||
return {
|
||||
val: displayRounding(_.val, true),
|
||||
curr: _.curr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AppTitlebar',
|
||||
props: {
|
||||
title: {
|
||||
@@ -22,7 +24,7 @@ export default {
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="postcss">
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
text: {
|
||||
type: String,
|
||||
@@ -21,27 +23,29 @@ export default {
|
||||
default: undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
parts () {
|
||||
const res = []
|
||||
this.text.split(/(?<![#])[+-]?[#]/gm).forEach((text, idx, parts) => {
|
||||
if (text !== '') {
|
||||
res.push({ text })
|
||||
}
|
||||
if (idx !== (parts.length - 1)) {
|
||||
if (this.roll == null) {
|
||||
res.push({ text: '#' })
|
||||
} else {
|
||||
res.push({
|
||||
text: this.roll,
|
||||
placeholder: true
|
||||
})
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return res
|
||||
return res
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user