From 62ff7b27ad9db7d15f411b0e313e7ec3363075dd Mon Sep 17 00:00:00 2001 From: VerZsuT Date: Sat, 16 Mar 2024 13:56:37 +0300 Subject: [PATCH 01/16] add trailer center of mass --- .../pages/main/editor/components/tables/trailer/index.vue | 6 ++++++ .../pages/main/editor/components/tables/trailer/texts.ts | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/renderer/pages/main/editor/components/tables/trailer/index.vue b/src/renderer/pages/main/editor/components/tables/trailer/index.vue index facf993..edfb976 100644 --- a/src/renderer/pages/main/editor/components/tables/trailer/index.vue +++ b/src/renderer/pages/main/editor/components/tables/trailer/index.vue @@ -76,6 +76,11 @@ key="mass" :label="texts.mass" > + import { SaveUtils } from '../../../utils' import Accordion from '../../accordion.vue' +import Coords from '../../coords' import Group from '../../group' import { Float, Int } from '../../input' import type { ReadyEmits, ReadyProps } from '../../utils' diff --git a/src/renderer/pages/main/editor/components/tables/trailer/texts.ts b/src/renderer/pages/main/editor/components/tables/trailer/texts.ts index 311ce05..465dea0 100644 --- a/src/renderer/pages/main/editor/components/tables/trailer/texts.ts +++ b/src/renderer/pages/main/editor/components/tables/trailer/texts.ts @@ -56,6 +56,12 @@ export default localize({ [Lang.de]: 'Anzahl der Räder zu reparieren', [Lang.ch]: '需要修复的车轮数量' }, + centerOfMass: { + [Lang.ru]: 'Смещение центра масс', + [Lang.en]: 'Center of mass offset', + [Lang.de]: 'Versatz des Massenzentrums', + [Lang.ch]: '质量中心的位移' + }, trailerMass: { [Lang.ru]: 'Масса прицепа', [Lang.en]: 'Trailer mass', From 54708ae6dfef30e4a6489db6d5840529dd43e23d Mon Sep 17 00:00:00 2001 From: VerZsuT Date: Sat, 16 Mar 2024 17:59:06 +0300 Subject: [PATCH 02/16] add raw-edit --- package.json | 22 +-- src/modules/data/config/main.ts | 5 +- src/modules/files/main.ts | 6 +- src/modules/files/renderer.ts | 6 +- src/modules/helpers/main.ts | 1 + src/modules/helpers/public.ts | 2 + src/modules/helpers/renderer.ts | 3 + src/modules/xml/xml-element.ts | 45 +++++- src/renderer/components/language/index.vue | 9 +- .../main/editor/components/error-header.vue | 17 --- .../extra/addons-content/content-field.vue | 3 +- .../components/extra/addons-content/index.vue | 38 ++++-- .../main/editor/components/extra/texts.ts | 6 + .../editor/components/files-menu/file.vue | 23 ++++ .../editor/components/files-menu/files.vue | 29 ++++ .../editor/components/files-menu/index.ts | 1 + .../editor/components/files-menu/index.vue | 54 ++++++++ .../editor/components/files-menu/texts.ts | 47 +++++++ .../editor/components/header/error-header.vue | 54 ++++++++ .../main/editor/components/header/index.ts | 1 + .../main/editor/components/header/index.vue | 82 +++++++++++ .../components/{ => header}/main-header.vue | 51 +++---- .../pages/main/editor/components/index.ts | 5 +- .../components/tables/engines/index.vue | 26 +++- .../components/tables/gearboxes/index.vue | 25 +++- .../main/editor/components/tables/index.ts | 8 +- .../main/editor/components/tables/index.vue | 46 +++++++ .../components/tables/suspensions/index.vue | 26 +++- .../editor/components/tables/wheels/index.vue | 43 ++++-- .../components/tables/winches/index.vue | 25 +++- .../pages/main/editor/components/utils.ts | 4 +- src/renderer/pages/main/editor/index.vue | 129 +++++++++--------- src/renderer/pages/main/editor/utils/files.ts | 66 +++++++++ src/renderer/pages/main/editor/utils/index.ts | 2 + src/renderer/pages/main/store/editor.ts | 28 +++- src/renderer/pages/whats-new/index.vue | 12 +- 36 files changed, 738 insertions(+), 212 deletions(-) delete mode 100644 src/renderer/pages/main/editor/components/error-header.vue create mode 100644 src/renderer/pages/main/editor/components/files-menu/file.vue create mode 100644 src/renderer/pages/main/editor/components/files-menu/files.vue create mode 100644 src/renderer/pages/main/editor/components/files-menu/index.ts create mode 100644 src/renderer/pages/main/editor/components/files-menu/index.vue create mode 100644 src/renderer/pages/main/editor/components/files-menu/texts.ts create mode 100644 src/renderer/pages/main/editor/components/header/error-header.vue create mode 100644 src/renderer/pages/main/editor/components/header/index.ts create mode 100644 src/renderer/pages/main/editor/components/header/index.vue rename src/renderer/pages/main/editor/components/{ => header}/main-header.vue (82%) create mode 100644 src/renderer/pages/main/editor/components/tables/index.vue create mode 100644 src/renderer/pages/main/editor/utils/files.ts diff --git a/package.json b/package.json index 153096e..af2e0ac 100644 --- a/package.json +++ b/package.json @@ -28,32 +28,34 @@ }, "devDependencies": { "@ant-design/icons-vue": "^7.0.1", - "@electron-forge/cli": "^7.3.0", - "@electron-forge/plugin-vite": "^7.3.0", + "@electron-forge/cli": "^7.3.1", + "@electron-forge/plugin-vite": "^7.3.1", "@types/memoizee": "^0.4.11", - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", "@vitejs/plugin-vue": "^5.0.4", "ant-design-vue": "^4.1.2", "cheerio": "^1.0.0-rc.12", "cross-env": "^7.0.3", - "electron": "^29.1.0", + "debounce": "^2.0.0", + "electron": "^29.1.5", "emr-bridge": "^1.7.1", "eslint": "^8.57.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-unicorn": "^51.0.1", - "eslint-plugin-vue": "^9.22.0", + "eslint-plugin-vue": "^9.23.0", "memoizee": "^0.4.15", "pinia": "^2.1.7", - "sass": "^1.71.1", + "sass": "^1.72.0", "ts-node": "^10.9.2", "tslib": "^2.6.2", - "typescript": "^5.3.3", - "vite": "^5.1.4", + "typescript": "^5.4.3", + "vite": "^5.2.4", "vite-plugin-static-copy": "^1.0.1", "vue": "^3.4.21", "vue-eslint-parser": "^9.4.2", - "vue-tsc": "^1.8.27" + "vue-tsc": "^2.0.7", + "xml-formatter": "^3.6.2" } } diff --git a/src/modules/data/config/main.ts b/src/modules/data/config/main.ts index c1f31e2..7914606 100644 --- a/src/modules/data/config/main.ts +++ b/src/modules/data/config/main.ts @@ -151,13 +151,14 @@ class Config extends HasPublic { private async getFromJSON(defaultConfig: IConfig): Promise { const data = await Files.config.readFromJSON<{ version: string }>() const version = this.getVersion(data.version) + const thisVersion = this.getVersion(this.default.version) let config: IConfig - if (version === this.default.version) { + if (version === thisVersion) { config = data as IConfig } - else if (version < this.default.version) { + else if (version < thisVersion) { config = await this.convertToNewest(data) } else { diff --git a/src/modules/files/main.ts b/src/modules/files/main.ts index c9f18b6..6e5b1ce 100644 --- a/src/modules/files/main.ts +++ b/src/modules/files/main.ts @@ -1,5 +1,5 @@ import { execFile } from 'node:child_process' -import type { WatchEventType } from 'node:fs' +import type { WatchListener } from 'node:fs' import { watch } from 'node:fs' import { access, chmod, constants, copyFile, lstat, mkdir, readFile, readdir, rename, rm, writeFile } from 'node:fs/promises' import { basename, dirname, extname, join } from 'node:path' @@ -268,8 +268,8 @@ export class File extends FSEntry { } /** Отслеживает изменения файла */ - watch(listener: (event: WatchEventType) => void) { - watch(this.path, { persistent: false }, listener) + watch(listener: WatchListener) { + return watch(this.path, { persistent: false }, listener) } /** Исполняет файл */ diff --git a/src/modules/files/renderer.ts b/src/modules/files/renderer.ts index 0336bb4..2c2ea11 100644 --- a/src/modules/files/renderer.ts +++ b/src/modules/files/renderer.ts @@ -1,6 +1,6 @@ import type CP from 'node:child_process' import type FS from 'node:fs' -import type { WatchEventType } from 'node:fs' +import type { WatchListener } from 'node:fs' import type FSP from 'node:fs/promises' import type PATH from 'node:path' @@ -286,8 +286,8 @@ export class File extends FSEntry { } /** Отслеживает изменения файла */ - watch(listener: (event: WatchEventType) => void) { - watch(this.path, { persistent: false }, listener) + watch(listener: WatchListener) { + return watch(this.path, { persistent: false }, listener) } /** Исполняет файл */ diff --git a/src/modules/helpers/main.ts b/src/modules/helpers/main.ts index acb2081..f1fba9d 100644 --- a/src/modules/helpers/main.ts +++ b/src/modules/helpers/main.ts @@ -74,6 +74,7 @@ class Helpers extends HasPublic { publicFunction(PubKeys.homedir, homedir) publicFunction(PubKeys.userInfo, userInfo) publicFunction(PubKeys.openLink, shell.openExternal) + publicFunction(PubKeys.openFile, shell.openExternal) publicFunction(PubKeys.openPath, shell.openPath) publicFunction(PubKeys.reloadApp, () => { app.relaunch(); app.quit() }) publicFunction(PubKeys.quitApp, app.quit) diff --git a/src/modules/helpers/public.ts b/src/modules/helpers/public.ts index 3616b75..d09d1f0 100644 --- a/src/modules/helpers/public.ts +++ b/src/modules/helpers/public.ts @@ -9,6 +9,7 @@ export enum PubKeys { homedir = 'helpers/homedir', userInfo = 'helpers/user-info', openLink = 'helpers/open-link', + openFile = 'helpers/open-file', openPath = 'helpers/open-path', reloadApp = 'helpers/reload-app', quitApp = 'helpers/quit-app', @@ -21,6 +22,7 @@ export type PubType = { [PubKeys.homedir]: typeof homedir [PubKeys.userInfo]: typeof userInfo [PubKeys.openLink](url: string): Promise + [PubKeys.openFile](path: string): Promise [PubKeys.openPath](path: string): Promise [PubKeys.reloadApp](): void [PubKeys.quitApp](): void diff --git a/src/modules/helpers/renderer.ts b/src/modules/helpers/renderer.ts index 3d05697..9c7cf47 100644 --- a/src/modules/helpers/renderer.ts +++ b/src/modules/helpers/renderer.ts @@ -35,6 +35,9 @@ class Helpers { /** Открывает путь в проводнике */ openPath = providePubFunc(PubKeys.openPath) + /** Открывает файл для редактирования */ + openFile = providePubFunc(PubKeys.openFile) + /** Перезагружает программу */ reloadApp = providePubFunc(PubKeys.reloadApp) diff --git a/src/modules/xml/xml-element.ts b/src/modules/xml/xml-element.ts index 8aead09..a12ad47 100644 --- a/src/modules/xml/xml-element.ts +++ b/src/modules/xml/xml-element.ts @@ -4,6 +4,8 @@ import { load } from 'cheerio' import { File } from '/mods/files/renderer' import { hasItems, isString } from '/utils/checks/renderer' +import xmlFormat from 'xml-formatter' + /** Объект DOM элемента */ export default class XMLElement { /** Является ли аргумент `XMLElement` */ @@ -17,7 +19,7 @@ export default class XMLElement { static async from(file: File): Promise static async from(source: File | string): Promise { const data = File.isFile(source) ? (await source.read()) : source - const xml = load(data || '', { xmlMode: true }) + const xml = load(data || '', { xml: true }) if (!data || !xml.xml()) return return new this(xml.root()) @@ -39,9 +41,9 @@ export default class XMLElement { return new XMLElement(this.element.parent()) } + /** Строковое представление элемента */ get xml() { - const string = this.element.html() || '' let attrs: string[] | undefined if (this.hasAttrs()) { @@ -51,15 +53,48 @@ export default class XMLElement { } } if (this.tagName) { - return `<${this.tagName}${attrs && hasItems(attrs) ? ` ${attrs.join(' ')}` : ''}>\n${string}\n` + // eslint-disable-next-line unicorn/prefer-ternary + if (this.innerXML) { + return xmlFormat(`<${this.tagName}${attrs && hasItems(attrs) ? ` ${attrs.join(' ')}` : ''}>${this.innerXML}`) + } + else { + return xmlFormat(`<${this.tagName}${attrs && hasItems(attrs) ? ` ${attrs.join(' ')}` : ''} />`) + } } - return load(string, { xmlMode: true }).xml() + return this.baseXML } + /** Строковое представление элемента вместе с базовым тегом */ get baseXML() { - return load(this.baseElement.html() || '', { xmlMode: true }).xml() + const cloned = this.baseElement.clone() + const templates = cloned.find('_templates').eq(0) + + function format(str: string) { + return xmlFormat(str, { + whiteSpaceAtEndOfSelfclosingTag: true, + forceSelfClosingEmptyTag: true, + indentation: ' ' + }) + } + + let templatesText = '' + if (templates.length === 1) { + const Include = templates.attr('Include') + const templatesXML = `<_templates${Include ? ` Include="${Include}"` : ''}>${templates.html()!}` + templatesText = `${format(templatesXML)}\r\n` + templates.remove() + } + + const mainText = format(cloned.html()!) + + return templatesText + mainText + } + + /** Строковое представление содержимого элемента */ + get innerXML() { + return this.element.html() ?? '' } /** Существует ли элемент */ diff --git a/src/renderer/components/language/index.vue b/src/renderer/components/language/index.vue index ad387a4..2f9824f 100644 --- a/src/renderer/components/language/index.vue +++ b/src/renderer/components/language/index.vue @@ -1,12 +1,11 @@ diff --git a/src/renderer/pages/main/editor/components/tables/wheels/index.vue b/src/renderer/pages/main/editor/components/tables/wheels/index.vue index e3f2df0..bd91dd3 100644 --- a/src/renderer/pages/main/editor/components/tables/wheels/index.vue +++ b/src/renderer/pages/main/editor/components/tables/wheels/index.vue @@ -1,7 +1,8 @@ diff --git a/src/renderer/pages/main/editor/components/utils.ts b/src/renderer/pages/main/editor/components/utils.ts index 37acb9c..1aa094b 100644 --- a/src/renderer/pages/main/editor/components/utils.ts +++ b/src/renderer/pages/main/editor/components/utils.ts @@ -49,8 +49,8 @@ export function useFilesReady(emit: EmitFn, dynamic = false) { }) return { - ready: (type: string) => ready.add(type), - inProgress: (type: string) => inProgress.add(type) + ready: (type: string) => { ready.add(type) }, + inProgress: (type: string) => { inProgress.add(type) } } } diff --git a/src/renderer/pages/main/editor/index.vue b/src/renderer/pages/main/editor/index.vue index cb44528..ba613b6 100644 --- a/src/renderer/pages/main/editor/index.vue +++ b/src/renderer/pages/main/editor/index.vue @@ -1,60 +1,38 @@