mirror of
https://gitee.com/eolink_admin/postcat.git
synced 2024-11-30 02:37:57 +08:00
fix: extension configure i18n support variable/i18n Readme
This commit is contained in:
parent
b679a5834f
commit
f2e1cebac0
2
.github/workflows/crowdin.yml
vendored
2
.github/workflows/crowdin.yml
vendored
@ -6,7 +6,7 @@ on:
|
||||
|
||||
jobs:
|
||||
synchronize-with-crowdin:
|
||||
if: startsWith(github.event.head_commit.message , 'i18n')
|
||||
if: contains(github.event.head_commit.message , 'i18n')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -1,89 +0,0 @@
|
||||
// import { ipcRenderer, app } from 'electron';
|
||||
// import { isNotEmpty } from 'eo/shared/common/common';
|
||||
// import * as fs from 'fs';
|
||||
// import * as path from 'path';
|
||||
// import {
|
||||
// StorageRes,
|
||||
// StorageResStatus,
|
||||
// StorageHandleArgs,
|
||||
// StorageProcessType,
|
||||
// } from '../../../../workbench/browser/src/app/shared/services/storage/index.model';
|
||||
// import { IndexedDBStorage } from '../../../../workbench/browser/src/app/shared/services/storage/IndexedDB/lib/index';
|
||||
|
||||
// class StorageService {
|
||||
// private ipcRenderer: typeof ipcRenderer;
|
||||
// private app: typeof app;
|
||||
// private fs: typeof fs;
|
||||
// private path: typeof path;
|
||||
// constructor() {
|
||||
// this.ipcRenderer = window.require('electron').ipcRenderer;
|
||||
// this.app = window.require('electron').app;
|
||||
// this.fs = window.require('fs');
|
||||
// this.path = window.require('path');
|
||||
// this.storageListen();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 存储监听处理
|
||||
// * @param args
|
||||
// */
|
||||
// private storageListenHandle(args: StorageHandleArgs): void {
|
||||
// const action: string = args.action || undefined;
|
||||
// const handleResult: StorageRes = {
|
||||
// status: StorageResStatus.invalid,
|
||||
// data: undefined,
|
||||
// callback: args.callback || null,
|
||||
// };
|
||||
// if (IndexedDBStorage && IndexedDBStorage[action] && typeof IndexedDBStorage[action] === 'function') {
|
||||
// IndexedDBStorage[action](...args.params).subscribe(
|
||||
// (result: any) => {
|
||||
// handleResult.data = result;
|
||||
// if (isNotEmpty(result)) {
|
||||
// handleResult.status = StorageResStatus.success;
|
||||
// } else {
|
||||
// handleResult.status = StorageResStatus.empty;
|
||||
// }
|
||||
// this.storageListenHandleNotify(args.type, handleResult);
|
||||
// },
|
||||
// (error: any) => {
|
||||
// handleResult.status = StorageResStatus.error;
|
||||
// this.storageListenHandleNotify(args.type, handleResult);
|
||||
// }
|
||||
// );
|
||||
// } else {
|
||||
// this.storageListenHandleNotify(args.type, handleResult);
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 数据存储监听通知返回
|
||||
// * @param type
|
||||
// * @param result
|
||||
// */
|
||||
// private storageListenHandleNotify(type: string, result: StorageRes): void {
|
||||
// try {
|
||||
// if (StorageProcessType.default === type) {
|
||||
// this.ipcRenderer.send('eo-storage', { type: 'result', result: result });
|
||||
// } else if (StorageProcessType.sync === type) {
|
||||
// const storageTemp = this.path.join(this.app.getPath('home'), '.eo', 'tmp.storage');
|
||||
// this.fs.writeFileSync(storageTemp, JSON.stringify(result));
|
||||
// } else if (StorageProcessType.remote === type) {
|
||||
// window.require('@electron/remote').getGlobal('shareObject').storageResult = result;
|
||||
// }
|
||||
// } catch (e) {
|
||||
// console.log(e);
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 开启数据存储监听
|
||||
// * @returns
|
||||
// */
|
||||
// private storageListen(): void {
|
||||
// this.ipcRenderer.on('eo-storage', (event, args: StorageHandleArgs) => this.storageListenHandle(args));
|
||||
// }
|
||||
|
||||
// isElectron(): boolean {
|
||||
// return !!(window && window.process && window.process.type);
|
||||
// }
|
||||
// }
|
@ -23,18 +23,39 @@ export class TranslateService {
|
||||
* Transalte package.json variable ${} to locale text
|
||||
*/
|
||||
translateVariableKey() {
|
||||
let that = this;
|
||||
Object.keys(this.module.features).forEach((name) => {
|
||||
let feature = that.module.features[name];
|
||||
Object.keys(feature).forEach((childName) => {
|
||||
if (typeof feature[childName] !== 'string') return;
|
||||
that.module.features[name][childName] = feature[childName].replace(/\$\{(.+)\}/g, (match, rest) => {
|
||||
let replacement = match;
|
||||
replacement = that.locale[rest] || replacement;
|
||||
return replacement;
|
||||
});
|
||||
});
|
||||
this.translateObject(this.locale, this.module.features, {
|
||||
currentLevel: 0,
|
||||
maxLevel: 4,
|
||||
});
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Loop translate object
|
||||
* @param locale
|
||||
* @param origin
|
||||
* @param opts.maxLevel loop object level
|
||||
*/
|
||||
private translateObject(locale, origin, opts) {
|
||||
if (opts.currentLevel >= opts.maxLevel) return;
|
||||
Object.keys(origin).forEach((name) => {
|
||||
if (typeof origin[name] !== 'string') {
|
||||
let newOpts = { maxLevel: opts.maxLevel, currentLevel: opts.currentLevel + 1 };
|
||||
this.translateObject(locale, origin[name], newOpts);
|
||||
return;
|
||||
}
|
||||
origin[name] = this.translateString(locale, origin[name]);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Translate primitive data types(string/numebr/..)
|
||||
* @param locale
|
||||
* @param variable
|
||||
*/
|
||||
private translateString(locale, variable) {
|
||||
return variable.replace(/\$\{(.+)\}/g, (match, rest) => {
|
||||
let replacement = match;
|
||||
replacement = locale[rest] || replacement;
|
||||
return replacement;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -9,39 +9,48 @@
|
||||
</div>
|
||||
<section class="h-full p-4 max-w-[80vw] mx-auto">
|
||||
<div class="flex">
|
||||
<i class="block w-24 h-24 mr-8 bg-center bg-no-repeat bg-cover border rounded-lg bd_all"
|
||||
[ngStyle]="{ 'background-image': 'url(' + (extensionDetail?.logo || '') + ')' }"></i>
|
||||
<i
|
||||
class="block w-24 h-24 mr-8 bg-center bg-no-repeat bg-cover border rounded-lg bd_all"
|
||||
[ngStyle]="{ 'background-image': 'url(' + (extensionDetail?.logo || '') + ')' }"
|
||||
></i>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex flex-col">
|
||||
<span class="mb-2 text-xl font-bold">{{ extensionDetail?.moduleName }}</span>
|
||||
<p class="w-full h-20">{{ extensionDetail?.description }}</p>
|
||||
</div>
|
||||
<div class="flex">
|
||||
|
||||
</div>
|
||||
<div class="flex"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-full mt-6 h-[calc(100vh-350px)]">
|
||||
<div class="flex-auto">
|
||||
<div class="flex-auto min-w-0">
|
||||
<h2 class="text-lg font-bold" i18n>Intro</h2>
|
||||
<!-- <nz-divider></nz-divider> -->
|
||||
<div class="h-full overflow-auto markdown-desc">
|
||||
<nz-skeleton [nzLoading]="introLoading" [nzActive]="true">
|
||||
<eo-shadow-dom [text]="extensionDetail?.introduction" [options]="{ html: true }">
|
||||
<eo-shadow-dom class="md-preview" [text]="extensionDetail?.introduction" [options]="{ html: true }">
|
||||
</eo-shadow-dom>
|
||||
</nz-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-[1px] bg-[#f2f2f2] mx-[10px]"></div>
|
||||
<div class="w-[200px] 2xl:w-[250px] overflow-auto h-full">
|
||||
<div class="shrink-0 w-[200px] 2xl:w-[250px] overflow-auto h-full">
|
||||
<h2 class="text-lg font-bold" i18n>Install</h2>
|
||||
<div class="flex items-center mt-[22px]" *ngIf="!extensionDetail?.installed">
|
||||
<button *ngIf="isElectron" nz-button nzType="primary" nzBlock nzSize="large" [nzLoading]="isOperating"
|
||||
(click)="manageExtension('install', extensionDetail?.name)">
|
||||
<button
|
||||
*ngIf="isElectron"
|
||||
nz-button
|
||||
nzType="primary"
|
||||
nzBlock
|
||||
nzSize="large"
|
||||
[nzLoading]="isOperating"
|
||||
(click)="manageExtension('install', extensionDetail?.name)"
|
||||
i18n
|
||||
>
|
||||
Install
|
||||
</button>
|
||||
<div *ngIf="!isElectron">
|
||||
<button nz-button nzType="primary" nz-dropdown [nzDropdownMenu]="download" class="!w-full" i18n>Download Client
|
||||
<button nz-button nzType="primary" nz-dropdown [nzDropdownMenu]="download" class="!w-full" i18n>
|
||||
Download Client
|
||||
</button>
|
||||
<nz-dropdown-menu #download="nzDropdownMenu">
|
||||
<ul nz-menu>
|
||||
@ -56,16 +65,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button *ngIf="extensionDetail?.installed" nz-button nzBlock nzType="primary" nzDanger nzSize="large"
|
||||
[nzLoading]="isOperating" class="mt-[12px]" (click)="manageExtension('uninstall', extensionDetail?.name)" i18n>
|
||||
<button
|
||||
*ngIf="extensionDetail?.installed"
|
||||
nz-button
|
||||
nzBlock
|
||||
nzType="primary"
|
||||
nzDanger
|
||||
nzSize="large"
|
||||
[nzLoading]="isOperating"
|
||||
class="mt-[12px]"
|
||||
(click)="manageExtension('uninstall', extensionDetail?.name)"
|
||||
i18n
|
||||
>
|
||||
Uninstall
|
||||
</button>
|
||||
|
||||
<h2 class="text-lg font-bold mt-[30px]" i18n>Support</h2>
|
||||
<nz-descriptions [nzColumn]="1" nzTitle="">
|
||||
<nz-descriptions-item i18n-nzTitle nzTitle="Author">{{ extensionDetail?.author}}</nz-descriptions-item>
|
||||
<nz-descriptions-item i18n-nzTitle nzTitle="Version">{{ extensionDetail?.version }}
|
||||
</nz-descriptions-item>
|
||||
<nz-descriptions-item i18n-nzTitle nzTitle="Author">{{ extensionDetail?.author }}</nz-descriptions-item>
|
||||
<nz-descriptions-item i18n-nzTitle nzTitle="Version">{{ extensionDetail?.version }} </nz-descriptions-item>
|
||||
</nz-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,23 +4,28 @@
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
::ng-deep .extension-detail {
|
||||
|
||||
.markdown-desc {
|
||||
overflow: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width:0;
|
||||
}
|
||||
&:hover::-webkit-scrollbar {
|
||||
width:8px;
|
||||
.md-preview {
|
||||
img {
|
||||
max-width: 800px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-descriptions-row > td {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.ant-descriptions-item-content,.ant-descriptions-item-label {
|
||||
color: #999;
|
||||
.extension-detail {
|
||||
.markdown-desc {
|
||||
overflow: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
&:hover::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-descriptions-row > td {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.ant-descriptions-item-content,
|
||||
.ant-descriptions-item-label {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import { ElectronService } from 'eo/workbench/browser/src/app/core/services';
|
||||
import { EoExtensionInfo } from '../extension.model';
|
||||
import { ResourceInfo } from '../../../shared/models/client.model';
|
||||
import { ExtensionService } from '../extension.service';
|
||||
import { LanguageService } from 'eo/workbench/browser/src/app/core/services/language/language.service';
|
||||
|
||||
@Component({
|
||||
selector: 'eo-extension-detail',
|
||||
@ -22,7 +23,8 @@ export class ExtensionDetailComponent implements OnInit {
|
||||
private extensionService: ExtensionService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private electronService: ElectronService
|
||||
private electronService: ElectronService,
|
||||
private language: LanguageService
|
||||
) {
|
||||
this.getDetail();
|
||||
this.getInstaller();
|
||||
@ -33,17 +35,26 @@ export class ExtensionDetailComponent implements OnInit {
|
||||
this.route.snapshot.queryParams.name
|
||||
);
|
||||
if (!this.extensionDetail?.installed) {
|
||||
await this.fetchReadme();
|
||||
await this.fetchReadme(this.language.systemLanguage);
|
||||
}
|
||||
this.extensionDetail.introduction ||= $localize`This plugin has no documentation yet.`;
|
||||
}
|
||||
|
||||
async fetchReadme() {
|
||||
async fetchReadme(locale = '') {
|
||||
//Default locale en-US
|
||||
if (locale === 'en-US') locale = '';
|
||||
try {
|
||||
this.introLoading = true;
|
||||
const response = await fetch(`https://unpkg.com/${this.extensionDetail.name}/README.md`);
|
||||
const response = await fetch(
|
||||
`https://unpkg.com/${this.extensionDetail.name}@${this.extensionDetail.version}/README.${
|
||||
locale ? locale + '.' : ''
|
||||
}md`
|
||||
);
|
||||
if (response.status === 200) {
|
||||
this.extensionDetail.introduction = await response.text();
|
||||
} else if (locale) {
|
||||
//If locale README not find,fetch default locale(en-US)
|
||||
this.fetchReadme();
|
||||
}
|
||||
} catch (error) {
|
||||
} finally {
|
||||
@ -92,7 +103,6 @@ export class ExtensionDetailComponent implements OnInit {
|
||||
|
||||
manageExtension(operate: string, id) {
|
||||
this.isOperating = true;
|
||||
console.log(this.isOperating);
|
||||
/**
|
||||
* * WARNING:Sending a synchronous message will block the whole
|
||||
* renderer process until the reply is received, so use this method only as a last
|
||||
@ -107,7 +117,7 @@ export class ExtensionDetailComponent implements OnInit {
|
||||
}
|
||||
case 'uninstall': {
|
||||
this.extensionDetail.installed = !this.extensionService.uninstall(id);
|
||||
this.fetchReadme();
|
||||
this.fetchReadme(this.language.systemLanguage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -30,28 +30,29 @@ export class ExtensionService {
|
||||
private translateModule(module: ModuleInfo) {
|
||||
const lang = this.language.systemLanguage;
|
||||
const locale = module.i18n?.find((val) => val.locale === lang)?.package;
|
||||
console.log(locale, module);
|
||||
if (!locale) return module;
|
||||
module = new TranslateService(module, locale).translate();
|
||||
return module;
|
||||
}
|
||||
public async requestList() {
|
||||
let result: any = await lastValueFrom(this.http.get(`${this.HOST}/list?locale=${this.language.systemLanguage}`));
|
||||
let installList = this.getInstalledList();
|
||||
result.data = [
|
||||
...result.data,
|
||||
...result.data.filter((val) => installList.every((childVal) => childVal.name !== val.name)),
|
||||
//Local debug package
|
||||
...this.getInstalledList().filter((val) => result.data.every((childVal) => childVal.name !== val.name)),
|
||||
...installList,
|
||||
];
|
||||
console.log(result.data)
|
||||
result.data = result.data.map((module) => this.translateModule(module));
|
||||
return result;
|
||||
}
|
||||
async getDetail(id, name): Promise<any> {
|
||||
let result = {};
|
||||
let { code, data }: any = await this.requestDetail(name);
|
||||
Object.assign(result, data);
|
||||
if (this.localExtensions.has(id)) {
|
||||
Object.assign(result, this.localExtensions.get(id), { installed: true });
|
||||
}
|
||||
let { code, data }: any = await this.requestDetail(name);
|
||||
Object.assign(result, data);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@
|
||||
class="bd_all w-full min-h-[140px] p-5 rounded-lg flex flex-col flex-wrap items-center plugin-block hover:border-green-700 hover:shadow-lg transition-shadow duration-300"
|
||||
*ngFor="let it of renderList" (click)="clickExtension(it)">
|
||||
<div class="flex w-full">
|
||||
<div class=" block w-[40px] h-[40px] rounded-lg bg-cover bg-center bg-no-repeat mr-[20px]"
|
||||
<div class="shrink-0 block w-[40px] h-[40px] rounded-lg bg-cover bg-center bg-no-repeat mr-[20px]"
|
||||
[ngClass]="{ 'bg-gray-100': it.logo }" [ngStyle]="{ 'background-image': 'url(' + (it.logo || '') + ')' }">
|
||||
</div>
|
||||
|
||||
|
@ -80,7 +80,7 @@
|
||||
>
|
||||
<eo-shadow-dom [text]="module.properties[field]?.description || ''"></eo-shadow-dom>
|
||||
</div>
|
||||
<nz-form-control nzErrorTip="请输入{{ module.properties[field]?.label }}" class="form-control">
|
||||
<nz-form-control i18n-nzErrorTip nzErrorTip="请输入{{ module.properties[field]?.label }}" class="form-control">
|
||||
<!-- 字符串类型 -->
|
||||
<ng-container *ngIf="module.properties[field]?.type === 'string'">
|
||||
<input
|
||||
@ -88,6 +88,7 @@
|
||||
nz-input
|
||||
id="{{ field }}"
|
||||
[disabled]="module.properties[field]?.disabled"
|
||||
i18n-placeholder
|
||||
placeholder="{{ module.properties[field]?.placeholder ?? '请输入' + module.properties[field]?.label }}"
|
||||
formControlName="{{ field }}"
|
||||
[(ngModel)]="settings[field]"
|
||||
|
@ -4,7 +4,13 @@ import MarkdownIt from 'markdown-it/dist/markdown-it';
|
||||
@Component({
|
||||
selector: 'eo-shadow-dom',
|
||||
template: ` <div [innerHTML]="content"></div> `,
|
||||
styles: [],
|
||||
styles: [
|
||||
`
|
||||
img {
|
||||
max-width: 600px;
|
||||
}
|
||||
`,
|
||||
],
|
||||
encapsulation: ViewEncapsulation.ShadowDom,
|
||||
})
|
||||
export class ShadowDomEncapsulationComponent implements OnInit {
|
||||
|
@ -14,7 +14,7 @@
|
||||
<source>No mock found with ID <x id="PH" equiv-text="mockID"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/app.service.ts</context>
|
||||
<context context-type="linenumber">45</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4580786032076405950" datatype="html">
|
||||
@ -1284,53 +1284,60 @@
|
||||
<context context-type="linenumber">37</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0cd99ecbc1878fe507d251f7097c296827591866" datatype="html">
|
||||
<source>Download Client </source>
|
||||
<trans-unit id="c10feff406d4b2759fa2b37a33ebf9cf9f31276f" datatype="html">
|
||||
<source> Install </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">44,45</context>
|
||||
<context context-type="linenumber">48,50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ff30254c1bb7fdda70783d33f81d0312159c4742" datatype="html">
|
||||
<source> Download Client </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">52,54</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="634e9df42c9b62368a31d091e53ea60582bff569" datatype="html">
|
||||
<source> The extensions can only be installed on the client at present. Please download the client first~ </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">54,56</context>
|
||||
<context context-type="linenumber">63,65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e67b8fac834cf48010053ad82372fed4c4e2ba9" datatype="html">
|
||||
<source> Uninstall </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">60,62</context>
|
||||
<context context-type="linenumber">79,81</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604" datatype="html">
|
||||
<source>Support</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">83</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d7293b61e9088c66421df2e367e0ccc00346cf9f" datatype="html">
|
||||
<source>Author</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">66</context>
|
||||
<context context-type="linenumber">85</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8fe73a4787b8068b2ba61f54ab7e0f9af2ea1fc9" datatype="html">
|
||||
<source>Version</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">86</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6031434056991752553" datatype="html">
|
||||
<source>This plugin has no documentation yet.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.ts</context>
|
||||
<context context-type="linenumber">38</context>
|
||||
<context context-type="linenumber">40</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8852490424970169127" datatype="html">
|
||||
@ -2784,18 +2791,32 @@
|
||||
<context context-type="linenumber">103</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b20217b59531361f9ebc6df4c148399f76461f96" datatype="html">
|
||||
<source>请输入<x id="INTERPOLATION" equiv-text="{{ module.properties[field]?.label }}"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/setting.component.html</context>
|
||||
<context context-type="linenumber">83</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="872abb7923d5fcf1c5b3b60f3c469ea277a17f48" datatype="html">
|
||||
<source><x id="INTERPOLATION" equiv-text="{{ module.properties[field]?.placeholder ?? '请输入' + module.properties[field]?.label }}"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/setting.component.html</context>
|
||||
<context context-type="linenumber">92</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0153ca63af84192825f056daf8503077a518d413" datatype="html">
|
||||
<source> Switched to <x id="INTERPOLATION" equiv-text="{{ isRemote ? 'Localhost' : 'Remote Server' }}"/> </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/setting.component.html</context>
|
||||
<context context-type="linenumber">136,138</context>
|
||||
<context context-type="linenumber">137,139</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0d1ece694da029a20f5a97fbf3302f6213da891" datatype="html">
|
||||
<source>No plugins are currently installed,<x id="START_LINK" ctype="x-a" equiv-text="<a class="eo_link" (click)="navToExtensionList()">"/> go to install <x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/setting.component.html</context>
|
||||
<context context-type="linenumber">152</context>
|
||||
<context context-type="linenumber">153</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3139147897029202869" datatype="html">
|
||||
|
23
vercel.json
23
vercel.json
@ -1,13 +1,12 @@
|
||||
{
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "/:path((?!en/).*)",
|
||||
"destination": "/en/:path*"
|
||||
},
|
||||
{
|
||||
"source": "/:path((?!zh/).*)",
|
||||
"destination": "/zh/:path*"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "/:path((?!zh/).*)",
|
||||
"destination": "/zh/:path*"
|
||||
},
|
||||
{
|
||||
"source": "/:path((?!en/).*)",
|
||||
"destination": "/en/:path*"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user