Fix PWA registration, font loading, and Safari slider interactions.

Configure module service worker registration, remove duplicate SW hook, correct IRANSans Black font path, and improve touch slider handling in trade and wallet forms.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-05 15:56:43 +02:00
co-authored by Cursor
parent 6a0379e226
commit 0bddc5746e
10 changed files with 94 additions and 50 deletions
+4 -1
View File
@@ -8,7 +8,6 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
AButton: typeof import('ant-design-vue/es')['Button'] AButton: typeof import('ant-design-vue/es')['Button']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ADivider: typeof import('ant-design-vue/es')['Divider'] ADivider: typeof import('ant-design-vue/es')['Divider']
AForm: typeof import('ant-design-vue/es')['Form'] AForm: typeof import('ant-design-vue/es')['Form']
AFormItem: typeof import('ant-design-vue/es')['FormItem'] AFormItem: typeof import('ant-design-vue/es')['FormItem']
@@ -16,14 +15,17 @@ declare module 'vue' {
AInputPassword: typeof import('ant-design-vue/es')['InputPassword'] AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
AModal: typeof import('ant-design-vue/es')['Modal'] AModal: typeof import('ant-design-vue/es')['Modal']
AppCreditLink: typeof import('./src/components/AppCreditLink.vue')['default'] AppCreditLink: typeof import('./src/components/AppCreditLink.vue')['default']
ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioButton: typeof import('ant-design-vue/es')['RadioButton'] ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ASelect: typeof import('ant-design-vue/es')['Select'] ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption'] ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASlider: typeof import('ant-design-vue/es')['Slider'] ASlider: typeof import('ant-design-vue/es')['Slider']
ASpin: typeof import('ant-design-vue/es')['Spin'] ASpin: typeof import('ant-design-vue/es')['Spin']
ASwitch: typeof import('ant-design-vue/es')['Switch']
ATag: typeof import('ant-design-vue/es')['Tag'] ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea'] ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
BaseDatePicker: typeof import('./src/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue')['default'] BaseDatePicker: typeof import('./src/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue')['default']
Basic: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/basic.vue')['default'] Basic: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/basic.vue')['default']
BasicActionSheet: typeof import('./src/components/BasicPacks/BasicActionSheet.vue')['default'] BasicActionSheet: typeof import('./src/components/BasicPacks/BasicActionSheet.vue')['default']
@@ -68,5 +70,6 @@ declare module 'vue' {
TransactionSkeleton: typeof import('./src/components/TransactionSkeleton.vue')['default'] TransactionSkeleton: typeof import('./src/components/TransactionSkeleton.vue')['default']
VanActionSheet: typeof import('vant/es')['ActionSheet'] VanActionSheet: typeof import('vant/es')['ActionSheet']
VanDialog: typeof import('vant/es')['Dialog'] VanDialog: typeof import('vant/es')['Dialog']
VanField: typeof import('vant/es')['Field']
} }
} }
-2
View File
@@ -92,7 +92,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import pkg from '../package.json' import pkg from '../package.json'
import { getDisplayAppVersion } from '@/config/config-cache' import { getDisplayAppVersion } from '@/config/config-cache'
import {useRegisterSW} from 'virtual:pwa-register/vue'
import {computed, defineAsyncComponent, h, onMounted, ref, watch} from 'vue' import {computed, defineAsyncComponent, h, onMounted, ref, watch} from 'vue'
import img_topGradiant from '@/views/login/assets/img/gr_top_white.svg' import img_topGradiant from '@/views/login/assets/img/gr_top_white.svg'
import img_pattern from '@/views/login/assets/img/pattern.svg' import img_pattern from '@/views/login/assets/img/pattern.svg'
@@ -127,7 +126,6 @@ const showDesktopFloatingCredit = computed(() => {
return route.name === 'login' || !!route.meta.hideMenu return route.name === 'login' || !!route.meta.hideMenu
}) })
useRegisterSW()
const displayVersion = getDisplayAppVersion(pkg.version) const displayVersion = getDisplayAppVersion(pkg.version)
const config = useConfigStore() const config = useConfigStore()
const splashIndicator = computed(() => h(LoadingOutlined, { const splashIndicator = computed(() => h(LoadingOutlined, {
+15
View File
@@ -156,11 +156,26 @@
//} //}
/* =================== Slider =================== */ /* =================== Slider =================== */
.app-touch-slider {
position: relative;
z-index: 1;
touch-action: none;
-webkit-user-select: none;
user-select: none;
padding-block: 0.375rem;
}
.ant-slider {
touch-action: none;
}
.ant-slider-track { .ant-slider-track {
background-color: @App-primary-color !important; background-color: @App-primary-color !important;
} }
.ant-slider-handle { .ant-slider-handle {
border-color: @App-primary-color !important; border-color: @App-primary-color !important;
touch-action: none;
-webkit-tap-highlight-color: transparent;
} }
/* =================== Menu =================== */ /* =================== Menu =================== */
+2 -2
View File
@@ -30,14 +30,14 @@
@font-face { @font-face {
font-family: @prefixCls-font-family; font-family: @prefixCls-font-family;
src: url("../fonts/iranSans/woff2/IRANSansWeb(FaNum)_Bold.woff2") format("woff"); src: url("../fonts/iranSans/woff2/IRANSansWeb(FaNum)_Bold.woff2") format("woff2");
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: @prefixCls-font-family; font-family: @prefixCls-font-family;
src: url("../fonts/iranSans/woff2/IRANSansWeb(FaNum)_primary.woff2") format("woff"); src: url("../fonts/iranSans/woff2/IRANSansWeb(FaNum)_Black.woff2") format("woff2");
font-weight: 900; font-weight: 900;
font-style: normal; font-style: normal;
} }
+3 -3
View File
@@ -4,9 +4,9 @@ import img_pattern from "@/assets/img/dollar_pattern.svg";
</script> </script>
<template> <template>
<div class="flex absolute w-full top-0 right-0 left-0 bottom-0"> <div class="bg-main-decor flex absolute w-full top-0 right-0 left-0 bottom-0 pointer-events-none">
<img :src="img_right" alt="" class=" absolute z-5 w-screen h-full object-cover"> <img :src="img_right" alt="" class="absolute z-5 w-screen h-full object-cover">
<img :src="img_pattern" alt="" class=" w-full object-cover"> <img :src="img_pattern" alt="" class="w-full object-cover">
</div> </div>
</template> </template>
+9 -2
View File
@@ -69,6 +69,12 @@
<Transition mode="out-in" name="fade"> <Transition mode="out-in" name="fade">
<a-form-item v-if="walletStore?.walletInfo" class="!mt-3 "> <a-form-item v-if="walletStore?.walletInfo" class="!mt-3 ">
<!-- {{ isBuy }}--> <!-- {{ isBuy }}-->
<div
class="app-touch-slider"
@touchstart.stop
@touchmove.stop
@pointerdown.stop
>
<a-slider v-model:value="form.percentWallet" <a-slider v-model:value="form.percentWallet"
:disabled="isBuy? cashWalletBalance <= 0: false" :disabled="isBuy? cashWalletBalance <= 0: false"
:max="100" :max="100"
@@ -77,6 +83,7 @@
:tip-formatter="null" :tip-formatter="null"
class="!my-1" class="!my-1"
@change="percentChange" /> @change="percentChange" />
</div>
</a-form-item> </a-form-item>
</Transition> </Transition>
<!-- <Transition mode="out-in" name="fade"> <!-- <Transition mode="out-in" name="fade">
@@ -444,7 +451,7 @@ onMounted(async () => {
const form = ref<Gold>({ const form = ref<Gold>({
goldCash: undefined, goldCash: undefined,
goldValue: undefined, goldValue: undefined,
percentWallet: undefined percentWallet: 0,
}) })
const allowedAsciiCodeFloat = [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57] const allowedAsciiCodeFloat = [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
const allowedAsciiCodeInt = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57] const allowedAsciiCodeInt = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
@@ -683,7 +690,7 @@ async function ok() {
form.value = { form.value = {
goldValue: undefined, goldValue: undefined,
goldCash: undefined, goldCash: undefined,
percentWallet: undefined, percentWallet: 0,
method: 'cash' method: 'cash'
} }
await fundStore.getMyFund() await fundStore.getMyFund()
+9 -2
View File
@@ -92,6 +92,12 @@
<Transition mode="out-in" name="fade"> <Transition mode="out-in" name="fade">
<a-form-item v-if="walletStore?.walletInfo" class="!mt-3 "> <a-form-item v-if="walletStore?.walletInfo" class="!mt-3 ">
<!-- {{ isBuy }}--> <!-- {{ isBuy }}-->
<div
class="app-touch-slider"
@touchstart.stop
@touchmove.stop
@pointerdown.stop
>
<a-slider v-model:value="form.percentWallet" <a-slider v-model:value="form.percentWallet"
:disabled="isBuy? cashWalletBalance <= 0: false" :disabled="isBuy? cashWalletBalance <= 0: false"
:max="100" :max="100"
@@ -100,6 +106,7 @@
:tip-formatter="null" :tip-formatter="null"
class="!my-1" class="!my-1"
@change="percentChange" /> @change="percentChange" />
</div>
</a-form-item> </a-form-item>
</Transition> </Transition>
</div> </div>
@@ -608,7 +615,7 @@ onMounted(async () => {
const form = ref<Gold>({ const form = ref<Gold>({
goldCash: undefined, goldCash: undefined,
goldValue: undefined, goldValue: undefined,
percentWallet: undefined percentWallet: 0,
}) })
const allowedAsciiCodeFloat = [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57] const allowedAsciiCodeFloat = [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
const allowedAsciiCodeInt = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57] const allowedAsciiCodeInt = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
@@ -811,7 +818,7 @@ async function ok() {
form.value = { form.value = {
goldValue: undefined, goldValue: undefined,
goldCash: undefined, goldCash: undefined,
percentWallet: undefined percentWallet: 0,
} }
inputLock.value = null inputLock.value = null
message.success('سفارش شما با موفقیت انجام شد') message.success('سفارش شما با موفقیت انجام شد')
@@ -62,6 +62,12 @@
{{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }} {{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }}
</p> </p>
<a-form-item v-if="walletStore?.walletInfo" class="!mt-3"> <a-form-item v-if="walletStore?.walletInfo" class="!mt-3">
<div
class="app-touch-slider"
@touchstart.stop
@touchmove.stop
@pointerdown.stop
>
<a-slider <a-slider
v-model:value="form.percentWallet" v-model:value="form.percentWallet"
:disabled="walletStore?.walletInfo?.cash <= 0" :disabled="walletStore?.walletInfo?.cash <= 0"
@@ -71,6 +77,7 @@
:tip-formatter="formatter" :tip-formatter="formatter"
@change="percentChange" @change="percentChange"
/> />
</div>
</a-form-item> </a-form-item>
</div> </div>
<div v-else key="deposit" class="dwallet-form__extras"> <div v-else key="deposit" class="dwallet-form__extras">
@@ -66,6 +66,12 @@
{{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }} {{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }}
</div> </div>
<a-form-item v-if="walletStore?.walletInfo" class="!mt-3"> <a-form-item v-if="walletStore?.walletInfo" class="!mt-3">
<div
class="app-touch-slider"
@touchstart.stop
@touchmove.stop
@pointerdown.stop
>
<a-slider <a-slider
v-model:value="form.percentWallet" v-model:value="form.percentWallet"
:disabled="walletStore?.walletInfo?.cash <= 0" :disabled="walletStore?.walletInfo?.cash <= 0"
@@ -75,6 +81,7 @@
:tip-formatter="formatter" :tip-formatter="formatter"
@change="percentChange" @change="percentChange"
/> />
</div>
</a-form-item> </a-form-item>
</div> </div>
<div v-else class="mt-3"> <div v-else class="mt-3">
+4 -4
View File
@@ -18,21 +18,21 @@ export default defineConfig({
vue(), vue(),
vueJsx(), vueJsx(),
VitePWA({ VitePWA({
//registerType: 'autoUpdate', registerType: 'autoUpdate',
devOptions: { devOptions: {
enabled: true enabled: true,
type: 'module',
}, },
workbox: { workbox: {
cleanupOutdatedCaches: true, cleanupOutdatedCaches: true,
clientsClaim: true, clientsClaim: true,
skipWaiting: true skipWaiting: true
}, },
mode: 'development', strategies: 'injectManifest',
base: '/', base: '/',
srcDir: 'src', srcDir: 'src',
filename: 'sw.ts', filename: 'sw.ts',
includeAssets: ['/favicon.png'], includeAssets: ['/favicon.png'],
strategies: 'injectManifest',
manifest: { manifest: {
name: ``, name: ``,
short_name: ``, short_name: ``,