kashkool ver 1
This commit is contained in:
Vendored
+1
@@ -8,6 +8,7 @@ export {}
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
||||
AForm: typeof import('ant-design-vue/es')['Form']
|
||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||
|
||||
+73
-17
@@ -84,15 +84,24 @@
|
||||
<div class="home_appear_fade_in_up mt-2">نسخه جدید منتشر شد!</div>
|
||||
</div>
|
||||
</van-dialog>
|
||||
<a v-if="config.config?.name === 'garoosi'" href="https://ble.ir/garoosigallery" target="_blank"
|
||||
id="support-button">
|
||||
<div class="bg-green-100 text-green-800 flex gap-2 p-2 rounded-lg mr-2">
|
||||
<div
|
||||
v-if="showSupportButton && !showSplash"
|
||||
id="support-button"
|
||||
class="draggable-support-button"
|
||||
:class="{ 'is-dragging': supportDragging }"
|
||||
:style="supportButtonStyle"
|
||||
@pointerdown="onSupportPointerDown"
|
||||
@pointermove="onSupportPointerMove"
|
||||
@pointerup="handleSupportPointerUp"
|
||||
@pointercancel="onSupportPointerCancel"
|
||||
>
|
||||
<div class="bg-green-100 text-green-800 flex gap-2 p-2 rounded-lg">
|
||||
<span>پشتیبانی</span>
|
||||
<div class="w-5">
|
||||
<img src="/src/assets/img/support.png" alt=""/>
|
||||
<div class="w-5">
|
||||
<img src="/logo-montzar.png" alt="" draggable="false" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="!showSplash"
|
||||
@@ -126,6 +135,12 @@ import {useConfigStore} from "@/store/configStore";
|
||||
import {getProjectFontFamily, getProjectLoginLogo, getProjectSplashBackground, getProjectBrandRed, hasCustomLoginLogoLayout, isBoursecuProject} from "@/utils/config";
|
||||
import {ConfigProvider as AConfigProvider} from 'ant-design-vue'
|
||||
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import {
|
||||
buildSupportMessengerUrl,
|
||||
loadSupportMessengerFromSettings,
|
||||
supportMessengerSettings,
|
||||
} from '@/utils/supportMessenger'
|
||||
import {useDraggableFloatingButton} from '@/utils/useDraggableFloatingButton'
|
||||
|
||||
const {offlineReady, needRefresh, updateServiceWorker} = useRegisterSW()
|
||||
const config = useConfigStore()
|
||||
@@ -139,6 +154,44 @@ const splashIndicator = computed(() => h(LoadingOutlined, {
|
||||
const showSplash = ref(true)
|
||||
const popVisible = ref(false)
|
||||
|
||||
const GAROOSI_SUPPORT_URL = 'https://ble.ir/garoosigallery'
|
||||
|
||||
const supportLink = computed(() => {
|
||||
if (config.config?.name === 'garoosi') {
|
||||
return GAROOSI_SUPPORT_URL
|
||||
}
|
||||
return buildSupportMessengerUrl(
|
||||
supportMessengerSettings.value.messenger,
|
||||
supportMessengerSettings.value.messengerId
|
||||
)
|
||||
})
|
||||
|
||||
const showSupportButton = computed(() => !!supportLink.value)
|
||||
|
||||
const {
|
||||
dragging: supportDragging,
|
||||
fabStyle: supportButtonStyle,
|
||||
handlePointerDown: onSupportPointerDown,
|
||||
handlePointerMove: onSupportPointerMove,
|
||||
handlePointerUp: supportPointerUp,
|
||||
handlePointerCancel: onSupportPointerCancel
|
||||
} = useDraggableFloatingButton('khaneghi_support_button_position', {
|
||||
width: 110,
|
||||
height: 44,
|
||||
defaultBottomOffset: 120
|
||||
})
|
||||
|
||||
function openSupportLink() {
|
||||
if (!supportLink.value) return
|
||||
window.open(supportLink.value, '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
|
||||
function handleSupportPointerUp(event: PointerEvent) {
|
||||
if (supportPointerUp(event)) {
|
||||
openSupportLink()
|
||||
}
|
||||
}
|
||||
|
||||
const antTheme = computed(() => {
|
||||
if (!config.config?.color) return null
|
||||
|
||||
@@ -164,6 +217,7 @@ const antTheme = computed(() => {
|
||||
|
||||
onMounted(async () => {
|
||||
await config.getConfigData()
|
||||
await loadSupportMessengerFromSettings()
|
||||
console.log(config?.config?.color)
|
||||
checkVersion()
|
||||
setTimeout(() => {
|
||||
@@ -235,18 +289,20 @@ function update() {
|
||||
|
||||
#support-button {
|
||||
position: fixed;
|
||||
bottom: calc(80px + var(--app-credit-footer-offset, 28px) + 12px);
|
||||
right: 20px;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
//border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
//box-shadow: 0 4px 10px rgba(0,0,0,0.3);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
z-index: 9999;
|
||||
cursor: grab;
|
||||
user-select: none;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
border-radius: 0.5rem;
|
||||
|
||||
&.is-dragging {
|
||||
cursor: grabbing;
|
||||
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.22);
|
||||
}
|
||||
|
||||
img {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 426px) {
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const DRAG_THRESHOLD = 6
|
||||
|
||||
type FabPosition = { x: number; y: number }
|
||||
|
||||
type DraggableFloatingOptions = {
|
||||
width?: number
|
||||
height?: number
|
||||
defaultBottomOffset?: number
|
||||
defaultRightOffset?: number
|
||||
}
|
||||
|
||||
export function useDraggableFloatingButton(
|
||||
storageKey: string,
|
||||
options: DraggableFloatingOptions = {}
|
||||
) {
|
||||
const width = options.width ?? 96
|
||||
const height = options.height ?? 44
|
||||
const defaultBottomOffset = options.defaultBottomOffset ?? 120
|
||||
const defaultRightOffset = options.defaultRightOffset ?? 20
|
||||
|
||||
const pos = ref<FabPosition>({ x: 0, y: 0 })
|
||||
const dragging = ref(false)
|
||||
|
||||
let pointerId: number | null = null
|
||||
let startX = 0
|
||||
let startY = 0
|
||||
let originX = 0
|
||||
let originY = 0
|
||||
let hasMoved = false
|
||||
|
||||
const fabStyle = computed(() => ({
|
||||
left: `${pos.value.x}px`,
|
||||
top: `${pos.value.y}px`,
|
||||
width: `${width}px`,
|
||||
touchAction: 'none'
|
||||
}))
|
||||
|
||||
function getViewportWidth() {
|
||||
return Math.min(window.innerWidth, 426)
|
||||
}
|
||||
|
||||
function getHorizontalOffset() {
|
||||
const vw = window.innerWidth
|
||||
const contentWidth = getViewportWidth()
|
||||
return Math.max(0, (vw - contentWidth) / 2)
|
||||
}
|
||||
|
||||
function resetToDefault() {
|
||||
const vh = window.innerHeight
|
||||
const offsetX = getHorizontalOffset()
|
||||
const contentWidth = getViewportWidth()
|
||||
|
||||
pos.value = {
|
||||
x: offsetX + contentWidth - width - defaultRightOffset,
|
||||
y: vh - defaultBottomOffset - height
|
||||
}
|
||||
}
|
||||
|
||||
function clampToViewport() {
|
||||
const vw = window.innerWidth
|
||||
const vh = window.innerHeight
|
||||
|
||||
pos.value = {
|
||||
x: Math.max(0, Math.min(vw - width, pos.value.x)),
|
||||
y: Math.max(0, Math.min(vh - height, pos.value.y))
|
||||
}
|
||||
}
|
||||
|
||||
function loadPosition() {
|
||||
try {
|
||||
const raw = localStorage.getItem(storageKey)
|
||||
if (!raw) return false
|
||||
const parsed = JSON.parse(raw) as FabPosition
|
||||
if (typeof parsed?.x === 'number' && typeof parsed?.y === 'number') {
|
||||
pos.value = parsed
|
||||
clampToViewport()
|
||||
return true
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function savePosition() {
|
||||
localStorage.setItem(storageKey, JSON.stringify(pos.value))
|
||||
}
|
||||
|
||||
function handleResize() {
|
||||
clampToViewport()
|
||||
savePosition()
|
||||
}
|
||||
|
||||
function handlePointerDown(event: PointerEvent) {
|
||||
dragging.value = true
|
||||
hasMoved = false
|
||||
pointerId = event.pointerId
|
||||
startX = event.clientX
|
||||
startY = event.clientY
|
||||
originX = pos.value.x
|
||||
originY = pos.value.y
|
||||
;(event.currentTarget as HTMLElement)?.setPointerCapture?.(event.pointerId)
|
||||
}
|
||||
|
||||
function handlePointerMove(event: PointerEvent) {
|
||||
if (!dragging.value || pointerId !== event.pointerId) return
|
||||
|
||||
const dx = event.clientX - startX
|
||||
const dy = event.clientY - startY
|
||||
|
||||
if (Math.abs(dx) > DRAG_THRESHOLD || Math.abs(dy) > DRAG_THRESHOLD) {
|
||||
hasMoved = true
|
||||
}
|
||||
|
||||
pos.value = {
|
||||
x: originX + dx,
|
||||
y: originY + dy
|
||||
}
|
||||
clampToViewport()
|
||||
}
|
||||
|
||||
function finishPointer(event: PointerEvent) {
|
||||
if (!dragging.value || pointerId !== event.pointerId) return false
|
||||
|
||||
dragging.value = false
|
||||
pointerId = null
|
||||
savePosition()
|
||||
|
||||
const clicked = !hasMoved
|
||||
hasMoved = false
|
||||
return clicked
|
||||
}
|
||||
|
||||
function handlePointerUp(event: PointerEvent) {
|
||||
return finishPointer(event)
|
||||
}
|
||||
|
||||
function handlePointerCancel(event: PointerEvent) {
|
||||
finishPointer(event)
|
||||
return false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!loadPosition()) {
|
||||
resetToDefault()
|
||||
}
|
||||
window.addEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
return {
|
||||
dragging,
|
||||
fabStyle,
|
||||
handlePointerDown,
|
||||
handlePointerMove,
|
||||
handlePointerUp,
|
||||
handlePointerCancel,
|
||||
resetToDefault
|
||||
}
|
||||
}
|
||||
@@ -118,8 +118,6 @@
|
||||
:src="getProjectNavLogo(config.config?.avatar)"
|
||||
/>
|
||||
</div>
|
||||
<!-- <div class="flex justify-center">خرید </div>
|
||||
<div class="flex justify-center">محصول </div>-->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div :class="setNavColor('buyProduct')" class="tab" @click="setRoute('buyProduct')">
|
||||
@@ -157,17 +155,6 @@ import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import {useConfigStore} from "@/store/configStore";
|
||||
import {getConfigApp, getProjectNavLogo, isBoursecuProject} from "@/utils/config";
|
||||
|
||||
/*onMounted(async () => {
|
||||
const c = await document.getElementById("canvas1");
|
||||
const ctx = c.getContext("2d");
|
||||
console.log(ctx)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0,20);
|
||||
ctx.lineTo(165,20)
|
||||
ctx.arc(200, 50, 45, 3.9, 5.5, false);
|
||||
ctx.lineTo(400,20)
|
||||
ctx.stroke();
|
||||
})*/
|
||||
const currentRoute = computed(() => router.currentRoute.value.name)
|
||||
const hideMenu = computed(() => !!router.currentRoute.value.meta.hideMenu)
|
||||
const config = useConfigStore()
|
||||
|
||||
Reference in New Issue
Block a user