mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-02-08 00:04:21 +01:00
♻️ Bazaar uses a map to replace the i18n struct (#16960)
- package.go:DisplayName/Description/Readme 改为 map[string]string,统一 getPreferredLocaleString - bazzar.go:搜索匹配适配 LocaleStrings,抽出 packageContainsKeyword - bazaar.ts:keyword 仅在有值时传入 API - appearance:主题「默认主题」与 displayName 改为多语言 key 与 map 取值
This commit is contained in:
parent
cc37ec4030
commit
9642f486bd
19 changed files with 127 additions and 388 deletions
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "اكتمل تنظيف الملفات المؤقتة، تم حذف [%d] ملفًا، تم تحرير [%s] من مساحة القرص",
|
||||
"278": "مساحة العمل غير موجودة على قرص الحالة الصلبة (SSD)، قد يؤدي ذلك إلى تدهور كبير في الأداء، يُنصح بوضع مساحة العمل على قرص SSD",
|
||||
"279": "يوجد إجمالاً [%d] قواعد بيانات غير مرجعية، هنا يتم سرد [%d] فقط",
|
||||
"280": "اكتمل تنظيف قواعد البيانات غير المرجعية، تم حذف [%d] ملفًا، وتم تحرير [%s] من مساحة القرص"
|
||||
"280": "اكتمل تنظيف قواعد البيانات غير المرجعية، تم حذف [%d] ملفًا، وتم تحرير [%s] من مساحة القرص",
|
||||
"281": " (الافتراضي)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Bereinigung der temporären Dateien abgeschlossen, [%d] Dateien entfernt, [%s] Festplattenspeicher freigegeben",
|
||||
"278": "Der Arbeitsbereich befindet sich nicht auf einer SSD, was zu erheblichen Leistungseinbußen führen kann, es wird empfohlen, den Arbeitsbereich auf einer SSD zu platzieren",
|
||||
"279": "Insgesamt [%d] nicht referenzierte Datenbanken, hier werden nur [%d] aufgelistet",
|
||||
"280": "Bereinigung nicht referenzierter Datenbanken abgeschlossen, [%d] Dateien gelöscht, [%s] Festplattenspeicher freigegeben"
|
||||
"280": "Bereinigung nicht referenzierter Datenbanken abgeschlossen, [%d] Dateien gelöscht, [%s] Festplattenspeicher freigegeben",
|
||||
"281": " (Standard)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Temporary files cleaned, [%d] files removed, [%s] disk space freed",
|
||||
"278": "The workspace is not located on a solid-state drive (SSD), which can cause significant performance degradation, it is recommended to place the workspace on an SSD",
|
||||
"279": "There are [%d] unreferenced databases in total, only [%d] are listed here",
|
||||
"280": "Cleanup of unreferenced databases completed, [%d] files removed, [%s] of disk space freed"
|
||||
"280": "Cleanup of unreferenced databases completed, [%d] files removed, [%s] of disk space freed",
|
||||
"281": " (Default)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Limpieza de archivos temporales completada, [%d] archivos eliminados, se liberaron [%s] de espacio en disco",
|
||||
"278": "El espacio de trabajo no está ubicado en un disco de estado sólido (SSD), esto puede provocar una disminución notable del rendimiento, se recomienda colocar el espacio de trabajo en un SSD",
|
||||
"279": "Hay [%d] bases de datos sin referencias en total, aquí se muestran solo [%d]",
|
||||
"280": "Limpieza de bases de datos sin referencias completada, [%d] archivos eliminados, se liberaron [%s] de espacio en disco"
|
||||
"280": "Limpieza de bases de datos sin referencias completada, [%d] archivos eliminados, se liberaron [%s] de espacio en disco",
|
||||
"281": " (Por defecto)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Nettoyage des fichiers temporaires terminé, [%d] fichiers supprimés, [%s] d'espace disque libéré",
|
||||
"278": "L'espace de travail n'est pas placé sur un disque SSD, ce qui peut entraîner une baisse significative des performances, il est recommandé de placer l'espace de travail sur un SSD",
|
||||
"279": "Au total [%d] bases de données non référencées, ici n'en sont listées que [%d]",
|
||||
"280": "Nettoyage des bases de données non référencées terminé, [%d] fichiers supprimés, [%s] d'espace disque libéré"
|
||||
"280": "Nettoyage des bases de données non référencées terminé, [%d] fichiers supprimés, [%s] d'espace disque libéré",
|
||||
"281": " (Default)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "ניקוי הקבצים הזמניים הושלם, נמחקו [%d] קבצים, שוחררו [%s] מקום בדיסק",
|
||||
"278": "מרחב העבודה לא מאוחסן בכונן מצב מוצק (SSD), הדבר עלול להוביל לירידה משמעותית בביצועים, מומלץ לאחסן את מרחב העבודה על גבי SSD",
|
||||
"279": "בסך הכל קיימים [%d] מאגרי מידע שלא מקושרים, כאן מופיעים רק [%d]",
|
||||
"280": "ניקוי מאגרי המידע שלא מקושרים הושלם, נמחקו [%d] קבצים, שוחררו [%s] נפח דיסק"
|
||||
"280": "ניקוי מאגרי המידע שלא מקושרים הושלם, נמחקו [%d] קבצים, שוחררו [%s] נפח דיסק",
|
||||
"281": " (ברירת מחדל)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Pulizia dei file temporanei completata, [%d] file rimossi, liberati [%s] di spazio su disco",
|
||||
"278": "Lo spazio di lavoro non è su un disco a stato solido (SSD), ciò può causare una diminuzione significativa delle prestazioni, si consiglia di posizionare lo spazio di lavoro su un SSD",
|
||||
"279": "Database non referenziati in totale: [%d], qui ne vengono elencati solo [%d]",
|
||||
"280": "Pulizia dei database non referenziati completata, eliminati [%d] file, liberato [%s] di spazio su disco"
|
||||
"280": "Pulizia dei database non referenziati completata, eliminati [%d] file, liberato [%s] di spazio su disco",
|
||||
"281": " (Predefinito)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "一時ファイルのクリーンアップが完了しました。[%d]件のファイルを削除し、合計で [%s] のディスク容量を解放しました",
|
||||
"278": "ワークスペースがSSD上に配置されていません、これにより著しいパフォーマンス低下が発生する可能性があるため、ワークスペースをSSD上で使用することを推奨します",
|
||||
"279": "参照されていないデータベースは合計 [%d] 件で、ここには [%d] 件のみ表示しています",
|
||||
"280": "参照されていないデータベースのクリーンアップが完了しました。[%d] 個のファイルを削除し、合計 [%s] のディスク領域を解放しました"
|
||||
"280": "参照されていないデータベースのクリーンアップが完了しました。[%d] 個のファイルを削除し、合計 [%s] のディスク領域を解放しました",
|
||||
"281": " (デフォルト)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "임시 파일 정리 완료, [%d]개 파일이 삭제되어 총 [%s]의 디스크 공간이 확보되었습니다",
|
||||
"278": "작업 공간이 SSD에 있지 않습니다, 이로 인해 성능이 크게 저하될 수 있으므로 작업 공간을 SSD에 두어 사용하시기 바랍니다",
|
||||
"279": "참조되지 않은 데이터베이스 전체 [%d]개, 여기에는 [%d]개만 나열됩니다",
|
||||
"280": "참조되지 않은 데이터베이스 정리 완료, [%d]개의 파일을 삭제하여 총 [%s]의 디스크 공간을 확보했습니다"
|
||||
"280": "참조되지 않은 데이터베이스 정리 완료, [%d]개의 파일을 삭제하여 총 [%s]의 디스크 공간을 확보했습니다",
|
||||
"281": " (기본)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Czyszczenie plików tymczasowych zakończone, usunięto [%d] plików, zwolniono [%s] miejsca na dysku",
|
||||
"278": "Obszar roboczy nie znajduje się na dysku SSD, co może spowodować znaczny spadek wydajności, zaleca się umieszczenie obszaru roboczego na dysku SSD",
|
||||
"279": "Nieodwołane bazy danych łącznie: [%d], tutaj wyświetlono tylko [%d]",
|
||||
"280": "Czyszczenie nieodwołanych baz danych zakończone, usunięto [%d] plików, zwolniono [%s] miejsca na dysku"
|
||||
"280": "Czyszczenie nieodwołanych baz danych zakończone, usunięto [%d] plików, zwolniono [%s] miejsca na dysku",
|
||||
"281": " (Domyślny)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Limpeza de arquivos temporários concluída, [%d] arquivos removidos, [%s] de espaço em disco liberado",
|
||||
"278": "O espaço de trabalho não está em um disco de estado sólido (SSD), o que pode causar uma queda significativa de desempenho, recomenda-se colocar o espaço de trabalho em um SSD",
|
||||
"279": "Há [%d] bancos de dados não referenciados no total, aqui são listados apenas [%d]",
|
||||
"280": "Limpeza de bancos de dados não referenciados concluída, [%d] arquivos removidos, [%s] de espaço em disco liberados"
|
||||
"280": "Limpeza de bancos de dados não referenciados concluída, [%d] arquivos removidos, [%s] de espaço em disco liberados",
|
||||
"281": " (Padrão)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Очистка временных файлов завершена, удалено [%d] файлов, освобождено [%s] дискового пространства",
|
||||
"278": "Рабочее пространство не размещено на твердотельном накопителе (SSD), это может привести к заметному снижению производительности, рекомендуется разместить рабочее пространство на SSD",
|
||||
"279": "Всего неиспользуемых баз данных: [%d], здесь показано только [%d]",
|
||||
"280": "Очистка неиспользуемых баз данных завершена, удалено [%d] файлов, освобождено [%s] дискового пространства"
|
||||
"280": "Очистка неиспользуемых баз данных завершена, удалено [%d] файлов, освобождено [%s] дискового пространства",
|
||||
"281": " (По умолчанию)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "Geçici dosyalar temizlendi, [%d] dosya silindi, toplam [%s] boş alan açıldı",
|
||||
"278": "Çalışma alanı katı hal sürücüsünde (SSD) değil, bu belirgin bir performans düşüşüne yol açabilir, çalışma alanınızı SSD'de tutmanız önerilir",
|
||||
"279": "Kullanılmayan veritabanı toplam [%d] adet, burada yalnızca [%d] tanesi listeleniyor",
|
||||
"280": "Kullanılmayan veritabanları temizlendi, [%d] dosya kaldırıldı, toplam [%s] disk alanı boşaltıldı"
|
||||
"280": "Kullanılmayan veritabanları temizlendi, [%d] dosya kaldırıldı, toplam [%s] disk alanı boşaltıldı",
|
||||
"281": " (Varsayılan)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "清理臨時檔案完畢,已刪除 [%d] 個檔案,共釋放 [%s] 磁碟空間",
|
||||
"278": "工作空間未放置在固態硬碟上,這會導致顯著的效能下降,建議將工作空間放置在固態硬碟上使用",
|
||||
"279": "未引用資料庫一共 [%d] 個,這裡僅列出 [%d] 個",
|
||||
"280": "清理未引用的資料庫完畢,已刪除 [%d] 個檔案,共釋放 [%s] 磁碟空間"
|
||||
"280": "清理未引用的資料庫完畢,已刪除 [%d] 個檔案,共釋放 [%s] 磁碟空間",
|
||||
"281": "(預設主題)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,7 @@
|
|||
"277": "清理临时文件完毕,已删除 [%d] 个文件,共释放 [%s] 磁盘空间",
|
||||
"278": "工作空间未放置在固态硬盘上,这会导致显著的性能下降,建议将工作空间放置在固态硬盘上使用",
|
||||
"279": "未引用数据库一共 [%d] 个,这里仅列出 [%d] 个",
|
||||
"280": "清理未引用的数据库完毕,已删除 [%d] 个文件,共释放 [%s] 磁盘空间"
|
||||
"280": "清理未引用的数据库完毕,已删除 [%d] 个文件,共释放 [%s] 磁盘空间",
|
||||
"281": "(默认主题)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,9 +385,10 @@ export const bazaar = {
|
|||
} else if (bazaarType === "plugins") {
|
||||
url = "/api/bazaar/getInstalledPlugin";
|
||||
}
|
||||
const keyword = (contentElement.previousElementSibling.querySelector(".b3-text-field") as HTMLInputElement)?.value?.trim() || "";
|
||||
fetchPost(url, {
|
||||
frontend: getFrontend(),
|
||||
keyword: (contentElement.previousElementSibling.querySelector(".b3-text-field") as HTMLInputElement)?.value || "",
|
||||
...(keyword ? { keyword } : {}),
|
||||
}, response => {
|
||||
contentElement.removeAttribute("data-loading");
|
||||
let html = "";
|
||||
|
|
@ -690,8 +691,9 @@ type="checkbox">
|
|||
} else if (bazaarType === "plugins") {
|
||||
url = "/api/bazaar/installBazaarPlugin";
|
||||
}
|
||||
const keyword = (bazaar.element.querySelector(".config-bazaar__panel:not(.fn__none) .b3-form__icon-input") as HTMLInputElement).value.trim();
|
||||
fetchPost(url, {
|
||||
keyword: (bazaar.element.querySelector(".config-bazaar__panel:not(.fn__none) .b3-form__icon-input") as HTMLInputElement).value,
|
||||
...(keyword ? { keyword } : {}),
|
||||
repoURL: dataObj.repoURL,
|
||||
packageName: dataObj.name,
|
||||
repoHash: dataObj.repoHash,
|
||||
|
|
@ -750,8 +752,9 @@ type="checkbox">
|
|||
if (!target.classList.contains("b3-button")) {
|
||||
target.parentElement.insertAdjacentHTML("afterend", '<img data-type="img-loading" style="position: absolute;top: 0;left: 0;height: 100%;width: 100%;padding: 16px;box-sizing: border-box;" src="/stage/loading-pure.svg">');
|
||||
}
|
||||
const keyword = (bazaar.element.querySelector(".config-bazaar__panel:not(.fn__none) .b3-form__icon-input") as HTMLInputElement).value.trim();
|
||||
fetchPost(url, {
|
||||
keyword: (bazaar.element.querySelector(".config-bazaar__panel:not(.fn__none) .b3-form__icon-input") as HTMLInputElement).value,
|
||||
...(keyword ? { keyword } : {}),
|
||||
repoURL: dataObj.repoURL,
|
||||
packageName: dataObj.name,
|
||||
repoHash: dataObj.repoHash,
|
||||
|
|
@ -803,9 +806,10 @@ type="checkbox">
|
|||
showMessage(window.siyuan.languages.uninstallTip);
|
||||
} else {
|
||||
confirmDialog("⚠️ " + window.siyuan.languages.uninstall, window.siyuan.languages.confirmUninstall.replace("${name}", packageName), () => {
|
||||
const keyword = (bazaar.element.querySelector(".config-bazaar__panel:not(.fn__none) .b3-form__icon-input") as HTMLInputElement).value.trim();
|
||||
fetchPost(url, {
|
||||
packageName,
|
||||
keyword: (bazaar.element.querySelector(".config-bazaar__panel:not(.fn__none) .b3-form__icon-input") as HTMLInputElement).value,
|
||||
...(keyword ? { keyword } : {}),
|
||||
frontend: getFrontend()
|
||||
}, response => {
|
||||
this._genMyHTML(bazaarType, app);
|
||||
|
|
@ -997,29 +1001,29 @@ type="checkbox">
|
|||
const keyword = inputElement.value.trim();
|
||||
const type = (hasClosestByClassName(inputElement, "config-bazaar__panel") as HTMLElement).getAttribute("data-type");
|
||||
if (type === "template") {
|
||||
fetchPost("/api/bazaar/getBazaarTemplate", {keyword}, response => {
|
||||
fetchPost("/api/bazaar/getBazaarTemplate", keyword ? { keyword } : {}, response => {
|
||||
bazaar._onBazaar(response, "templates");
|
||||
bazaar._data.templates = response.data.packages;
|
||||
});
|
||||
} else if (type === "icon") {
|
||||
fetchPost("/api/bazaar/getBazaarIcon", {keyword}, response => {
|
||||
fetchPost("/api/bazaar/getBazaarIcon", keyword ? { keyword } : {}, response => {
|
||||
bazaar._onBazaar(response, "icons");
|
||||
bazaar._data.icons = response.data.packages;
|
||||
});
|
||||
} else if (type === "widget") {
|
||||
fetchPost("/api/bazaar/getBazaarWidget", {keyword}, response => {
|
||||
fetchPost("/api/bazaar/getBazaarWidget", keyword ? { keyword } : {}, response => {
|
||||
bazaar._onBazaar(response, "widgets");
|
||||
bazaar._data.widgets = response.data.packages;
|
||||
});
|
||||
} else if (type === "theme") {
|
||||
fetchPost("/api/bazaar/getBazaarTheme", {keyword}, response => {
|
||||
fetchPost("/api/bazaar/getBazaarTheme", keyword ? { keyword } : {}, response => {
|
||||
bazaar._onBazaar(response, "themes");
|
||||
bazaar._data.themes = response.data.packages;
|
||||
});
|
||||
} else if (type === "plugin") {
|
||||
fetchPost("/api/bazaar/getBazaarPlugin", {
|
||||
frontend: getFrontend(),
|
||||
keyword
|
||||
...(keyword ? { keyword } : {}),
|
||||
}, response => {
|
||||
bazaar._onBazaar(response, "plugins");
|
||||
bazaar._data.plugins = response.data.packages;
|
||||
|
|
|
|||
|
|
@ -40,62 +40,8 @@ import (
|
|||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
type DisplayName struct {
|
||||
Default string `json:"default"`
|
||||
ArSA string `json:"ar_SA"`
|
||||
DeDE string `json:"de_DE"`
|
||||
EnUS string `json:"en_US"`
|
||||
EsES string `json:"es_ES"`
|
||||
FrFR string `json:"fr_FR"`
|
||||
HeIL string `json:"he_IL"`
|
||||
ItIT string `json:"it_IT"`
|
||||
JaJP string `json:"ja_JP"`
|
||||
KoKR string `json:"ko_KR"`
|
||||
PlPL string `json:"pl_PL"`
|
||||
PtBR string `json:"pt_BR"`
|
||||
RuRU string `json:"ru_RU"`
|
||||
TrTR string `json:"tr_TR"`
|
||||
ZhCHT string `json:"zh_CHT"`
|
||||
ZhCN string `json:"zh_CN"`
|
||||
}
|
||||
|
||||
type Description struct {
|
||||
Default string `json:"default"`
|
||||
ArSA string `json:"ar_SA"`
|
||||
DeDE string `json:"de_DE"`
|
||||
EnUS string `json:"en_US"`
|
||||
EsES string `json:"es_ES"`
|
||||
FrFR string `json:"fr_FR"`
|
||||
HeIL string `json:"he_IL"`
|
||||
ItIT string `json:"it_IT"`
|
||||
JaJP string `json:"ja_JP"`
|
||||
KoKR string `json:"ko_KR"`
|
||||
PlPL string `json:"pl_PL"`
|
||||
PtBR string `json:"pt_BR"`
|
||||
RuRU string `json:"ru_RU"`
|
||||
TrTR string `json:"tr_TR"`
|
||||
ZhCHT string `json:"zh_CHT"`
|
||||
ZhCN string `json:"zh_CN"`
|
||||
}
|
||||
|
||||
type Readme struct {
|
||||
Default string `json:"default"`
|
||||
ArSA string `json:"ar_SA"`
|
||||
DeDE string `json:"de_DE"`
|
||||
EnUS string `json:"en_US"`
|
||||
EsES string `json:"es_ES"`
|
||||
FrFR string `json:"fr_FR"`
|
||||
HeIL string `json:"he_IL"`
|
||||
ItIT string `json:"it_IT"`
|
||||
JaJP string `json:"ja_JP"`
|
||||
KoKR string `json:"ko_KR"`
|
||||
PlPL string `json:"pl_PL"`
|
||||
PtBR string `json:"pt_BR"`
|
||||
RuRU string `json:"ru_RU"`
|
||||
TrTR string `json:"tr_TR"`
|
||||
ZhCHT string `json:"zh_CHT"`
|
||||
ZhCN string `json:"zh_CN"`
|
||||
}
|
||||
// LocaleStrings 表示按语种 key 的字符串表,key 为语种如 "default"、"en_US"、"zh_CN" 等
|
||||
type LocaleStrings map[string]string
|
||||
|
||||
type Funding struct {
|
||||
OpenCollective string `json:"openCollective"`
|
||||
|
|
@ -105,18 +51,18 @@ type Funding struct {
|
|||
}
|
||||
|
||||
type Package struct {
|
||||
Author string `json:"author"`
|
||||
URL string `json:"url"`
|
||||
Version string `json:"version"`
|
||||
MinAppVersion string `json:"minAppVersion"`
|
||||
DisabledInPublish bool `json:"disabledInPublish"`
|
||||
Backends []string `json:"backends"`
|
||||
Frontends []string `json:"frontends"`
|
||||
DisplayName *DisplayName `json:"displayName"`
|
||||
Description *Description `json:"description"`
|
||||
Readme *Readme `json:"readme"`
|
||||
Funding *Funding `json:"funding"`
|
||||
Keywords []string `json:"keywords"`
|
||||
Author string `json:"author"`
|
||||
URL string `json:"url"`
|
||||
Version string `json:"version"`
|
||||
MinAppVersion string `json:"minAppVersion"`
|
||||
DisabledInPublish bool `json:"disabledInPublish"`
|
||||
Backends []string `json:"backends"`
|
||||
Frontends []string `json:"frontends"`
|
||||
DisplayName LocaleStrings `json:"displayName"`
|
||||
Description LocaleStrings `json:"description"`
|
||||
Readme LocaleStrings `json:"readme"`
|
||||
Funding *Funding `json:"funding"`
|
||||
Keywords []string `json:"keywords"`
|
||||
|
||||
PreferredFunding string `json:"preferredFunding"`
|
||||
PreferredName string `json:"preferredName"`
|
||||
|
|
@ -151,13 +97,13 @@ type Package struct {
|
|||
}
|
||||
|
||||
type StagePackage struct {
|
||||
Author string `json:"author"`
|
||||
URL string `json:"url"`
|
||||
Version string `json:"version"`
|
||||
Description *Description `json:"description"`
|
||||
Readme *Readme `json:"readme"`
|
||||
I18N []string `json:"i18n"`
|
||||
Funding *Funding `json:"funding"`
|
||||
Author string `json:"author"`
|
||||
URL string `json:"url"`
|
||||
Version string `json:"version"`
|
||||
Description LocaleStrings `json:"description"`
|
||||
Readme LocaleStrings `json:"readme"`
|
||||
I18N []string `json:"i18n"`
|
||||
Funding *Funding `json:"funding"`
|
||||
}
|
||||
|
||||
type StageRepo struct {
|
||||
|
|
@ -175,259 +121,33 @@ type StageIndex struct {
|
|||
Repos []*StageRepo `json:"repos"`
|
||||
}
|
||||
|
||||
func getPreferredReadme(readme *Readme) string {
|
||||
if nil == readme {
|
||||
return "README.md"
|
||||
// getPreferredLocaleString 从 LocaleStrings 中按当前语种取值,无则回退 default、en_US,再回退 fallback。
|
||||
func getPreferredLocaleString(m LocaleStrings, fallback string) string {
|
||||
if len(m) == 0 {
|
||||
return fallback
|
||||
}
|
||||
|
||||
var ret string
|
||||
switch util.Lang {
|
||||
case "ar_SA":
|
||||
if "" != readme.ArSA {
|
||||
ret = readme.ArSA
|
||||
}
|
||||
case "de_DE":
|
||||
if "" != readme.DeDE {
|
||||
ret = readme.DeDE
|
||||
}
|
||||
case "en_US":
|
||||
if "" != readme.EnUS {
|
||||
ret = readme.EnUS
|
||||
}
|
||||
case "es_ES":
|
||||
if "" != readme.EsES {
|
||||
ret = readme.EsES
|
||||
}
|
||||
case "fr_FR":
|
||||
if "" != readme.FrFR {
|
||||
ret = readme.FrFR
|
||||
}
|
||||
case "he_IL":
|
||||
if "" != readme.HeIL {
|
||||
ret = readme.HeIL
|
||||
}
|
||||
case "it_IT":
|
||||
if "" != readme.ItIT {
|
||||
ret = readme.ItIT
|
||||
}
|
||||
case "ja_JP":
|
||||
if "" != readme.JaJP {
|
||||
ret = readme.JaJP
|
||||
}
|
||||
case "ko_KR":
|
||||
if "" != readme.KoKR {
|
||||
ret = readme.KoKR
|
||||
}
|
||||
case "pl_PL":
|
||||
if "" != readme.PlPL {
|
||||
ret = readme.PlPL
|
||||
}
|
||||
case "pt_BR":
|
||||
if "" != readme.PtBR {
|
||||
ret = readme.PtBR
|
||||
}
|
||||
case "ru_RU":
|
||||
if "" != readme.RuRU {
|
||||
ret = readme.RuRU
|
||||
}
|
||||
case "tr_TR":
|
||||
if "" != readme.TrTR {
|
||||
ret = readme.TrTR
|
||||
}
|
||||
case "zh_CHT":
|
||||
if "" != readme.ZhCHT {
|
||||
ret = readme.ZhCHT
|
||||
}
|
||||
case "zh_CN":
|
||||
if "" != readme.ZhCN {
|
||||
ret = readme.ZhCN
|
||||
}
|
||||
if v := strings.TrimSpace(m[util.Lang]); "" != v {
|
||||
return v
|
||||
}
|
||||
if "" != strings.TrimSpace(ret) {
|
||||
return ret
|
||||
if v := strings.TrimSpace(m["default"]); "" != v {
|
||||
return v
|
||||
}
|
||||
|
||||
defaultReadme := strings.TrimSpace(readme.Default)
|
||||
if "" != defaultReadme {
|
||||
return defaultReadme
|
||||
if v := strings.TrimSpace(m["en_US"]); "" != v {
|
||||
return v
|
||||
}
|
||||
|
||||
enUSReadme := strings.TrimSpace(readme.EnUS)
|
||||
if "" != enUSReadme {
|
||||
return enUSReadme
|
||||
}
|
||||
|
||||
return "README.md"
|
||||
return fallback
|
||||
}
|
||||
|
||||
func GetPreferredName(pkg *Package) string {
|
||||
if nil == pkg.DisplayName {
|
||||
return pkg.Name
|
||||
}
|
||||
|
||||
var ret string
|
||||
switch util.Lang {
|
||||
case "ar_SA":
|
||||
if "" != pkg.DisplayName.ArSA {
|
||||
ret = pkg.DisplayName.ArSA
|
||||
}
|
||||
case "de_DE":
|
||||
if "" != pkg.DisplayName.DeDE {
|
||||
ret = pkg.DisplayName.DeDE
|
||||
}
|
||||
case "en_US":
|
||||
if "" != pkg.DisplayName.EnUS {
|
||||
ret = pkg.DisplayName.EnUS
|
||||
}
|
||||
case "es_ES":
|
||||
if "" != pkg.DisplayName.EsES {
|
||||
ret = pkg.DisplayName.EsES
|
||||
}
|
||||
case "fr_FR":
|
||||
if "" != pkg.DisplayName.FrFR {
|
||||
ret = pkg.DisplayName.FrFR
|
||||
}
|
||||
case "he_IL":
|
||||
if "" != pkg.DisplayName.HeIL {
|
||||
ret = pkg.DisplayName.HeIL
|
||||
}
|
||||
case "it_IT":
|
||||
if "" != pkg.DisplayName.ItIT {
|
||||
ret = pkg.DisplayName.ItIT
|
||||
}
|
||||
case "ja_JP":
|
||||
if "" != pkg.DisplayName.JaJP {
|
||||
ret = pkg.DisplayName.JaJP
|
||||
}
|
||||
case "ko_KR":
|
||||
if "" != pkg.DisplayName.KoKR {
|
||||
ret = pkg.DisplayName.KoKR
|
||||
}
|
||||
case "pl_PL":
|
||||
if "" != pkg.DisplayName.PlPL {
|
||||
ret = pkg.DisplayName.PlPL
|
||||
}
|
||||
case "pt_BR":
|
||||
if "" != pkg.DisplayName.PtBR {
|
||||
ret = pkg.DisplayName.PtBR
|
||||
}
|
||||
case "ru_RU":
|
||||
if "" != pkg.DisplayName.RuRU {
|
||||
ret = pkg.DisplayName.RuRU
|
||||
}
|
||||
case "tr_TR":
|
||||
if "" != pkg.DisplayName.TrTR {
|
||||
ret = pkg.DisplayName.TrTR
|
||||
}
|
||||
case "zh_CHT":
|
||||
if "" != pkg.DisplayName.ZhCHT {
|
||||
ret = pkg.DisplayName.ZhCHT
|
||||
}
|
||||
case "zh_CN":
|
||||
if "" != pkg.DisplayName.ZhCN {
|
||||
ret = pkg.DisplayName.ZhCN
|
||||
}
|
||||
}
|
||||
if "" != strings.TrimSpace(ret) {
|
||||
return ret
|
||||
}
|
||||
|
||||
defaultName := strings.TrimSpace(pkg.DisplayName.Default)
|
||||
if "" != defaultName {
|
||||
return defaultName
|
||||
}
|
||||
|
||||
enUSName := strings.TrimSpace(pkg.DisplayName.EnUS)
|
||||
if "" != enUSName {
|
||||
return enUSName
|
||||
}
|
||||
|
||||
return pkg.Name
|
||||
return getPreferredLocaleString(pkg.DisplayName, pkg.Name)
|
||||
}
|
||||
|
||||
func getPreferredDesc(desc *Description) string {
|
||||
if nil == desc {
|
||||
return ""
|
||||
}
|
||||
func getPreferredDesc(desc LocaleStrings) string {
|
||||
return getPreferredLocaleString(desc, "")
|
||||
}
|
||||
|
||||
var ret string
|
||||
switch util.Lang {
|
||||
case "ar_SA":
|
||||
if "" != desc.ArSA {
|
||||
ret = desc.ArSA
|
||||
}
|
||||
case "de_DE":
|
||||
if "" != desc.DeDE {
|
||||
ret = desc.DeDE
|
||||
}
|
||||
case "en_US":
|
||||
if "" != desc.EnUS {
|
||||
ret = desc.EnUS
|
||||
}
|
||||
case "es_ES":
|
||||
if "" != desc.EsES {
|
||||
ret = desc.EsES
|
||||
}
|
||||
case "fr_FR":
|
||||
if "" != desc.FrFR {
|
||||
ret = desc.FrFR
|
||||
}
|
||||
case "he_IL":
|
||||
if "" != desc.HeIL {
|
||||
ret = desc.HeIL
|
||||
}
|
||||
case "it_IT":
|
||||
if "" != desc.ItIT {
|
||||
ret = desc.ItIT
|
||||
}
|
||||
case "ja_JP":
|
||||
if "" != desc.JaJP {
|
||||
ret = desc.JaJP
|
||||
}
|
||||
case "ko_KR":
|
||||
if "" != desc.KoKR {
|
||||
ret = desc.KoKR
|
||||
}
|
||||
case "pl_PL":
|
||||
if "" != desc.PlPL {
|
||||
ret = desc.PlPL
|
||||
}
|
||||
case "pt_BR":
|
||||
if "" != desc.PtBR {
|
||||
ret = desc.PtBR
|
||||
}
|
||||
case "ru_RU":
|
||||
if "" != desc.RuRU {
|
||||
ret = desc.RuRU
|
||||
}
|
||||
case "tr_TR":
|
||||
if "" != desc.TrTR {
|
||||
ret = desc.TrTR
|
||||
}
|
||||
case "zh_CHT":
|
||||
if "" != desc.ZhCHT {
|
||||
ret = desc.ZhCHT
|
||||
}
|
||||
case "zh_CN":
|
||||
if "" != desc.ZhCN {
|
||||
ret = desc.ZhCN
|
||||
}
|
||||
}
|
||||
if "" != strings.TrimSpace(ret) {
|
||||
return ret
|
||||
}
|
||||
|
||||
defaultDesc := strings.TrimSpace(desc.Default)
|
||||
if "" != defaultDesc {
|
||||
return defaultDesc
|
||||
}
|
||||
|
||||
enUSDesc := strings.TrimSpace(desc.EnUS)
|
||||
if "" != enUSDesc {
|
||||
return enUSDesc
|
||||
}
|
||||
|
||||
return ""
|
||||
func getPreferredReadme(readme LocaleStrings) string {
|
||||
return getPreferredLocaleString(readme, "README.md")
|
||||
}
|
||||
|
||||
func getPreferredFunding(funding *Funding) string {
|
||||
|
|
@ -735,8 +455,8 @@ func GetPackageREADME(repoURL, repoHash, packageType string) (ret string) {
|
|||
ret = fmt.Sprintf("Load bazaar package's preferred README(%s) failed: %s", readme, err.Error())
|
||||
// 回退到 Default README
|
||||
var defaultReadme string
|
||||
if nil != repo.Package.Readme {
|
||||
defaultReadme = repo.Package.Readme.Default
|
||||
if len(repo.Package.Readme) > 0 {
|
||||
defaultReadme = repo.Package.Readme["default"]
|
||||
}
|
||||
if "" == strings.TrimSpace(defaultReadme) {
|
||||
defaultReadme = "README.md"
|
||||
|
|
@ -771,7 +491,7 @@ func GetPackageREADME(repoURL, repoHash, packageType string) (ret string) {
|
|||
return
|
||||
}
|
||||
|
||||
func loadInstalledReadme(installPath, basePath string, readme *Readme) (ret string) {
|
||||
func loadInstalledReadme(installPath, basePath string, readme LocaleStrings) (ret string) {
|
||||
readmeFilename := getPreferredReadme(readme)
|
||||
readmeData, readErr := os.ReadFile(filepath.Join(installPath, readmeFilename))
|
||||
if nil == readErr {
|
||||
|
|
@ -783,8 +503,8 @@ func loadInstalledReadme(installPath, basePath string, readme *Readme) (ret stri
|
|||
ret = fmt.Sprintf("File %s not found", readmeFilename)
|
||||
// 回退到 Default README
|
||||
var defaultReadme string
|
||||
if nil != readme {
|
||||
defaultReadme = strings.TrimSpace(readme.Default)
|
||||
if len(readme) > 0 {
|
||||
defaultReadme = strings.TrimSpace(readme["default"])
|
||||
}
|
||||
if "" == defaultReadme {
|
||||
defaultReadme = "README.md"
|
||||
|
|
|
|||
|
|
@ -132,25 +132,18 @@ func loadThemes() {
|
|||
modes := themeConf.Modes
|
||||
for _, mode := range modes {
|
||||
t := &conf.AppearanceTheme{Name: name}
|
||||
if "zh_CN" == util.Lang {
|
||||
if "midnight" == name {
|
||||
t.Label = name + "(默认主题)"
|
||||
} else if "daylight" == name {
|
||||
t.Label = name + "(默认主题)"
|
||||
} else {
|
||||
if nil != themeConf.DisplayName && "" != themeConf.DisplayName.ZhCN && name != themeConf.DisplayName.ZhCN {
|
||||
t.Label = themeConf.DisplayName.ZhCN + "(" + name + ")"
|
||||
} else {
|
||||
t.Label = name
|
||||
}
|
||||
}
|
||||
if "midnight" == name || "daylight" == name {
|
||||
t.Label = name + Conf.Language(281)
|
||||
} else {
|
||||
if "midnight" == name {
|
||||
t.Label = name + " (Default)"
|
||||
} else if "daylight" == name {
|
||||
t.Label = name + " (Default)"
|
||||
} else {
|
||||
t.Label = name
|
||||
t.Label = name
|
||||
if len(themeConf.DisplayName) > 0 {
|
||||
v := strings.TrimSpace(themeConf.DisplayName[util.Lang])
|
||||
if "" == v {
|
||||
v = strings.TrimSpace(themeConf.DisplayName["default"])
|
||||
}
|
||||
if "" != v && name != v {
|
||||
t.Label = v + " (" + name + ")"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,34 +514,41 @@ func matchPackage(keywords []string, pkg *bazaar.Package) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if nil == pkg || nil == pkg.DisplayName || nil == pkg.Description {
|
||||
if nil == pkg {
|
||||
return false
|
||||
}
|
||||
|
||||
hits := map[string]bool{}
|
||||
for _, keyword := range keywords {
|
||||
if strings.Contains(strings.ToLower(pkg.DisplayName.Default), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.DisplayName.ZhCN), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.DisplayName.ZhCHT), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.DisplayName.EnUS), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.Description.Default), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.Description.ZhCN), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.Description.ZhCHT), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.Description.EnUS), keyword) ||
|
||||
strings.Contains(strings.ToLower(path.Base(pkg.RepoURL)), keyword) ||
|
||||
strings.Contains(strings.ToLower(pkg.Author), keyword) {
|
||||
hits[keyword] = true
|
||||
continue
|
||||
}
|
||||
|
||||
for _, pkgKeyword := range pkg.Keywords {
|
||||
if strings.Contains(strings.ToLower(pkgKeyword), keyword) {
|
||||
hits[keyword] = true
|
||||
break
|
||||
}
|
||||
for _, kw := range keywords {
|
||||
if !packageContainsKeyword(pkg, kw) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return len(hits) == len(keywords)
|
||||
|
||||
// 全部关键词匹配
|
||||
return true
|
||||
}
|
||||
|
||||
func packageContainsKeyword(pkg *bazaar.Package, kw string) bool {
|
||||
if strings.Contains(strings.ToLower(path.Base(pkg.RepoURL)), kw) ||
|
||||
strings.Contains(strings.ToLower(pkg.Author), kw) {
|
||||
return true
|
||||
}
|
||||
for _, s := range pkg.DisplayName {
|
||||
if strings.Contains(strings.ToLower(s), kw) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, s := range pkg.Description {
|
||||
if strings.Contains(strings.ToLower(s), kw) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, s := range pkg.Keywords {
|
||||
if strings.Contains(strings.ToLower(s), kw) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getSearchKeywords(query string) (ret []string) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue