| 
									
										
										
										
											2025-03-04 17:27:00 +02:00
										 |  |  | import { Dropdown } from "bootstrap"; | 
					
						
							|  |  |  | import NoteContextAwareWidget from "./note_context_aware_widget.js"; | 
					
						
							| 
									
										
										
										
											2025-03-04 20:48:36 +02:00
										 |  |  | import { getAvailableLocales } from "../services/i18n.js"; | 
					
						
							| 
									
										
										
										
											2025-03-04 17:48:04 +02:00
										 |  |  | import { t } from "i18next"; | 
					
						
							| 
									
										
										
										
											2025-03-04 17:49:58 +02:00
										 |  |  | import type { EventData } from "../components/app_context.js"; | 
					
						
							|  |  |  | import type FNote from "../entities/fnote.js"; | 
					
						
							| 
									
										
										
										
											2025-03-04 17:54:52 +02:00
										 |  |  | import attributes from "../services/attributes.js"; | 
					
						
							| 
									
										
										
										
											2025-03-04 20:48:36 +02:00
										 |  |  | import type { Locale } from "../../../services/i18n.js"; | 
					
						
							| 
									
										
										
										
											2025-03-04 17:27:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | const TPL = `\
 | 
					
						
							|  |  |  | <div class="dropdown note-language-widget"> | 
					
						
							|  |  |  |     <button type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="btn btn-sm dropdown-toggle select-button note-language-button"> | 
					
						
							|  |  |  |         <span class="note-language-desc"></span> | 
					
						
							|  |  |  |         <span class="caret"></span> | 
					
						
							|  |  |  |     </button> | 
					
						
							|  |  |  |     <div class="note-language-dropdown dropdown-menu dropdown-menu-left tn-dropdown-list"></div> | 
					
						
							| 
									
										
										
										
											2025-03-04 20:48:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <style> | 
					
						
							|  |  |  |         .note-language-dropdown [dir=rtl] { | 
					
						
							|  |  |  |             text-align: right; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     </style> | 
					
						
							| 
									
										
										
										
											2025-03-04 17:27:00 +02:00
										 |  |  | </div> | 
					
						
							|  |  |  | `;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 18:38:07 +02:00
										 |  |  | const DEFAULT_LOCALE: Locale = { | 
					
						
							|  |  |  |     id: "", | 
					
						
							|  |  |  |     name: t("note_language.not_set") | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 17:27:00 +02:00
										 |  |  | export default class NoteLanguageWidget extends NoteContextAwareWidget { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private dropdown!: Dropdown; | 
					
						
							|  |  |  |     private $noteLanguageDropdown!: JQuery<HTMLElement>; | 
					
						
							|  |  |  |     private $noteLanguageDesc!: JQuery<HTMLElement>; | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |     private locales: (Locale | "---")[]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor() { | 
					
						
							|  |  |  |         super(); | 
					
						
							| 
									
										
										
										
											2025-03-04 20:57:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const allLanguages = getAvailableLocales(); | 
					
						
							|  |  |  |         const leftToRightLanguages = allLanguages.filter((l) => !l.rtl); | 
					
						
							|  |  |  |         const rightToLeftLanguages = allLanguages.filter((l) => l.rtl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |         this.locales = [ | 
					
						
							| 
									
										
										
										
											2025-03-04 18:38:07 +02:00
										 |  |  |             DEFAULT_LOCALE, | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |             "---", | 
					
						
							| 
									
										
										
										
											2025-03-04 20:57:21 +02:00
										 |  |  |             ...leftToRightLanguages | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2025-03-04 20:57:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (rightToLeftLanguages.length > 0) { | 
					
						
							|  |  |  |             this.locales = [ | 
					
						
							|  |  |  |                 ...this.locales, | 
					
						
							|  |  |  |                 "---", | 
					
						
							|  |  |  |                 ...rightToLeftLanguages | 
					
						
							|  |  |  |             ]; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-03-04 17:27:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     doRender() { | 
					
						
							|  |  |  |         this.$widget = $(TPL); | 
					
						
							|  |  |  |         this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")[0]); | 
					
						
							| 
									
										
										
										
											2025-03-04 17:43:24 +02:00
										 |  |  |         this.$widget.on("show.bs.dropdown", () => this.renderDropdown()); | 
					
						
							| 
									
										
										
										
											2025-03-04 17:27:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.$noteLanguageDropdown = this.$widget.find(".note-language-dropdown") | 
					
						
							|  |  |  |         this.$noteLanguageDesc = this.$widget.find(".note-language-desc"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 17:43:24 +02:00
										 |  |  |     renderDropdown() { | 
					
						
							|  |  |  |         this.$noteLanguageDropdown.empty(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!this.note) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |         for (const locale of this.locales) { | 
					
						
							| 
									
										
										
										
											2025-03-04 17:48:04 +02:00
										 |  |  |             if (typeof locale === "object") { | 
					
						
							|  |  |  |                 const $title = $("<span>").text(locale.name); | 
					
						
							| 
									
										
										
										
											2025-03-04 20:48:36 +02:00
										 |  |  |                 if (locale.rtl) { | 
					
						
							|  |  |  |                     $title.attr("dir", "rtl"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 17:48:04 +02:00
										 |  |  |                 const $link = $('<a class="dropdown-item">') | 
					
						
							|  |  |  |                     .attr("data-language", locale.id) | 
					
						
							|  |  |  |                     .append('<span class="check">✓</span> ') | 
					
						
							| 
									
										
										
										
											2025-03-04 17:54:52 +02:00
										 |  |  |                     .append($title) | 
					
						
							|  |  |  |                     .on("click", () => { | 
					
						
							|  |  |  |                         const languageId = $link.attr("data-language") ?? ""; | 
					
						
							|  |  |  |                         this.save(languageId); | 
					
						
							|  |  |  |                     }) | 
					
						
							| 
									
										
										
										
											2025-03-04 20:48:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 17:48:04 +02:00
										 |  |  |                 this.$noteLanguageDropdown.append($link); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 this.$noteLanguageDropdown.append('<div class="dropdown-divider"></div>'); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-03-04 17:43:24 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 17:54:52 +02:00
										 |  |  |     async save(languageId: string) { | 
					
						
							|  |  |  |         if (!this.note) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 18:35:42 +02:00
										 |  |  |         attributes.setAttribute(this.note, "label", "language", languageId); | 
					
						
							| 
									
										
										
										
											2025-03-04 17:54:52 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 17:49:58 +02:00
										 |  |  |     async refreshWithNote(note: FNote) { | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |         const languageId = note.getLabelValue("language") ?? ""; | 
					
						
							| 
									
										
										
										
											2025-03-04 18:38:07 +02:00
										 |  |  |         const language = (this.locales.find((l) => (typeof l === "object" && l.id === languageId)) as Locale | null) ?? DEFAULT_LOCALE; | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |         this.$noteLanguageDesc.text(language.name); | 
					
						
							| 
									
										
										
										
											2025-03-04 18:40:26 +02:00
										 |  |  |         this.dropdown.hide(); | 
					
						
							| 
									
										
										
										
											2025-03-04 17:49:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) { | 
					
						
							| 
									
										
										
										
											2025-03-04 18:30:43 +02:00
										 |  |  |         if (loadResults.getAttributeRows().find((a) => a.noteId === this.noteId && a.name === "language")) { | 
					
						
							| 
									
										
										
										
											2025-03-04 17:49:58 +02:00
										 |  |  |             this.refresh(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-04 17:27:00 +02:00
										 |  |  | } |