mirror of
https://github.com/sabjorn7/meetguru.git
synced 2025-12-17 19:07:33 +03:00
v189 - lessons
This commit is contained in:
parent
2de028e570
commit
8c20931f59
@ -1 +1 @@
|
|||||||
{"name":"weweb-front","version":"4.0.0","private":true,"type":"module","scripts":{"serve":"vite","build":"vite build","postbuild":"node ./postbuild.js"},"dependencies":{"@vueuse/head":"2.0.0","axios":"1.9.0","html-escaper":"3.0.3","lodash":"4.17.21","pinia":"3.0.2","short-unique-id":"5.3.2","tiny-emitter":"2.1.0","uuid":"11.1.0","vue":"3.5.13","vue-cookie-next":"1.3.0","vue-meta":"2.4.0","vue-router":"4.5.1","vuex":"4.1.0","dayjs":"1.11.0","@supabase/supabase-js":"2.50.3","qs":"^6.14.0","@vueform/multiselect":"2.6.2","vue-ellipse-progress":"^2.1.1","@vueuse/core":"^13.0.0","diff":"^5.1.0","animejs":"^3.2.2","marked":"^14.1.2","medium-zoom":"^1.0.6","prismjs":"^1.23.0","lodash-es":"^4.17.21","@vuepic/vue-datepicker":"3.6.8","date-fns":"4.1.0","@tiptap/extension-color":"2.8.0","@tiptap/extension-image":"2.8.0","@tiptap/extension-link":"2.8.0","@tiptap/extension-mathematics":"2.26.1","@tiptap/extension-mention":"2.8.0","@tiptap/extension-placeholder":"2.8.0","@tiptap/extension-table":"2.8.0","@tiptap/extension-table-cell":"2.8.0","@tiptap/extension-table-header":"2.8.0","@tiptap/extension-table-row":"2.8.0","@tiptap/extension-task-item":"2.8.0","@tiptap/extension-task-list":"2.8.0","@tiptap/extension-text-align":"2.8.0","@tiptap/extension-text-style":"2.8.0","@tiptap/extension-underline":"2.8.0","@tiptap/pm":"2.8.0","@tiptap/starter-kit":"2.8.0","@tiptap/suggestion":"2.8.0","@tiptap/vue-3":"2.8.0","katex":"^0.16.22","prosemirror-commands":"1.5.0","prosemirror-dropcursor":"1.5.0","prosemirror-gapcursor":"1.3.1","prosemirror-history":"1.3.0","prosemirror-keymap":"1.2.0","prosemirror-schema-list":"1.2.2","tiptap-markdown":"^0.8.10"},"devDependencies":{"@vitejs/plugin-vue":"5.2.4","autoprefixer":"10.4.21","handlebars":"4.7.8","sass-embedded":"1.89.0","vite":"6.3.5","vite-plugin-node-polyfills":"0.23.0"},"browserslist":["last 3 years"]}
|
{"name":"weweb-front","version":"4.0.0","private":true,"type":"module","scripts":{"serve":"vite","build":"vite build","postbuild":"node ./postbuild.js"},"dependencies":{"@vueuse/head":"2.0.0","axios":"1.9.0","html-escaper":"3.0.3","lodash":"4.17.21","pinia":"3.0.2","short-unique-id":"5.3.2","tiny-emitter":"2.1.0","uuid":"11.1.0","vue":"3.5.13","vue-cookie-next":"1.3.0","vue-meta":"2.4.0","vue-router":"4.5.1","vuex":"4.1.0","dayjs":"1.11.0","@supabase/supabase-js":"2.50.3","qs":"^6.14.0","@vueform/multiselect":"2.6.2","vue-ellipse-progress":"^2.1.1","@vueuse/core":"^13.0.0","diff":"^5.1.0","animejs":"^3.2.2","marked":"^14.1.2","medium-zoom":"^1.0.6","prismjs":"^1.23.0","@vuepic/vue-datepicker":"3.6.8","date-fns":"4.1.0","@tiptap/extension-color":"2.8.0","@tiptap/extension-image":"2.8.0","@tiptap/extension-link":"2.8.0","@tiptap/extension-mathematics":"2.26.1","@tiptap/extension-mention":"2.8.0","@tiptap/extension-placeholder":"2.8.0","@tiptap/extension-table":"2.8.0","@tiptap/extension-table-cell":"2.8.0","@tiptap/extension-table-header":"2.8.0","@tiptap/extension-table-row":"2.8.0","@tiptap/extension-task-item":"2.8.0","@tiptap/extension-task-list":"2.8.0","@tiptap/extension-text-align":"2.8.0","@tiptap/extension-text-style":"2.8.0","@tiptap/extension-underline":"2.8.0","@tiptap/pm":"2.8.0","@tiptap/starter-kit":"2.8.0","@tiptap/suggestion":"2.8.0","@tiptap/vue-3":"2.8.0","katex":"^0.16.22","prosemirror-commands":"1.5.0","prosemirror-dropcursor":"1.5.0","prosemirror-gapcursor":"1.3.1","prosemirror-history":"1.3.0","prosemirror-keymap":"1.2.0","prosemirror-schema-list":"1.2.2","tiptap-markdown":"^0.8.10","lodash-es":"^4.17.21"},"devDependencies":{"@vitejs/plugin-vue":"5.2.4","autoprefixer":"10.4.21","handlebars":"4.7.8","sass-embedded":"1.89.0","vite":"6.3.5","vite-plugin-node-polyfills":"0.23.0"},"browserslist":["last 3 years"]}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
{"cacheVersion":183,"page":{"id":"cf9f551f-e733-4934-a682-535575cb7c70","paths":{"en":"promo","default":"promo"},"cmsDataSetPath":null,"workflows":[]},"sections":{"4a2188f6-d98c-4150-9ba7-5918c72f3421":{"uid":"4a2188f6-d98c-4150-9ba7-5918c72f3421","linkId":"416695e7-e54e-4897-9f9a-befeb223f1b0","_state":{"style":{"default":{}}},"content":{"default":{"wwObjects":[],"_ww-layout_alignItems":"flex-start","_ww-layout_flexDirection":"column"}},"sectionBaseId":"99586bd3-2b15-4d6b-a025-6a50d07ca845","sectionTitle":"Section"}},"wwObjects":{},"collections":[],"variables":[],"workflows":[],"formulas":[],"libraryComponents":[]}
|
{"cacheVersion":189,"page":{"id":"cf9f551f-e733-4934-a682-535575cb7c70","paths":{"en":"promo","default":"promo"},"cmsDataSetPath":null,"workflows":[]},"sections":{"4a2188f6-d98c-4150-9ba7-5918c72f3421":{"uid":"4a2188f6-d98c-4150-9ba7-5918c72f3421","linkId":"416695e7-e54e-4897-9f9a-befeb223f1b0","_state":{"style":{"default":{}}},"content":{"default":{"wwObjects":[],"_ww-layout_alignItems":"flex-start","_ww-layout_flexDirection":"column"}},"sectionBaseId":"99586bd3-2b15-4d6b-a025-6a50d07ca845","sectionTitle":"Section"}},"wwObjects":{},"collections":[],"variables":[],"workflows":[],"formulas":[],"libraryComponents":[]}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
{"name":"Образовательная платформа Meetguru","short_name":"Образовательная платформа Meetguru","icons":[{"src":"images/48-favicon.png?_wwcv=183","type":"image/png","sizes":"48x48"},{"src":"images/72-favicon.png?_wwcv=183","type":"image/png","sizes":"72x72"},{"src":"images/96-favicon.png?_wwcv=183","type":"image/png","sizes":"96x96"},{"src":"images/128-favicon.png?_wwcv=183","type":"image/png","sizes":"128x128"},{"src":"images/144-favicon.png?_wwcv=183","type":"image/png","sizes":"144x144"},{"src":"images/152-favicon.png?_wwcv=183","type":"image/png","sizes":"152x152"},{"src":"images/192-favicon.png?_wwcv=183","type":"image/png","sizes":"192x192"},{"src":"images/256-favicon.png?_wwcv=183","type":"image/png","sizes":"256x256"},{"src":"images/384-favicon.png?_wwcv=183","type":"image/png","sizes":"384x384"},{"src":"images/512-favicon.png?_wwcv=183","type":"image/png","sizes":"512x512"}],"start_url":"/","display":"fullscreen","scope":"/","background_color":"#FFFFFF","theme_color":"#FFFFFF"}
|
{"name":"Образовательная платформа Meetguru","short_name":"Образовательная платформа Meetguru","icons":[{"src":"images/48-favicon.png?_wwcv=189","type":"image/png","sizes":"48x48"},{"src":"images/72-favicon.png?_wwcv=189","type":"image/png","sizes":"72x72"},{"src":"images/96-favicon.png?_wwcv=189","type":"image/png","sizes":"96x96"},{"src":"images/128-favicon.png?_wwcv=189","type":"image/png","sizes":"128x128"},{"src":"images/144-favicon.png?_wwcv=189","type":"image/png","sizes":"144x144"},{"src":"images/152-favicon.png?_wwcv=189","type":"image/png","sizes":"152x152"},{"src":"images/192-favicon.png?_wwcv=189","type":"image/png","sizes":"192x192"},{"src":"images/256-favicon.png?_wwcv=189","type":"image/png","sizes":"256x256"},{"src":"images/384-favicon.png?_wwcv=189","type":"image/png","sizes":"384x384"},{"src":"images/512-favicon.png?_wwcv=189","type":"image/png","sizes":"512x512"}],"start_url":"/","display":"fullscreen","scope":"/","background_color":"#FFFFFF","theme_color":"#FFFFFF"}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
const version = 183;
|
const version = 189;
|
||||||
self.addEventListener('install', event => {
|
self.addEventListener('install', event => {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Service worker v${version} installed`);
|
console.log(`Service worker v${version} installed`);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -200,15 +200,15 @@ function mapFilterSortData(rawValue, filter, sort, __wwmap, context, event, args
|
|||||||
let value = rawValue;
|
let value = rawValue;
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
let data = value; // TODO: remove this when no side effects are expected
|
let data = value; // TODO: remove this when no side effects are expected
|
||||||
if (__wwmap) data = mapData(value, __wwmap, context, event, args);
|
|
||||||
if (filter) data = filterData(data, filter, context, event, args);
|
if (filter) data = filterData(data, filter, context, event, args);
|
||||||
if (sort) data = sortData([...data], sort, context, event, args);
|
if (sort) data = sortData([...data], sort, context, event, args);
|
||||||
|
if (__wwmap) data = mapData(data, __wwmap, context, event, args);
|
||||||
return { value: data, rawValue };
|
return { value: data, rawValue };
|
||||||
} else if (isObject(value) && Array.isArray(value.data) && value.type === 'collection') {
|
} else if (isObject(value) && Array.isArray(value.data) && value.type === 'collection') {
|
||||||
let data = value.data; // TODO: remove this when no side effects are expected
|
let data = value.data; // TODO: remove this when no side effects are expected
|
||||||
if (__wwmap) data = mapData(value.data, __wwmap, context, event, args);
|
|
||||||
if (filter) data = filterData(data, filter, context, event, args);
|
if (filter) data = filterData(data, filter, context, event, args);
|
||||||
if (sort) data = sortData([...data], sort, context, event, args);
|
if (sort) data = sortData([...data], sort, context, event, args);
|
||||||
|
if (__wwmap) data = mapData(data, __wwmap, context, event, args);
|
||||||
return { value: { ...value, data, total: data.length }, rawValue };
|
return { value: { ...value, data, total: data.length }, rawValue };
|
||||||
}
|
}
|
||||||
return { value, rawValue };
|
return { value, rawValue };
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -52,6 +52,7 @@ export function useForm(
|
|||||||
validation,
|
validation,
|
||||||
customValidation = shallowRef(false),
|
customValidation = shallowRef(false),
|
||||||
required = shallowRef(false),
|
required = shallowRef(false),
|
||||||
|
requiredValidation = null,
|
||||||
initialValue = undefined,
|
initialValue = undefined,
|
||||||
},
|
},
|
||||||
{ elementState, emit, sidepanelFormPath = 'form', setValue = null }
|
{ elementState, emit, sidepanelFormPath = 'form', setValue = null }
|
||||||
@ -60,6 +61,7 @@ export function useForm(
|
|||||||
const registerFormInput = inject('_wwForm:registerInput', () => {});
|
const registerFormInput = inject('_wwForm:registerInput', () => {});
|
||||||
const unregisterFormInput = inject('_wwForm:unregisterInput', () => {});
|
const unregisterFormInput = inject('_wwForm:unregisterInput', () => {});
|
||||||
const updateFormInput = inject('_wwForm:updateInput', () => {});
|
const updateFormInput = inject('_wwForm:updateInput', () => {});
|
||||||
|
const submitForm = inject('_wwForm:submit', () => {});
|
||||||
|
|
||||||
const id = wwLib.wwUtils.getUid();
|
const id = wwLib.wwUtils.getUid();
|
||||||
const _fieldName = computed(() => fieldName?.value || elementState.name);
|
const _fieldName = computed(() => fieldName?.value || elementState.name);
|
||||||
@ -95,9 +97,11 @@ export function useForm(
|
|||||||
}
|
}
|
||||||
const { resolveFormula } = wwLib.wwFormula.useFormula();
|
const { resolveFormula } = wwLib.wwFormula.useFormula();
|
||||||
|
|
||||||
const computeValidation = (value, required, customValidation, validation) => {
|
const computeValidation = (value, required, customValidation, validation, requiredValidation) => {
|
||||||
const validationResult = customValidation && validation ? resolveFormula(validation)?.value : true;
|
const validationResult = customValidation && validation ? resolveFormula(validation)?.value : true;
|
||||||
const hasValue = !isValueEmpty(value);
|
|
||||||
|
// Use custom required validation if provided, otherwise use default isEmpty check
|
||||||
|
const hasValue = requiredValidation ? requiredValidation(value) : !isValueEmpty(value);
|
||||||
|
|
||||||
// If not required, field is valid unless there's custom validation
|
// If not required, field is valid unless there's custom validation
|
||||||
if (!required) {
|
if (!required) {
|
||||||
@ -109,7 +113,7 @@ export function useForm(
|
|||||||
return hasValue && validationResult;
|
return hasValue && validationResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If just required, check for value
|
// If just required, check for value using custom or default validation
|
||||||
return hasValue;
|
return hasValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,7 +139,7 @@ export function useForm(
|
|||||||
let isFirst = true;
|
let isFirst = true;
|
||||||
const computedValidation = computed(() => {
|
const computedValidation = computed(() => {
|
||||||
// We have to compute the validation here, otherwise the reactivity will not work
|
// We have to compute the validation here, otherwise the reactivity will not work
|
||||||
const isValid = computeValidation(value.value, required.value, customValidation.value, validation.value);
|
const isValid = computeValidation(value.value, required.value, customValidation.value, validation.value, requiredValidation);
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
return null;
|
return null;
|
||||||
@ -159,7 +163,7 @@ export function useForm(
|
|||||||
validationType => {
|
validationType => {
|
||||||
if (validationType === 'change') {
|
if (validationType === 'change') {
|
||||||
updateInputValidity(
|
updateInputValidity(
|
||||||
computeValidation(value.value, required?.value, customValidation?.value, validation?.value)
|
computeValidation(value.value, required?.value, customValidation?.value, validation?.value, requiredValidation)
|
||||||
);
|
);
|
||||||
} else if (validationType === 'submit') {
|
} else if (validationType === 'submit') {
|
||||||
updateInputValidity(true);
|
updateInputValidity(true);
|
||||||
@ -171,7 +175,7 @@ export function useForm(
|
|||||||
});
|
});
|
||||||
function forceValidateField() {
|
function forceValidateField() {
|
||||||
debouncedUpdateInputValidity.cancel();
|
debouncedUpdateInputValidity.cancel();
|
||||||
const isValid = computeValidation(value.value, required?.value, customValidation?.value, validation?.value);
|
const isValid = computeValidation(value.value, required?.value, customValidation?.value, validation?.value, requiredValidation);
|
||||||
updateInputValidity(isValid);
|
updateInputValidity(isValid);
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
@ -204,6 +208,7 @@ export function useForm(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
selectForm,
|
selectForm,
|
||||||
|
submitForm,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -177,6 +177,7 @@ export default {
|
|||||||
validationType,
|
validationType,
|
||||||
debounceDelay,
|
debounceDelay,
|
||||||
});
|
});
|
||||||
|
provide('_wwForm:submit', handleSubmit);
|
||||||
provide('_wwForm:useForm', useForm);
|
provide('_wwForm:useForm', useForm);
|
||||||
|
|
||||||
const markdown = `### Form local informations
|
const markdown = `### Form local informations
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
name: cookie-reader
|
||||||
|
description: A component that reads and displays cookie values, including the vkid_sdk:codeVerifier cookie.
|
||||||
|
keywords: cookies, vkid, code verifier, authentication
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Cookie Reader Component
|
||||||
|
|
||||||
|
***Purpose:***
|
||||||
|
This component reads and displays cookie values from the browser, with special focus on the vkid_sdk:codeVerifier cookie which is often used in authentication flows.
|
||||||
|
|
||||||
|
***Features:***
|
||||||
|
- Reads all cookies from the browser
|
||||||
|
- Specifically extracts and displays the vkid_sdk:codeVerifier cookie value
|
||||||
|
- Updates automatically when cookies change
|
||||||
|
|
||||||
|
***Properties:***
|
||||||
|
- No configurable properties are required as the component directly reads from browser cookies
|
||||||
|
|
||||||
|
***Exposed Variables:***
|
||||||
|
- codeVerifier: The current value of the vkid_sdk:codeVerifier cookie (path: variables['current_element_uid-codeVerifier'])
|
||||||
|
|
||||||
|
***Notes:***
|
||||||
|
- This component is useful for debugging authentication flows that use the PKCE (Proof Key for Code Exchange) method
|
||||||
|
- The codeVerifier is typically used in OAuth 2.0 authorization code flow with PKCE
|
||||||
|
- The component will show nothing if the vkid_sdk:codeVerifier cookie is not present
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{"name":"cookie-reader","version":"1.0.1","scripts":{"build":"weweb build","serve":"weweb serve"},"devDependencies":{}}
|
||||||
@ -0,0 +1,883 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vk-auth-component" :class="{ 'is-loading': isLoading }">
|
||||||
|
<!-- OAuth 2.0 Redirect Button -->
|
||||||
|
<button
|
||||||
|
v-if="content.authMethod === 'oauth'"
|
||||||
|
class="vk-auth-button"
|
||||||
|
:style="buttonStyle"
|
||||||
|
@click="initiateOAuthLogin"
|
||||||
|
:disabled="isLoading"
|
||||||
|
>
|
||||||
|
<div class="vk-auth-button__content">
|
||||||
|
<div class="vk-auth-button__icon" v-if="!content.hideIcon">
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M15.684 0H8.316C1.592 0 0 1.592 0 8.316v7.368C0 22.408 1.592 24 8.316 24h7.368C22.408 24 24 22.408 24 15.684V8.316C24 1.592 22.408 0 15.684 0zm3.692 17.123h-1.744c-.66 0-.862-.523-2.049-1.72-1.033-1.01-1.49-1.135-1.744-1.135-.356 0-.458.102-.458.593v1.573c0 .424-.136.593-1.252.593-1.844 0-3.896-1.122-5.342-3.208-2.17-3.05-2.778-5.342-2.778-5.817 0-.254.102-.491.593-.491h1.744c.44 0 .61.203.78.678.864 2.468 2.303 4.63 2.896 4.63.22 0 .322-.102.322-.66V9.473c-.068-1.186-.695-1.287-.695-1.71 0-.203.17-.407.44-.407h2.743c.373 0 .508.203.508.643v3.463c0 .373.17.508.271.508.22 0 .407-.135.813-.542 1.27-1.422 2.183-3.615 2.183-3.615.119-.254.305-.491.729-.491h1.744c.525 0 .644.271.525.643-.22 1.032-2.387 4.07-2.387 4.07-.186.305-.254.44 0 .78.186.254.796.779 1.2 1.252.745.864 1.32 1.592 1.473 2.1.17.508-.085.762-.576.762z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<span class="vk-auth-button__text">{{ content.buttonText }}</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- VK ID One Tap Container -->
|
||||||
|
<div v-else-if="content.authMethod === 'onetap'" ref="vkIdContainer" class="vk-id-container"></div>
|
||||||
|
|
||||||
|
<!-- Loading Indicator -->
|
||||||
|
<div v-if="isLoading" class="vk-auth-loading">
|
||||||
|
<div class="vk-auth-loading__spinner"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Telegram WebApp Info (hidden) -->
|
||||||
|
<div v-if="content.showTelegramInfo" class="telegram-info">
|
||||||
|
<div class="telegram-info__item">
|
||||||
|
<span class="telegram-info__label">Viewport Height:</span>
|
||||||
|
<span class="telegram-info__value">{{ telegramViewportHeight }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="telegram-info__item">
|
||||||
|
<span class="telegram-info__label">Safe Area Inset:</span>
|
||||||
|
<span class="telegram-info__value">{{ telegramSafeAreaInset }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="telegram-info__item">
|
||||||
|
<span class="telegram-info__label">Platform:</span>
|
||||||
|
<span class="telegram-info__value">{{ telegramPlatform }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="telegram-info__item">
|
||||||
|
<span class="telegram-info__label">Color Scheme:</span>
|
||||||
|
<span class="telegram-info__value">{{ telegramColorScheme }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
content: { type: Object, required: true },
|
||||||
|
uid: { type: String, required: true },
|
||||||
|
},
|
||||||
|
emits: ['trigger-event'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
// Editor state
|
||||||
|
const isEditing = computed(() => {
|
||||||
|
// eslint-disable-next-line no-unreachable
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Component state
|
||||||
|
const isLoading = ref(false);
|
||||||
|
const vkIdContainer = ref(null);
|
||||||
|
const vkSdkLoaded = ref(false);
|
||||||
|
const oneTapInstance = ref(null);
|
||||||
|
|
||||||
|
// Internal variables to expose to WeWeb
|
||||||
|
const { value: authCode, setValue: setAuthCode } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'authCode',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: deviceId, setValue: setDeviceId } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'deviceId',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: authError, setValue: setAuthError } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'authError',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Telegram WebApp internal variables
|
||||||
|
const { value: telegramViewportHeight, setValue: setTelegramViewportHeight } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramViewportHeight',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramSafeAreaInset, setValue: setTelegramSafeAreaInset } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramSafeAreaInset',
|
||||||
|
type: 'object',
|
||||||
|
defaultValue: { top: 0, right: 0, bottom: 0, left: 0 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramPlatform, setValue: setTelegramPlatform } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramPlatform',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramColorScheme, setValue: setTelegramColorScheme } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramColorScheme',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramThemeParams, setValue: setTelegramThemeParams } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramThemeParams',
|
||||||
|
type: 'object',
|
||||||
|
defaultValue: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramInitData, setValue: setTelegramInitData } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramInitData',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramInitDataUnsafe, setValue: setTelegramInitDataUnsafe } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramInitDataUnsafe',
|
||||||
|
type: 'object',
|
||||||
|
defaultValue: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramHeaderColor, setValue: setTelegramHeaderColor } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramHeaderColor',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramBackgroundColor, setValue: setTelegramBackgroundColor } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramBackgroundColor',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramIsExpanded, setValue: setTelegramIsExpanded } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramIsExpanded',
|
||||||
|
type: 'boolean',
|
||||||
|
defaultValue: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { value: telegramVersion, setValue: setTelegramVersion } = wwLib.wwVariable.useComponentVariable({
|
||||||
|
uid: props.uid,
|
||||||
|
name: 'telegramVersion',
|
||||||
|
type: 'string',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Computed properties
|
||||||
|
const buttonStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
backgroundColor: props.content?.buttonColor || '#0077FF',
|
||||||
|
color: props.content?.buttonTextColor || '#FFFFFF',
|
||||||
|
borderRadius: props.content?.buttonBorderRadius || '4px',
|
||||||
|
padding: props.content?.buttonPadding || '10px 16px',
|
||||||
|
fontSize: props.content?.buttonFontSize || '14px',
|
||||||
|
fontWeight: props.content?.buttonFontWeight || '500',
|
||||||
|
border: props.content?.buttonBorder || 'none',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
const validateAppConfig = () => {
|
||||||
|
if (!props.content?.appId) {
|
||||||
|
setAuthError('VK App ID is required');
|
||||||
|
emitError('VK App ID is required');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.content?.redirectUri) {
|
||||||
|
setAuthError('Redirect URI is required');
|
||||||
|
emitError('Redirect URI is required');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadVkSdk = () => {
|
||||||
|
if (isEditing.value || vkSdkLoaded.value) return;
|
||||||
|
|
||||||
|
const document = wwLib.getFrontDocument();
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = 'https://unpkg.com/@vkid/sdk@2.6.0/dist-sdk/umd/index.js';
|
||||||
|
script.async = true;
|
||||||
|
script.onload = () => {
|
||||||
|
vkSdkLoaded.value = true;
|
||||||
|
if (props.content?.authMethod === 'onetap') {
|
||||||
|
initVkIdOneTap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
script.onerror = () => {
|
||||||
|
setAuthError('Failed to load VK SDK');
|
||||||
|
emitError('Failed to load VK SDK');
|
||||||
|
};
|
||||||
|
document.head.appendChild(script);
|
||||||
|
};
|
||||||
|
|
||||||
|
const initVkIdOneTap = () => {
|
||||||
|
if (isEditing.value || !vkSdkLoaded.value || !vkIdContainer.value) return;
|
||||||
|
|
||||||
|
if (!validateAppConfig()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.VKIDSDK) {
|
||||||
|
setAuthError('VK SDK not loaded properly');
|
||||||
|
emitError('VK SDK not loaded properly');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const VKID = window.VKIDSDK;
|
||||||
|
|
||||||
|
// Initialize VKID config
|
||||||
|
VKID.Config.init({
|
||||||
|
app: parseInt(props.content?.appId, 10),
|
||||||
|
redirectUrl: props.content?.redirectUri,
|
||||||
|
responseMode: props.content?.backendTokenExchange === true
|
||||||
|
? VKID.ConfigResponseMode.Code
|
||||||
|
: VKID.ConfigResponseMode.Callback,
|
||||||
|
source: VKID.ConfigSource.LOWCODE,
|
||||||
|
scope: props.content?.scopes || '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create and render OneTap
|
||||||
|
oneTapInstance.value = new VKID.OneTap({
|
||||||
|
showAgreements: props.content?.showAgreements !== false,
|
||||||
|
skin: props.content?.oneTapButtonSkin || 'primary',
|
||||||
|
buttonSkin: props.content?.oneTapButtonSkin || 'primary',
|
||||||
|
buttonSize: props.content?.oneTapButtonSize || 'large',
|
||||||
|
});
|
||||||
|
|
||||||
|
oneTapInstance.value.render({
|
||||||
|
container: vkIdContainer.value,
|
||||||
|
showAlternativeLogin: props.content?.showAlternativeLogin !== false
|
||||||
|
})
|
||||||
|
.on(VKID.WidgetEvents.ERROR, handleOneTapError)
|
||||||
|
.on(VKID.OneTapInternalEvents.LOGIN_SUCCESS, (payload) => {
|
||||||
|
const code = payload.code;
|
||||||
|
const deviceId = payload.device_id;
|
||||||
|
|
||||||
|
// Handle success directly or exchange code if needed
|
||||||
|
handleOneTapSuccess({
|
||||||
|
code: code,
|
||||||
|
device_id: deviceId
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setAuthError(`VK SDK initialization error: ${error.message}`);
|
||||||
|
emitError(`VK SDK initialization error: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOneTapSuccess = (data) => {
|
||||||
|
if (!data) {
|
||||||
|
setAuthError('Invalid response from VK ID');
|
||||||
|
emitError('Invalid response from VK ID');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const code = data.code;
|
||||||
|
const device_id = data.device_id;
|
||||||
|
let code_verifier = '';
|
||||||
|
|
||||||
|
// Extract code_verifier from cookies if backendTokenExchange is enabled
|
||||||
|
if (props.content?.backendTokenExchange === true) {
|
||||||
|
const document = wwLib.getFrontDocument();
|
||||||
|
code_verifier = (document.cookie.match(/(?:^|; )VK_code_verifier=([^;]+)/)||[])[1]||'';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set internal variables
|
||||||
|
setAuthCode(code || '');
|
||||||
|
setDeviceId(device_id || '');
|
||||||
|
setAuthError('');
|
||||||
|
|
||||||
|
// Emit success event with code_verifier
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'success',
|
||||||
|
event: {
|
||||||
|
code: code || '',
|
||||||
|
device_id: device_id || '',
|
||||||
|
code_verifier: code_verifier
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const initiateOAuthLogin = () => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
if (!validateAppConfig()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
isLoading.value = true;
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
|
||||||
|
// Build OAuth URL
|
||||||
|
const oauthUrl = new URL('https://oauth.vk.com/authorize');
|
||||||
|
oauthUrl.searchParams.append('client_id', props.content?.appId);
|
||||||
|
oauthUrl.searchParams.append('redirect_uri', props.content?.redirectUri);
|
||||||
|
oauthUrl.searchParams.append('scope', props.content?.scopes || 'email');
|
||||||
|
oauthUrl.searchParams.append('response_type', 'code');
|
||||||
|
oauthUrl.searchParams.append('v', '5.131'); // Ensure API version is set
|
||||||
|
|
||||||
|
// Add optional parameters if provided
|
||||||
|
if (props.content?.state) {
|
||||||
|
oauthUrl.searchParams.append('state', props.content?.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect to VK OAuth page
|
||||||
|
window.location.href = oauthUrl.toString();
|
||||||
|
} catch (error) {
|
||||||
|
isLoading.value = false;
|
||||||
|
setAuthError(`OAuth redirect error: ${error.message}`);
|
||||||
|
emitError(`OAuth redirect error: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOneTapError = (error) => {
|
||||||
|
const errorMessage = error?.error_description || error?.error || 'Unknown VK ID error';
|
||||||
|
setAuthError(errorMessage);
|
||||||
|
emitError(errorMessage);
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkForOAuthCode = () => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const code = urlParams.get('code');
|
||||||
|
const error = urlParams.get('error');
|
||||||
|
const errorDescription = urlParams.get('error_description');
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
// Set internal variables
|
||||||
|
setAuthCode(code);
|
||||||
|
setDeviceId('');
|
||||||
|
setAuthError('');
|
||||||
|
|
||||||
|
// Emit success event
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'success',
|
||||||
|
event: {
|
||||||
|
code: code,
|
||||||
|
device_id: '',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clean URL if configured to do so
|
||||||
|
if (props.content?.cleanUrlAfterAuth) {
|
||||||
|
const newUrl = window.location.href.split('?')[0];
|
||||||
|
window.history.replaceState({}, document.title, newUrl);
|
||||||
|
}
|
||||||
|
} else if (error || errorDescription) {
|
||||||
|
// Handle specific VK error messages
|
||||||
|
let errorMsg = errorDescription || error || 'Unknown OAuth error';
|
||||||
|
|
||||||
|
// Check for common VK error patterns
|
||||||
|
if (errorMsg.includes('способ авторизации не доступен')) {
|
||||||
|
errorMsg = 'The selected authentication method is not available for this application. Please check your VK app settings and ensure it has the required permissions.';
|
||||||
|
}
|
||||||
|
|
||||||
|
setAuthError(errorMsg);
|
||||||
|
emitError(errorMsg);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setAuthError(`Error checking OAuth response: ${error.message}`);
|
||||||
|
emitError(`Error checking OAuth response: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const emitError = (errorMessage) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'error',
|
||||||
|
event: {
|
||||||
|
error: errorMessage
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Telegram WebApp methods
|
||||||
|
const initTelegramWebApp = () => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) {
|
||||||
|
// Not running in Telegram WebApp
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const tg = window.Telegram.WebApp;
|
||||||
|
|
||||||
|
|
||||||
|
// Set all Telegram WebApp variables
|
||||||
|
setTelegramViewportHeight(tg.viewportHeight || 0);
|
||||||
|
setTelegramSafeAreaInset(tg.safeAreaInset || { top: 0, right: 0, bottom: 0, left: 0 });
|
||||||
|
setTelegramPlatform(tg.platform || '');
|
||||||
|
setTelegramColorScheme(tg.colorScheme || '');
|
||||||
|
setTelegramThemeParams(tg.themeParams || {});
|
||||||
|
setTelegramInitData(tg.initData || '');
|
||||||
|
setTelegramInitDataUnsafe(tg.initDataUnsafe || {});
|
||||||
|
setTelegramHeaderColor(tg.headerColor || '');
|
||||||
|
setTelegramBackgroundColor(tg.backgroundColor || '');
|
||||||
|
setTelegramIsExpanded(tg.isExpanded || false);
|
||||||
|
setTelegramVersion(tg.version || '');
|
||||||
|
|
||||||
|
// Set up event listeners for Telegram WebApp events
|
||||||
|
tg.onEvent('viewportChanged', updateTelegramViewportData);
|
||||||
|
tg.onEvent('themeChanged', updateTelegramThemeData);
|
||||||
|
tg.onEvent('mainButtonClicked', () => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramMainButtonClicked',
|
||||||
|
event: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tg.onEvent('backButtonClicked', () => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramBackButtonClicked',
|
||||||
|
event: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tg.onEvent('settingsButtonClicked', () => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramSettingsButtonClicked',
|
||||||
|
event: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tg.onEvent('invoiceClosed', (eventData) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramInvoiceClosed',
|
||||||
|
event: eventData || {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tg.onEvent('popupClosed', (eventData) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramPopupClosed',
|
||||||
|
event: eventData || {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tg.onEvent('qrTextReceived', (eventData) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramQrTextReceived',
|
||||||
|
event: { text: eventData || '' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tg.onEvent('clipboardTextReceived', (eventData) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramClipboardTextReceived',
|
||||||
|
event: { text: eventData || '' }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Emit telegramWebAppReady event
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramWebAppReady',
|
||||||
|
event: {
|
||||||
|
platform: tg.platform,
|
||||||
|
version: tg.version
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error initializing Telegram WebApp:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateTelegramViewportData = () => {
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
const tg = window.Telegram.WebApp;
|
||||||
|
setTelegramViewportHeight(tg.viewportHeight || 0);
|
||||||
|
setTelegramSafeAreaInset(tg.safeAreaInset || { top: 0, right: 0, bottom: 0, left: 0 });
|
||||||
|
setTelegramIsExpanded(tg.isExpanded || false);
|
||||||
|
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramViewportChanged',
|
||||||
|
event: {
|
||||||
|
viewportHeight: tg.viewportHeight,
|
||||||
|
isExpanded: tg.isExpanded,
|
||||||
|
safeAreaInset: tg.safeAreaInset
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateTelegramThemeData = () => {
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
const tg = window.Telegram.WebApp;
|
||||||
|
setTelegramColorScheme(tg.colorScheme || '');
|
||||||
|
setTelegramThemeParams(tg.themeParams || {});
|
||||||
|
setTelegramHeaderColor(tg.headerColor || '');
|
||||||
|
setTelegramBackgroundColor(tg.backgroundColor || '');
|
||||||
|
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramThemeChanged',
|
||||||
|
event: {
|
||||||
|
colorScheme: tg.colorScheme,
|
||||||
|
themeParams: tg.themeParams
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Telegram WebApp action methods
|
||||||
|
const telegramExpandApp = () => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.expand();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error expanding Telegram WebApp:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramCloseApp = () => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.close();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error closing Telegram WebApp:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramSetupMainButton = (params) => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const mainButton = window.Telegram.WebApp.MainButton;
|
||||||
|
|
||||||
|
if (params?.text) mainButton.setText(params.text);
|
||||||
|
if (params?.color) mainButton.setBackgroundColor(params.color);
|
||||||
|
if (params?.textColor) mainButton.setTextColor(params.textColor);
|
||||||
|
if (params?.isVisible !== undefined) {
|
||||||
|
params.isVisible ? mainButton.show() : mainButton.hide();
|
||||||
|
}
|
||||||
|
if (params?.isActive !== undefined) {
|
||||||
|
params.isActive ? mainButton.enable() : mainButton.disable();
|
||||||
|
}
|
||||||
|
if (params?.isProgressVisible !== undefined) {
|
||||||
|
params.isProgressVisible ? mainButton.showProgress() : mainButton.hideProgress();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error setting up Telegram MainButton:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramSetupBackButton = (isVisible) => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const backButton = window.Telegram.WebApp.BackButton;
|
||||||
|
isVisible ? backButton.show() : backButton.hide();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error setting up Telegram BackButton:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramShowPopup = (params) => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.showPopup(params, (buttonId) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramPopupClosed',
|
||||||
|
event: { buttonId }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error showing Telegram popup:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramShowAlert = (message) => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.showAlert(message, () => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramAlertClosed',
|
||||||
|
event: {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error showing Telegram alert:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramShowConfirm = (message) => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.showConfirm(message, (confirmed) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramConfirmClosed',
|
||||||
|
event: { confirmed }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error showing Telegram confirm:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramScanQrCode = () => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.showScanQrPopup({}, (text) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramQrTextReceived',
|
||||||
|
event: { text }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error showing Telegram QR scanner:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const telegramReadClipboard = () => {
|
||||||
|
if (isEditing.value) return;
|
||||||
|
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (!window.Telegram || !window.Telegram.WebApp) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.readTextFromClipboard((text) => {
|
||||||
|
emit('trigger-event', {
|
||||||
|
name: 'telegramClipboardTextReceived',
|
||||||
|
event: { text }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading from Telegram clipboard:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Lifecycle hooks
|
||||||
|
onMounted(() => {
|
||||||
|
if (!isEditing.value) {
|
||||||
|
// Check for OAuth code in URL (for redirect flow)
|
||||||
|
checkForOAuthCode();
|
||||||
|
|
||||||
|
// Load VK SDK (for One Tap flow)
|
||||||
|
if (props.content?.authMethod === 'onetap') {
|
||||||
|
loadVkSdk();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize Telegram WebApp if available
|
||||||
|
initTelegramWebApp();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
// Cleanup if needed
|
||||||
|
oneTapInstance.value = null;
|
||||||
|
|
||||||
|
// Remove Telegram WebApp event listeners if needed
|
||||||
|
const window = wwLib.getFrontWindow();
|
||||||
|
if (window.Telegram && window.Telegram.WebApp) {
|
||||||
|
try {
|
||||||
|
window.Telegram.WebApp.offEvent('viewportChanged', updateTelegramViewportData);
|
||||||
|
window.Telegram.WebApp.offEvent('themeChanged', updateTelegramThemeData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error removing Telegram WebApp event listeners:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Watch for changes in configuration
|
||||||
|
watch(() => props.content?.authMethod, (newMethod) => {
|
||||||
|
if (newMethod === 'onetap' && !isEditing.value) {
|
||||||
|
if (vkSdkLoaded.value) {
|
||||||
|
initVkIdOneTap();
|
||||||
|
} else {
|
||||||
|
loadVkSdk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(() => props.content?.appId, () => {
|
||||||
|
if (props.content?.authMethod === 'onetap' && vkSdkLoaded.value && !isEditing.value) {
|
||||||
|
initVkIdOneTap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
isEditing,
|
||||||
|
isLoading,
|
||||||
|
vkIdContainer,
|
||||||
|
buttonStyle,
|
||||||
|
initiateOAuthLogin,
|
||||||
|
authCode,
|
||||||
|
deviceId,
|
||||||
|
authError,
|
||||||
|
// Telegram WebApp variables
|
||||||
|
telegramViewportHeight,
|
||||||
|
telegramSafeAreaInset,
|
||||||
|
telegramPlatform,
|
||||||
|
telegramColorScheme,
|
||||||
|
telegramThemeParams,
|
||||||
|
telegramInitData,
|
||||||
|
telegramInitDataUnsafe,
|
||||||
|
telegramHeaderColor,
|
||||||
|
telegramBackgroundColor,
|
||||||
|
telegramIsExpanded,
|
||||||
|
telegramVersion,
|
||||||
|
// Telegram WebApp methods
|
||||||
|
telegramExpandApp,
|
||||||
|
telegramCloseApp,
|
||||||
|
telegramSetupMainButton,
|
||||||
|
telegramSetupBackButton,
|
||||||
|
telegramShowPopup,
|
||||||
|
telegramShowAlert,
|
||||||
|
telegramShowConfirm,
|
||||||
|
telegramScanQrCode,
|
||||||
|
telegramReadClipboard,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.vk-auth-component {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
&.is-loading {
|
||||||
|
opacity: 0.7;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.vk-auth-button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.vk-id-container {
|
||||||
|
min-height: 40px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vk-auth-loading {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: rgba(255, 255, 255, 0.5);
|
||||||
|
|
||||||
|
&__spinner {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid rgba(0, 119, 255, 0.3);
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top-color: #0077FF;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.telegram-info {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
font-weight: 500;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__value {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,551 @@
|
|||||||
|
export default {
|
||||||
|
editor: {
|
||||||
|
label: {
|
||||||
|
en: 'VK Auth & Telegram WebApp',
|
||||||
|
ru: 'Авторизация ВК и Telegram WebApp'
|
||||||
|
},
|
||||||
|
icon: 'login',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
appId: {
|
||||||
|
label: {
|
||||||
|
en: 'VK App ID',
|
||||||
|
ru: 'ID приложения ВК'
|
||||||
|
},
|
||||||
|
type: 'Text',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '',
|
||||||
|
},
|
||||||
|
appSetupInfo: {
|
||||||
|
label: {
|
||||||
|
en: 'VK App Setup Info',
|
||||||
|
ru: 'Информация о настройке приложения ВК'
|
||||||
|
},
|
||||||
|
type: 'Info',
|
||||||
|
section: 'settings',
|
||||||
|
options: {
|
||||||
|
text: 'Important: Your VK application must be properly configured in the VK Developer Dashboard. For OAuth flow, ensure your app has "Open API" enabled and the redirect URI is whitelisted. For VK ID One Tap, your app must have "VK ID" integration enabled with the latest SDK version.'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
redirectUri: {
|
||||||
|
label: {
|
||||||
|
en: 'Redirect URI',
|
||||||
|
ru: 'URI перенаправления'
|
||||||
|
},
|
||||||
|
type: 'Text',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '',
|
||||||
|
},
|
||||||
|
scopes: {
|
||||||
|
label: {
|
||||||
|
en: 'Scopes',
|
||||||
|
ru: 'Разрешения'
|
||||||
|
},
|
||||||
|
type: 'Text',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: 'email',
|
||||||
|
},
|
||||||
|
authMethod: {
|
||||||
|
label: {
|
||||||
|
en: 'Auth Method',
|
||||||
|
ru: 'Метод авторизации'
|
||||||
|
},
|
||||||
|
type: 'TextSelect',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: 'oauth',
|
||||||
|
options: {
|
||||||
|
options: [
|
||||||
|
{ value: 'oauth', label: 'OAuth 2.0 (Redirect)' },
|
||||||
|
{ value: 'onetap', label: 'VK ID One Tap' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
label: {
|
||||||
|
en: 'State Parameter',
|
||||||
|
ru: 'Параметр state'
|
||||||
|
},
|
||||||
|
type: 'Text',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '',
|
||||||
|
},
|
||||||
|
cleanUrlAfterAuth: {
|
||||||
|
label: {
|
||||||
|
en: 'Clean URL After Auth',
|
||||||
|
ru: 'Очистить URL после авторизации'
|
||||||
|
},
|
||||||
|
type: 'OnOff',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Text',
|
||||||
|
ru: 'Текст кнопки'
|
||||||
|
},
|
||||||
|
type: 'Text',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: 'Sign in with VK',
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
hideIcon: {
|
||||||
|
label: {
|
||||||
|
en: 'Hide VK Icon',
|
||||||
|
ru: 'Скрыть иконку ВК'
|
||||||
|
},
|
||||||
|
type: 'OnOff',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: false,
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
buttonColor: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Color',
|
||||||
|
ru: 'Цвет кнопки'
|
||||||
|
},
|
||||||
|
type: 'Color',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '#0077FF',
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
buttonTextColor: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Text Color',
|
||||||
|
ru: 'Цвет текста кнопки'
|
||||||
|
},
|
||||||
|
type: 'Color',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '#FFFFFF',
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
buttonBorderRadius: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Border Radius',
|
||||||
|
ru: 'Радиус скругления кнопки'
|
||||||
|
},
|
||||||
|
type: 'Length',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '4px',
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
buttonPadding: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Padding',
|
||||||
|
ru: 'Внутренний отступ кнопки'
|
||||||
|
},
|
||||||
|
type: 'Text',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '10px 16px',
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
buttonFontSize: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Font Size',
|
||||||
|
ru: 'Размер шрифта кнопки'
|
||||||
|
},
|
||||||
|
type: 'Length',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '14px',
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
buttonFontWeight: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Font Weight',
|
||||||
|
ru: 'Толщина шрифта кнопки'
|
||||||
|
},
|
||||||
|
type: 'TextSelect',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: '500',
|
||||||
|
options: {
|
||||||
|
options: [
|
||||||
|
{ value: '300', label: 'Light' },
|
||||||
|
{ value: '400', label: 'Regular' },
|
||||||
|
{ value: '500', label: 'Medium' },
|
||||||
|
{ value: '600', label: 'Semi Bold' },
|
||||||
|
{ value: '700', label: 'Bold' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
buttonBorder: {
|
||||||
|
label: {
|
||||||
|
en: 'Button Border',
|
||||||
|
ru: 'Граница кнопки'
|
||||||
|
},
|
||||||
|
type: 'Text',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: 'none',
|
||||||
|
hidden: content => content.authMethod === 'onetap',
|
||||||
|
},
|
||||||
|
oneTapButtonSkin: {
|
||||||
|
label: {
|
||||||
|
en: 'One Tap Button Skin',
|
||||||
|
ru: 'Стиль кнопки One Tap'
|
||||||
|
},
|
||||||
|
type: 'TextSelect',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: 'primary',
|
||||||
|
options: {
|
||||||
|
options: [
|
||||||
|
{ value: 'primary', label: 'Primary' },
|
||||||
|
{ value: 'flat', label: 'Flat' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
hidden: content => content.authMethod !== 'onetap',
|
||||||
|
},
|
||||||
|
oneTapButtonSize: {
|
||||||
|
label: {
|
||||||
|
en: 'One Tap Button Size',
|
||||||
|
ru: 'Размер кнопки One Tap'
|
||||||
|
},
|
||||||
|
type: 'TextSelect',
|
||||||
|
section: 'style',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: 'large',
|
||||||
|
options: {
|
||||||
|
options: [
|
||||||
|
{ value: 'large', label: 'Large' },
|
||||||
|
{ value: 'medium', label: 'Medium' },
|
||||||
|
{ value: 'small', label: 'Small' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
hidden: content => content.authMethod !== 'onetap',
|
||||||
|
},
|
||||||
|
showAgreements: {
|
||||||
|
label: {
|
||||||
|
en: 'Show Agreements',
|
||||||
|
ru: 'Показывать соглашения'
|
||||||
|
},
|
||||||
|
type: 'OnOff',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: true,
|
||||||
|
hidden: content => content.authMethod !== 'onetap',
|
||||||
|
},
|
||||||
|
showAlternativeLogin: {
|
||||||
|
label: {
|
||||||
|
en: 'Show Alternative Login',
|
||||||
|
ru: 'Показывать альтернативный вход'
|
||||||
|
},
|
||||||
|
type: 'OnOff',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: true,
|
||||||
|
hidden: content => content.authMethod !== 'onetap',
|
||||||
|
},
|
||||||
|
backendTokenExchange: {
|
||||||
|
label: {
|
||||||
|
en: 'Backend token exchange',
|
||||||
|
ru: 'Обмен токенов на бэкенде'
|
||||||
|
},
|
||||||
|
type: 'OnOff',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: false,
|
||||||
|
hidden: content => content.authMethod !== 'onetap',
|
||||||
|
},
|
||||||
|
// Telegram WebApp settings
|
||||||
|
telegramSection: {
|
||||||
|
label: {
|
||||||
|
en: 'Telegram WebApp',
|
||||||
|
ru: 'Telegram WebApp'
|
||||||
|
},
|
||||||
|
type: 'Section',
|
||||||
|
section: 'settings',
|
||||||
|
},
|
||||||
|
showTelegramInfo: {
|
||||||
|
label: {
|
||||||
|
en: 'Show Telegram Info',
|
||||||
|
ru: 'Показать информацию Telegram'
|
||||||
|
},
|
||||||
|
type: 'OnOff',
|
||||||
|
section: 'settings',
|
||||||
|
bindable: true,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
telegramInfoText: {
|
||||||
|
label: {
|
||||||
|
en: 'Telegram WebApp Info',
|
||||||
|
ru: 'Информация о Telegram WebApp'
|
||||||
|
},
|
||||||
|
type: 'Info',
|
||||||
|
section: 'settings',
|
||||||
|
options: {
|
||||||
|
text: 'This component automatically detects if it\'s running inside a Telegram Mini App and exposes all Telegram WebApp data as internal variables. You can access these variables in your WeWeb project and use them to adapt your UI to the Telegram environment.'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
triggerEvents: [
|
||||||
|
{
|
||||||
|
name: 'success',
|
||||||
|
label: {
|
||||||
|
en: 'On Auth Success',
|
||||||
|
ru: 'При успешной авторизации'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
code: '',
|
||||||
|
device_id: '',
|
||||||
|
code_verifier: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'error',
|
||||||
|
label: {
|
||||||
|
en: 'On Auth Error',
|
||||||
|
ru: 'При ошибке авторизации'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
error: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Telegram WebApp events
|
||||||
|
{
|
||||||
|
name: 'telegramWebAppReady',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram WebApp Ready',
|
||||||
|
ru: 'При готовности Telegram WebApp'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
platform: '',
|
||||||
|
version: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramViewportChanged',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Viewport Changed',
|
||||||
|
ru: 'При изменении области просмотра Telegram'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
viewportHeight: 0,
|
||||||
|
isExpanded: false,
|
||||||
|
safeAreaInset: { top: 0, right: 0, bottom: 0, left: 0 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramThemeChanged',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Theme Changed',
|
||||||
|
ru: 'При изменении темы Telegram'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
colorScheme: '',
|
||||||
|
themeParams: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramMainButtonClicked',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Main Button Clicked',
|
||||||
|
ru: 'При нажатии на главную кнопку Telegram'
|
||||||
|
},
|
||||||
|
event: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramBackButtonClicked',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Back Button Clicked',
|
||||||
|
ru: 'При нажатии на кнопку назад Telegram'
|
||||||
|
},
|
||||||
|
event: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramSettingsButtonClicked',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Settings Button Clicked',
|
||||||
|
ru: 'При нажатии на кнопку настроек Telegram'
|
||||||
|
},
|
||||||
|
event: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramPopupClosed',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Popup Closed',
|
||||||
|
ru: 'При закрытии всплывающего окна Telegram'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
buttonId: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramAlertClosed',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Alert Closed',
|
||||||
|
ru: 'При закрытии оповещения Telegram'
|
||||||
|
},
|
||||||
|
event: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramConfirmClosed',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Confirm Closed',
|
||||||
|
ru: 'При закрытии подтверждения Telegram'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
confirmed: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramQrTextReceived',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram QR Text Received',
|
||||||
|
ru: 'При получении текста QR-кода Telegram'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
text: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramClipboardTextReceived',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Clipboard Text Received',
|
||||||
|
ru: 'При получении текста из буфера обмена Telegram'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
text: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'telegramInvoiceClosed',
|
||||||
|
label: {
|
||||||
|
en: 'On Telegram Invoice Closed',
|
||||||
|
ru: 'При закрытии счета Telegram'
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
status: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
// Telegram WebApp actions
|
||||||
|
{
|
||||||
|
action: 'telegramExpandApp',
|
||||||
|
label: {
|
||||||
|
en: 'Expand Telegram WebApp',
|
||||||
|
ru: 'Развернуть Telegram WebApp'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramCloseApp',
|
||||||
|
label: {
|
||||||
|
en: 'Close Telegram WebApp',
|
||||||
|
ru: 'Закрыть Telegram WebApp'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramSetupMainButton',
|
||||||
|
label: {
|
||||||
|
en: 'Setup Telegram Main Button',
|
||||||
|
ru: 'Настроить главную кнопку Telegram'
|
||||||
|
},
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: 'params',
|
||||||
|
type: 'object',
|
||||||
|
label: {
|
||||||
|
en: 'Button Parameters',
|
||||||
|
ru: 'Параметры кнопки'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramSetupBackButton',
|
||||||
|
label: {
|
||||||
|
en: 'Setup Telegram Back Button',
|
||||||
|
ru: 'Настроить кнопку назад Telegram'
|
||||||
|
},
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: 'isVisible',
|
||||||
|
type: 'boolean',
|
||||||
|
label: {
|
||||||
|
en: 'Is Visible',
|
||||||
|
ru: 'Видимость'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramShowPopup',
|
||||||
|
label: {
|
||||||
|
en: 'Show Telegram Popup',
|
||||||
|
ru: 'Показать всплывающее окно Telegram'
|
||||||
|
},
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: 'params',
|
||||||
|
type: 'object',
|
||||||
|
label: {
|
||||||
|
en: 'Popup Parameters',
|
||||||
|
ru: 'Параметры всплывающего окна'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramShowAlert',
|
||||||
|
label: {
|
||||||
|
en: 'Show Telegram Alert',
|
||||||
|
ru: 'Показать оповещение Telegram'
|
||||||
|
},
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
label: {
|
||||||
|
en: 'Message',
|
||||||
|
ru: 'Сообщение'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramShowConfirm',
|
||||||
|
label: {
|
||||||
|
en: 'Show Telegram Confirm',
|
||||||
|
ru: 'Показать подтверждение Telegram'
|
||||||
|
},
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: 'message',
|
||||||
|
type: 'string',
|
||||||
|
label: {
|
||||||
|
en: 'Message',
|
||||||
|
ru: 'Сообщение'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramScanQrCode',
|
||||||
|
label: {
|
||||||
|
en: 'Scan QR Code',
|
||||||
|
ru: 'Сканировать QR-код'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: 'telegramReadClipboard',
|
||||||
|
label: {
|
||||||
|
en: 'Read Clipboard',
|
||||||
|
ru: 'Прочитать буфер обмена'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
};
|
||||||
@ -14,6 +14,7 @@ import element_b783dc65_d528_4f74_8c14_e27c934c39b1 from '@/components/elements/
|
|||||||
import element_c6c0c00e_49fd_4cb9_bd78_5bc09945721e from '@/components/elements/element-c6c0c00e-49fd-4cb9-bd78-5bc09945721e/src/wwElement.vue';
|
import element_c6c0c00e_49fd_4cb9_bd78_5bc09945721e from '@/components/elements/element-c6c0c00e-49fd-4cb9-bd78-5bc09945721e/src/wwElement.vue';
|
||||||
import element_d7904e9d_fc9a_4d80_9e32_728e097879ad from '@/components/elements/element-d7904e9d-fc9a-4d80-9e32-728e097879ad/src/wwElement.vue';
|
import element_d7904e9d_fc9a_4d80_9e32_728e097879ad from '@/components/elements/element-d7904e9d-fc9a-4d80-9e32-728e097879ad/src/wwElement.vue';
|
||||||
import element_deb10a01_5eef_4aa1_9017_1b51c2ad6fd0 from '@/components/elements/element-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0/src/wwElement.vue';
|
import element_deb10a01_5eef_4aa1_9017_1b51c2ad6fd0 from '@/components/elements/element-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0/src/wwElement.vue';
|
||||||
|
import element_eb4b02a3_cbe6_47e9_8db5_322da8047160 from '@/components/elements/element-eb4b02a3-cbe6-47e9-8db5-322da8047160/src/wwElement.vue';
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
app.component('wwobject-1b1e2173-9b78-42cc-a8ee-a6167caea340', element_1b1e2173_9b78_42cc_a8ee_a6167caea340);
|
app.component('wwobject-1b1e2173-9b78-42cc-a8ee-a6167caea340', element_1b1e2173_9b78_42cc_a8ee_a6167caea340);
|
||||||
@ -28,6 +29,7 @@ app.component('wwobject-b783dc65-d528-4f74-8c14-e27c934c39b1', element_b783dc65_
|
|||||||
app.component('wwobject-c6c0c00e-49fd-4cb9-bd78-5bc09945721e', element_c6c0c00e_49fd_4cb9_bd78_5bc09945721e);
|
app.component('wwobject-c6c0c00e-49fd-4cb9-bd78-5bc09945721e', element_c6c0c00e_49fd_4cb9_bd78_5bc09945721e);
|
||||||
app.component('wwobject-d7904e9d-fc9a-4d80-9e32-728e097879ad', element_d7904e9d_fc9a_4d80_9e32_728e097879ad);
|
app.component('wwobject-d7904e9d-fc9a-4d80-9e32-728e097879ad', element_d7904e9d_fc9a_4d80_9e32_728e097879ad);
|
||||||
app.component('wwobject-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0', element_deb10a01_5eef_4aa1_9017_1b51c2ad6fd0);
|
app.component('wwobject-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0', element_deb10a01_5eef_4aa1_9017_1b51c2ad6fd0);
|
||||||
|
app.component('wwobject-eb4b02a3-cbe6-47e9-8db5-322da8047160', element_eb4b02a3_cbe6_47e9_8db5_322da8047160);
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
import section_99586bd3_2b15_4d6b_a025_6a50d07ca845 from '@/components/sections/section-99586bd3-2b15-4d6b-a025-6a50d07ca845/src/wwSection.vue';
|
import section_99586bd3_2b15_4d6b_a025_6a50d07ca845 from '@/components/sections/section-99586bd3-2b15-4d6b-a025-6a50d07ca845/src/wwSection.vue';
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import element_83d890fb_84f9_4386_b459_fb4be89a8e15 from '@/components/elements/
|
|||||||
import element_9256b033_f4e8_4ab4_adce_dac3a940d7f5 from '@/components/elements/element-9256b033-f4e8-4ab4-adce-dac3a940d7f5/src/wwElement.vue';
|
import element_9256b033_f4e8_4ab4_adce_dac3a940d7f5 from '@/components/elements/element-9256b033-f4e8-4ab4-adce-dac3a940d7f5/src/wwElement.vue';
|
||||||
import element_b783dc65_d528_4f74_8c14_e27c934c39b1 from '@/components/elements/element-b783dc65-d528-4f74-8c14-e27c934c39b1/src/wwElement.vue';
|
import element_b783dc65_d528_4f74_8c14_e27c934c39b1 from '@/components/elements/element-b783dc65-d528-4f74-8c14-e27c934c39b1/src/wwElement.vue';
|
||||||
import element_d7904e9d_fc9a_4d80_9e32_728e097879ad from '@/components/elements/element-d7904e9d-fc9a-4d80-9e32-728e097879ad/src/wwElement.vue';
|
import element_d7904e9d_fc9a_4d80_9e32_728e097879ad from '@/components/elements/element-d7904e9d-fc9a-4d80-9e32-728e097879ad/src/wwElement.vue';
|
||||||
|
import element_eb4b02a3_cbe6_47e9_8db5_322da8047160 from '@/components/elements/element-eb4b02a3-cbe6-47e9-8db5-322da8047160/src/wwElement.vue';
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
app.component('wwobject-1b1e2173-9b78-42cc-a8ee-a6167caea340', element_1b1e2173_9b78_42cc_a8ee_a6167caea340);
|
app.component('wwobject-1b1e2173-9b78-42cc-a8ee-a6167caea340', element_1b1e2173_9b78_42cc_a8ee_a6167caea340);
|
||||||
@ -28,6 +29,7 @@ app.component('wwobject-83d890fb-84f9-4386-b459-fb4be89a8e15', element_83d890fb_
|
|||||||
app.component('wwobject-9256b033-f4e8-4ab4-adce-dac3a940d7f5', element_9256b033_f4e8_4ab4_adce_dac3a940d7f5);
|
app.component('wwobject-9256b033-f4e8-4ab4-adce-dac3a940d7f5', element_9256b033_f4e8_4ab4_adce_dac3a940d7f5);
|
||||||
app.component('wwobject-b783dc65-d528-4f74-8c14-e27c934c39b1', element_b783dc65_d528_4f74_8c14_e27c934c39b1);
|
app.component('wwobject-b783dc65-d528-4f74-8c14-e27c934c39b1', element_b783dc65_d528_4f74_8c14_e27c934c39b1);
|
||||||
app.component('wwobject-d7904e9d-fc9a-4d80-9e32-728e097879ad', element_d7904e9d_fc9a_4d80_9e32_728e097879ad);
|
app.component('wwobject-d7904e9d-fc9a-4d80-9e32-728e097879ad', element_d7904e9d_fc9a_4d80_9e32_728e097879ad);
|
||||||
|
app.component('wwobject-eb4b02a3-cbe6-47e9-8db5-322da8047160', element_eb4b02a3_cbe6_47e9_8db5_322da8047160);
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
import section_99586bd3_2b15_4d6b_a025_6a50d07ca845 from '@/components/sections/section-99586bd3-2b15-4d6b-a025-6a50d07ca845/src/wwSection.vue';
|
import section_99586bd3_2b15_4d6b_a025_6a50d07ca845 from '@/components/sections/section-99586bd3-2b15-4d6b-a025-6a50d07ca845/src/wwSection.vue';
|
||||||
|
|||||||
@ -30,12 +30,13 @@ import wwobject6dcad2080a6743a2bd1d3b13ff5819cf from '@/components/elements/elem
|
|||||||
import wwobject57831abf83ad49adba973bd30b035710 from '@/components/elements/element-57831abf-83ad-49ad-ba97-3bd30b035710/ww-config.js';
|
import wwobject57831abf83ad49adba973bd30b035710 from '@/components/elements/element-57831abf-83ad-49ad-ba97-3bd30b035710/ww-config.js';
|
||||||
import wwobject59dca300db7842e4a7a60cbf22d3cc82 from '@/components/elements/element-59dca300-db78-42e4-a7a6-0cbf22d3cc82/ww-config.js';
|
import wwobject59dca300db7842e4a7a60cbf22d3cc82 from '@/components/elements/element-59dca300-db78-42e4-a7a6-0cbf22d3cc82/ww-config.js';
|
||||||
import wwobject1be951afde7143e6ad1ee9b36de15529 from '@/components/elements/element-1be951af-de71-43e6-ad1e-e9b36de15529/ww-config.js';
|
import wwobject1be951afde7143e6ad1ee9b36de15529 from '@/components/elements/element-1be951af-de71-43e6-ad1e-e9b36de15529/ww-config.js';
|
||||||
import wwobject9ecb2cfccef74be8b7363e17a3b7e9ff from '@/components/elements/element-9ecb2cfc-cef7-4be8-b736-3e17a3b7e9ff/ww-config.js';
|
|
||||||
import wwobjectdeb10a015eef4aa190171b51c2ad6fd0 from '@/components/elements/element-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0/ww-config.js';
|
import wwobjectdeb10a015eef4aa190171b51c2ad6fd0 from '@/components/elements/element-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0/ww-config.js';
|
||||||
import wwobject985570fcb3c04566800482ab3b30a11d from '@/components/elements/element-985570fc-b3c0-4566-8004-82ab3b30a11d/ww-config.js';
|
import wwobject985570fcb3c04566800482ab3b30a11d from '@/components/elements/element-985570fc-b3c0-4566-8004-82ab3b30a11d/ww-config.js';
|
||||||
import wwobjecta823467cbdc74ceca38c71875c4c214a from '@/components/elements/element-a823467c-bdc7-4cec-a38c-71875c4c214a/ww-config.js';
|
import wwobjecta823467cbdc74ceca38c71875c4c214a from '@/components/elements/element-a823467c-bdc7-4cec-a38c-71875c4c214a/ww-config.js';
|
||||||
import wwobject9ae1fce82e314bfda4d20450235bdfd5 from '@/components/elements/element-9ae1fce8-2e31-4bfd-a4d2-0450235bdfd5/ww-config.js';
|
import wwobject9ae1fce82e314bfda4d20450235bdfd5 from '@/components/elements/element-9ae1fce8-2e31-4bfd-a4d2-0450235bdfd5/ww-config.js';
|
||||||
import wwobjectc6c0c00e49fd4cb9bd785bc09945721e from '@/components/elements/element-c6c0c00e-49fd-4cb9-bd78-5bc09945721e/ww-config.js';
|
import wwobjectc6c0c00e49fd4cb9bd785bc09945721e from '@/components/elements/element-c6c0c00e-49fd-4cb9-bd78-5bc09945721e/ww-config.js';
|
||||||
|
import wwobjecteb4b02a3cbe647e98db5322da8047160 from '@/components/elements/element-eb4b02a3-cbe6-47e9-8db5-322da8047160/ww-config.js';
|
||||||
|
import wwobject9ecb2cfccef74be8b7363e17a3b7e9ff from '@/components/elements/element-9ecb2cfc-cef7-4be8-b736-3e17a3b7e9ff/ww-config.js';
|
||||||
/* wwFront:end */
|
/* wwFront:end */
|
||||||
|
|
||||||
export const useComponentBasesStore = defineStore('componentBases', () => {
|
export const useComponentBasesStore = defineStore('componentBases', () => {
|
||||||
@ -70,12 +71,13 @@ export const useComponentBasesStore = defineStore('componentBases', () => {
|
|||||||
'wwobject-57831abf-83ad-49ad-ba97-3bd30b035710': getInheritedConfiguration({ ...wwobject57831abf83ad49adba973bd30b035710, name: 'wwobject-57831abf-83ad-49ad-ba97-3bd30b035710' }),
|
'wwobject-57831abf-83ad-49ad-ba97-3bd30b035710': getInheritedConfiguration({ ...wwobject57831abf83ad49adba973bd30b035710, name: 'wwobject-57831abf-83ad-49ad-ba97-3bd30b035710' }),
|
||||||
'wwobject-59dca300-db78-42e4-a7a6-0cbf22d3cc82': getInheritedConfiguration({ ...wwobject59dca300db7842e4a7a60cbf22d3cc82, name: 'wwobject-59dca300-db78-42e4-a7a6-0cbf22d3cc82' }),
|
'wwobject-59dca300-db78-42e4-a7a6-0cbf22d3cc82': getInheritedConfiguration({ ...wwobject59dca300db7842e4a7a60cbf22d3cc82, name: 'wwobject-59dca300-db78-42e4-a7a6-0cbf22d3cc82' }),
|
||||||
'wwobject-1be951af-de71-43e6-ad1e-e9b36de15529': getInheritedConfiguration({ ...wwobject1be951afde7143e6ad1ee9b36de15529, name: 'wwobject-1be951af-de71-43e6-ad1e-e9b36de15529' }),
|
'wwobject-1be951af-de71-43e6-ad1e-e9b36de15529': getInheritedConfiguration({ ...wwobject1be951afde7143e6ad1ee9b36de15529, name: 'wwobject-1be951af-de71-43e6-ad1e-e9b36de15529' }),
|
||||||
'wwobject-9ecb2cfc-cef7-4be8-b736-3e17a3b7e9ff': getInheritedConfiguration({ ...wwobject9ecb2cfccef74be8b7363e17a3b7e9ff, name: 'wwobject-9ecb2cfc-cef7-4be8-b736-3e17a3b7e9ff' }),
|
|
||||||
'wwobject-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0': getInheritedConfiguration({ ...wwobjectdeb10a015eef4aa190171b51c2ad6fd0, name: 'wwobject-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0' }),
|
'wwobject-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0': getInheritedConfiguration({ ...wwobjectdeb10a015eef4aa190171b51c2ad6fd0, name: 'wwobject-deb10a01-5eef-4aa1-9017-1b51c2ad6fd0' }),
|
||||||
'wwobject-985570fc-b3c0-4566-8004-82ab3b30a11d': getInheritedConfiguration({ ...wwobject985570fcb3c04566800482ab3b30a11d, name: 'wwobject-985570fc-b3c0-4566-8004-82ab3b30a11d' }),
|
'wwobject-985570fc-b3c0-4566-8004-82ab3b30a11d': getInheritedConfiguration({ ...wwobject985570fcb3c04566800482ab3b30a11d, name: 'wwobject-985570fc-b3c0-4566-8004-82ab3b30a11d' }),
|
||||||
'wwobject-a823467c-bdc7-4cec-a38c-71875c4c214a': getInheritedConfiguration({ ...wwobjecta823467cbdc74ceca38c71875c4c214a, name: 'wwobject-a823467c-bdc7-4cec-a38c-71875c4c214a' }),
|
'wwobject-a823467c-bdc7-4cec-a38c-71875c4c214a': getInheritedConfiguration({ ...wwobjecta823467cbdc74ceca38c71875c4c214a, name: 'wwobject-a823467c-bdc7-4cec-a38c-71875c4c214a' }),
|
||||||
'wwobject-9ae1fce8-2e31-4bfd-a4d2-0450235bdfd5': getInheritedConfiguration({ ...wwobject9ae1fce82e314bfda4d20450235bdfd5, name: 'wwobject-9ae1fce8-2e31-4bfd-a4d2-0450235bdfd5' }),
|
'wwobject-9ae1fce8-2e31-4bfd-a4d2-0450235bdfd5': getInheritedConfiguration({ ...wwobject9ae1fce82e314bfda4d20450235bdfd5, name: 'wwobject-9ae1fce8-2e31-4bfd-a4d2-0450235bdfd5' }),
|
||||||
'wwobject-c6c0c00e-49fd-4cb9-bd78-5bc09945721e': getInheritedConfiguration({ ...wwobjectc6c0c00e49fd4cb9bd785bc09945721e, name: 'wwobject-c6c0c00e-49fd-4cb9-bd78-5bc09945721e' })};
|
'wwobject-c6c0c00e-49fd-4cb9-bd78-5bc09945721e': getInheritedConfiguration({ ...wwobjectc6c0c00e49fd4cb9bd785bc09945721e, name: 'wwobject-c6c0c00e-49fd-4cb9-bd78-5bc09945721e' }),
|
||||||
|
'wwobject-eb4b02a3-cbe6-47e9-8db5-322da8047160': getInheritedConfiguration({ ...wwobjecteb4b02a3cbe647e98db5322da8047160, name: 'wwobject-eb4b02a3-cbe6-47e9-8db5-322da8047160' }),
|
||||||
|
'wwobject-9ecb2cfc-cef7-4be8-b736-3e17a3b7e9ff': getInheritedConfiguration({ ...wwobject9ecb2cfccef74be8b7363e17a3b7e9ff, name: 'wwobject-9ecb2cfc-cef7-4be8-b736-3e17a3b7e9ff' })};
|
||||||
/* wwFront:end */
|
/* wwFront:end */
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -98,7 +98,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setValue(variableId, value, { ignoreQuery, path, index, arrayUpdateType, workflowContext } = {}) {
|
function setValue(variableId, value, { ignoreQuery, path, index, arrayUpdateType, workflowContext, silent } = {}) {
|
||||||
const configuration = this.getConfiguration(variableId);
|
const configuration = this.getConfiguration(variableId);
|
||||||
if (!configuration) return;
|
if (!configuration) return;
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
@ -170,6 +170,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
if (configuration.type === 'object' && path) {
|
if (configuration.type === 'object' && path) {
|
||||||
this.values[variableId] = this.values[variableId] || {};
|
this.values[variableId] = this.values[variableId] || {};
|
||||||
set(this.values[variableId], path, value);
|
set(this.values[variableId], path, value);
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(`Variable _wwVariable(${variableId}) update`, {
|
wwLib.logStore.verbose(`Variable _wwVariable(${variableId}) update`, {
|
||||||
preview: this.values[variableId],
|
preview: this.values[variableId],
|
||||||
workflowContext,
|
workflowContext,
|
||||||
@ -185,6 +186,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
finalPath = `${finalPath}.${path}`;
|
finalPath = `${finalPath}.${path}`;
|
||||||
}
|
}
|
||||||
set(this.values[variableId], finalPath, value);
|
set(this.values[variableId], finalPath, value);
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(`Updating partially array variable _wwVariable(${variableId}) `, {
|
wwLib.logStore.verbose(`Updating partially array variable _wwVariable(${variableId}) `, {
|
||||||
preview: value,
|
preview: value,
|
||||||
workflowContext,
|
workflowContext,
|
||||||
@ -194,6 +196,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
}
|
}
|
||||||
case 'delete':
|
case 'delete':
|
||||||
this.values[variableId].splice(index, 1);
|
this.values[variableId].splice(index, 1);
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(`Deleting item ${index} from array _wwVariable(${variableId})`, {
|
wwLib.logStore.verbose(`Deleting item ${index} from array _wwVariable(${variableId})`, {
|
||||||
workflowContext,
|
workflowContext,
|
||||||
type: workflowContext ? 'action' : null,
|
type: workflowContext ? 'action' : null,
|
||||||
@ -201,6 +204,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
break;
|
break;
|
||||||
case 'insert':
|
case 'insert':
|
||||||
this.values[variableId].splice(index, 0, value);
|
this.values[variableId].splice(index, 0, value);
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(
|
wwLib.logStore.verbose(
|
||||||
`Inserting value into array variable at index ${index} _wwVariable(${variableId}) `,
|
`Inserting value into array variable at index ${index} _wwVariable(${variableId}) `,
|
||||||
{
|
{
|
||||||
@ -212,13 +216,18 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
break;
|
break;
|
||||||
case 'unshift':
|
case 'unshift':
|
||||||
this.values[variableId].unshift(value);
|
this.values[variableId].unshift(value);
|
||||||
wwLib.logStore.verbose(`Removing first element from array variable _wwVariable(${variableId}) `, {
|
if (!silent)
|
||||||
|
wwLib.logStore.verbose(
|
||||||
|
`Removing first element from array variable _wwVariable(${variableId}) `,
|
||||||
|
{
|
||||||
workflowContext,
|
workflowContext,
|
||||||
type: workflowContext ? 'action' : null,
|
type: workflowContext ? 'action' : null,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case 'push':
|
case 'push':
|
||||||
this.values[variableId].push(value);
|
this.values[variableId].push(value);
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(
|
wwLib.logStore.verbose(
|
||||||
`Adding value at the end of the array variable _wwVariable(${variableId}) `,
|
`Adding value at the end of the array variable _wwVariable(${variableId}) `,
|
||||||
{
|
{
|
||||||
@ -230,6 +239,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
break;
|
break;
|
||||||
case 'shift':
|
case 'shift':
|
||||||
this.values[variableId].shift(value);
|
this.values[variableId].shift(value);
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(
|
wwLib.logStore.verbose(
|
||||||
`Adding value at the start of the array variable _wwVariable(${variableId}) `,
|
`Adding value at the start of the array variable _wwVariable(${variableId}) `,
|
||||||
{
|
{
|
||||||
@ -241,6 +251,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
break;
|
break;
|
||||||
case 'pop':
|
case 'pop':
|
||||||
this.values[variableId].pop(value);
|
this.values[variableId].pop(value);
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(`Removing last value of the array variable _wwVariable(${variableId})`, {
|
wwLib.logStore.verbose(`Removing last value of the array variable _wwVariable(${variableId})`, {
|
||||||
workflowContext,
|
workflowContext,
|
||||||
type: workflowContext ? 'action' : null,
|
type: workflowContext ? 'action' : null,
|
||||||
@ -249,6 +260,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.values[variableId] = value;
|
this.values[variableId] = value;
|
||||||
|
if (!silent)
|
||||||
wwLib.logStore.verbose(`Setting value for _wwVariable(${variableId}) `, {
|
wwLib.logStore.verbose(`Setting value for _wwVariable(${variableId}) `, {
|
||||||
preview: _.cloneDeep(value),
|
preview: _.cloneDeep(value),
|
||||||
workflowContext,
|
workflowContext,
|
||||||
@ -257,7 +269,7 @@ export const useVariablesStore = defineStore('variables', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.isLocalStorage && window.localStorage) {
|
if (configuration.isLocalStorage && window.localStorage) {
|
||||||
wwLib.logStore.verbose(`Updating localStorage to synchronize with _wwVariable(${variableId})`);
|
if (!silent) wwLib.logStore.verbose(`Updating localStorage to synchronize with _wwVariable(${variableId})`);
|
||||||
switch (configuration.type) {
|
switch (configuration.type) {
|
||||||
case 'query':
|
case 'query':
|
||||||
case 'string':
|
case 'string':
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* @PUBLIC_API
|
* @PUBLIC_API
|
||||||
*/
|
*/
|
||||||
updateValue(variableId, value, { path, index, arrayUpdateType, workflowContext } = {}) {
|
updateValue(variableId, value, { path, index, arrayUpdateType, workflowContext, silent } = {}) {
|
||||||
const variablesStore = useVariablesStore(wwLib.$pinia);
|
const variablesStore = useVariablesStore(wwLib.$pinia);
|
||||||
const variable = variablesStore.getConfiguration(variableId);
|
const variable = variablesStore.getConfiguration(variableId);
|
||||||
try {
|
try {
|
||||||
@ -32,7 +32,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
value = checkVariableType(variable, value, { path, arrayUpdateType });
|
value = checkVariableType(variable, value, { path, arrayUpdateType });
|
||||||
variablesStore.setValue(variableId, value, { path, index, arrayUpdateType, workflowContext });
|
variablesStore.setValue(variableId, value, { path, index, arrayUpdateType, workflowContext, silent });
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -12,20 +12,20 @@
|
|||||||
|
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico?_wwcv={{cacheVersion}}" />
|
<link rel="icon" type="image/x-icon" href="favicon.ico?_wwcv={{cacheVersion}}" />
|
||||||
|
|
||||||
<link rel="manifest" href="manifest.json?_wwcv=183" />
|
<link rel="manifest" href="manifest.json?_wwcv=189" />
|
||||||
<meta name="theme-color" content="" />
|
<meta name="theme-color" content="" />
|
||||||
<link rel="apple-touch-icon" sizes="48x48" href="images/48-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="48x48" href="images/48-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="images/72-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="72x72" href="images/72-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="96x96" href="images/96-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="96x96" href="images/96-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="128x128" href="images/128-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="128x128" href="images/128-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="images/144-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="144x144" href="images/144-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="images/152-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="152x152" href="images/152-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="192x192" href="images/192-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="192x192" href="images/192-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="256x256" href="images/256-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="256x256" href="images/256-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="384x384" href="images/384-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="384x384" href="images/384-favicon.png?_wwcv=189">
|
||||||
<link rel="apple-touch-icon" sizes="512x512" href="images/512-favicon.png?_wwcv=183">
|
<link rel="apple-touch-icon" sizes="512x512" href="images/512-favicon.png?_wwcv=189">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
<link href="/fonts/Phosphor/font.css?_wwcv=183" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
<link href="/fonts/Phosphor/font.css?_wwcv=189" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
<link href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
<style>:root{ --ww-default-font-family: 'Raleway', sans-serif }</style>
|
<style>:root{ --ww-default-font-family: 'Raleway', sans-serif }</style>
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user