|
|
- import { CORE_TEMPLATES } from '../scripts/mappingTemplates.js';
- import { TVA_CONFIG, updateSettings } from '../scripts/settings.js';
- import { showMappingSelectDialog, showUserTemplateCreateDialog } from './dialogs.js';
-
- export class Templates extends FormApplication {
- constructor({ mappings = null, callback = null } = {}) {
- super({}, {});
- this.mappings = mappings;
- this.callback = callback;
- }
-
- static get defaultOptions() {
- return mergeObject(super.defaultOptions, {
- id: 'token-variants-templates',
- classes: ['sheet'],
- template: 'modules/token-variants/templates/templates.html',
- resizable: false,
- minimizable: false,
- title: 'Mapping Templates',
- width: 500,
- height: 'auto',
- });
- }
-
- async getData(options) {
- const data = super.getData(options);
-
- if (!this.category) this.category = TVA_CONFIG.templateMappings?.length ? 'user' : 'core';
- if (this.category === 'user') {
- this.templates = TVA_CONFIG.templateMappings;
- } else if (this.category === 'core') {
- this.templates = CORE_TEMPLATES;
- } else {
- this.templates = await communityTemplates();
- }
-
- for (const template of this.templates) {
- template.hint = template.hint?.replace(/(\r\n|\n|\r)/gm, '<br>');
- }
-
- data.category = this.category;
- data.templates = this.templates;
- data.allowDelete = this.category === 'user';
- data.allowCreate = this.category === 'user';
- data.allowCopy = this.category === 'community' || this.category === 'core';
-
- return data;
- }
-
- /**
- * @param {JQuery} html
- */
- activateListeners(html) {
- super.activateListeners(html);
-
- // Position tooltip
- const appWindow = html.closest('#token-variants-templates');
- html.find('.template').on('mouseover', (event) => {
- const template = $(event.target).closest('.template');
- const pos = template.position();
- const tooltip = template.find('.tooltiptext');
- const windowPos = appWindow.position();
- tooltip.css('top', windowPos.top + pos.top).css('left', windowPos.left + pos.left);
-
- // Lazy load image
- const img = template.find('img');
- if (!img.attr('src')) img.attr('src', img.data('src'));
- });
-
- if (this.callback) {
- html.find('.template').on('click', async (event) => {
- const li = $(event.target).closest('.template');
- const id = li.data('id');
- const url = li.data('url');
- let mappings;
- let templateName;
- if (url) {
- const template = await getTemplateFromFileURL(url);
- if (template) mappings = template.mappings;
- } else if (id) {
- const template = this.templates.find((t) => t.id === id);
- if (template) {
- templateName = template.name;
- mappings = template.mappings;
- }
- }
-
- if (mappings) this.callback(templateName, mappings);
- });
- }
-
- html.find('.search').on('input', () => {
- const filter = html.find('.search').val().trim().toLowerCase();
- html.find('.template-list li').each(function () {
- const li = $(this);
- const description = li.find('.description').text().trim().toLowerCase();
- const name = li.data('name').trim().toLowerCase();
- const createdBy = li.data('creator').trim().toLowerCase();
- if (name.includes(filter) || description.includes(filter) || createdBy.includes(filter)) li.show();
- else li.hide();
- });
- });
-
- html.find('[name="category"]').on('change', (event) => {
- this.category = event.target.value;
- this.render(true);
- });
-
- html.find('.delete').on('click', async (event) => {
- event.preventDefault();
- event.stopPropagation();
-
- const id = $(event.target).closest('.template').data('id');
- if (id) {
- await updateSettings({
- templateMappings: TVA_CONFIG.templateMappings.filter((m) => m.id !== id),
- });
- this.render(true);
- }
- });
-
- html.find('.copy').on('click', async (event) => {
- event.preventDefault();
- event.stopPropagation();
-
- const id = $(event.target).closest('.template').data('id');
- if (id) {
- let template;
- if (this.category === 'core') {
- template = deepClone(CORE_TEMPLATES.find((t) => t.id === id));
- } else {
- const fileURL = $(event.target).closest('.template').data('url');
- if (fileURL) template = await getTemplateFromFileURL(fileURL);
- }
-
- if (template) {
- TVA_CONFIG.templateMappings.push(template);
- await updateSettings({
- templateMappings: TVA_CONFIG.templateMappings,
- });
- ui.notifications.info(`Template {${template.name}} copied to User templates.`);
- this.render(true);
- }
- }
- });
-
- html.find('.create').on('click', () => {
- showMappingSelectDialog(this.mappings, {
- title1: 'Create Template',
- callback: (selectedMappings) => {
- if (selectedMappings.length) showUserTemplateCreateDialog(selectedMappings);
- },
- });
- });
- }
-
- _getHeaderButtons() {
- const buttons = super._getHeaderButtons();
- buttons.unshift({
- label: 'Upload Template',
- class: '.token-variants-submit-template',
- icon: 'fa-solid fa-cloud-arrow-up',
- onclick: () => {
- new TemplateSubmissionForm().render(true);
- },
- });
- return buttons;
- }
-
- /**
- * @param {Event} event
- * @param {Object} formData
- */
- async _updateObject(event, formData) {}
- }
-
- class TemplateSubmissionForm extends FormApplication {
- constructor() {
- super({}, {});
- }
-
- static apiKey = 'AIzaSyCJpwIkpjrG10jaHwcpllvSChxRPawcMXE';
-
- static get pk() {
- const k2 = 'AIzaSyCJpw';
- const k1 = 'IkpjrG10jaHwcpllv';
- const k3 = 'SChxRPawcMXE';
- return k2 + k1 + k3;
- }
-
- static get defaultOptions() {
- return mergeObject(super.defaultOptions, {
- id: 'token-variants-template-submission',
- classes: ['sheet'],
- template: 'modules/token-variants/templates/templateSubmission.html',
- resizable: true,
- minimizable: false,
- closeOnSubmit: false,
- title: 'Upload Template',
- width: 500,
- height: 'auto',
- });
- }
-
- async getData(options) {
- const data = super.getData(options);
-
- data.systemID = game.system.id;
- data.systemTitle = game.system.title;
- data.templates = TVA_CONFIG.templateMappings;
-
- return data;
- }
-
- /**
- * @param {Event} event
- * @param {Object} formData
- */
- async _updateObject(event, formData) {
- if (!formData.template) return;
- let template = TVA_CONFIG.templateMappings.find((t) => t.id === formData.template);
- if (!template) return;
-
- const name = formData.name.trim() || template.name;
- const hint = formData.hint.trim() || template.hint?.trim();
- const createdBy = formData.createdBy.trim();
- const system = formData.system;
- const id = randomID();
- const img = formData.img.trim();
-
- const result = submitTemplate({ id, name, hint, img, createdBy, system, mappings: template.mappings });
- if (result) this.close();
- }
- }
-
- function _setStringField(template, fields, field) {
- if (template[field] && template[field] !== '') {
- fields[field] = { stringValue: template[field] };
- }
- }
-
- async function submitTemplate(template) {
- const fields = {};
- ['name', 'hint', 'img', 'id', 'createdBy', 'system'].forEach((field) => _setStringField(template, fields, field));
- fields.mappings = { stringValue: JSON.stringify(template.mappings) };
- fields.createTime = { integerValue: new Date().getTime() };
- fields.approved = { booleanValue: false };
-
- const response = await fetch(
- `https://firestore.googleapis.com/v1/projects/tva---templates/databases/(default)/documents/templates?key=${TemplateSubmissionForm.pk}`,
- {
- method: 'POST',
- body: JSON.stringify({
- fields: fields,
- }),
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- },
- }
- );
-
- if (response.ok && response.status === 200) {
- ui.notifications.info('Template submission completed.');
- return true;
- } else {
- ui.notifications.warn('Template submission failed.');
- return false;
- }
- }
-
- const SEARCH_QUERY = {
- structuredQuery: {
- select: {
- fields: [
- {
- fieldPath: 'id',
- },
- {
- fieldPath: 'name',
- },
- {
- fieldPath: 'hint',
- },
- {
- fieldPath: 'createdBy',
- },
- {
- fieldPath: 'img',
- },
- {
- fieldPath: 'system',
- },
- ],
- },
- where: {
- fieldFilter: {
- field: {
- fieldPath: 'approved',
- },
- op: 'EQUAL',
- value: {
- booleanValue: true,
- },
- },
- },
- from: [{ collectionId: 'templates' }],
- orderBy: [
- {
- field: {
- fieldPath: 'createTime',
- },
- },
- ],
- offset: 0,
- limit: 50,
- },
- };
-
- async function communityTemplates(search = null) {
- const response = await fetch(
- `https://firestore.googleapis.com/v1/projects/tva---templates/databases/(default)/documents:runQuery?key=${TemplateSubmissionForm.pk}`,
- {
- method: 'POST',
- body: JSON.stringify(SEARCH_QUERY),
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- },
- }
- );
-
- const templates = [];
- if (response.ok && response.status === 200) {
- const documents = await response.json();
-
- for (let doc of documents) {
- if ('document' in doc) templates.push(_docToTemplate(doc.document));
- }
- } else {
- ui.notifications.warn('Failed to retrieve Community templates.');
- }
- return templates;
- }
-
- function _docToTemplate(doc) {
- const template = {};
- ['id', 'name', 'mappings', 'createdBy', 'img', 'hint', 'system'].forEach((f) => {
- template[f] = doc.fields[f]?.stringValue || '';
- });
- if (template.mappings) template.mappings = JSON.parse(template.mappings);
- else template.fileURL = doc.name;
-
- if (!template.createdBy) template.createdBy = 'Anonymous';
- return template;
- }
-
- async function getTemplateFromFileURL(fileURL) {
- const response = await fetch(`https://firestore.googleapis.com/v1/${fileURL}?key=${TemplateSubmissionForm.pk}`, {
- method: 'GET',
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- },
- });
-
- if (response.ok && response.status === 200) {
- const doc = await response.json();
- return _docToTemplate(doc);
- }
- return null;
- }
|