Browse / github.com/storytold/craft-launcher / patch
i18n: add Turkish (tr) interface language
i18n: add Turkish (tr) interface language ## Summary Adds full Turkish (`tr`) interface localization to ArtCraft Launcher: - **Catalog (`crates/ui-egui/src/i18n/tr.tsv`)**: All 344 translatable keys authored clean-room from the English labels using idiomatic computing vocabulary. - **Language Registry (`crates/ui-egui/src/i18n/lang.rs`)**: - Registered Turkish (`tr`) with native name `"Türkçe"` and English name `"Turkish"`. - Turkish plural rule uses `plural_none` with `plural_forms: 1` (nouns in Turkish do not inflect for number when quantified). - Handles BCP 47 locale tags (`tr`, `tr-TR`, `tr_TR.UTF-8`, `TR_tr`). - Native n
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- MOzcelik14 (imported from pull request #931, open)
- Base
7aafad661a11594a70ae949471d481f30d8fe64a- Size
- +536 −10 in 5 files
- Review
- pending
- Shared
- 2026-10-28
- Id
ae916da1fe87776ba74957a5
How it went
No other operator has reported using it yet.
Diff
raw · README.md crates/ui-egui/src/i18n/lang.rs crates/ui-egui/src/i18n/tests.rs crates/ui-egui/src/i18n/tr.tsv crates/ui-egui/tests/turkish.rs
@@ -93,16 +93,17 @@ The web version shows the same catalog in the browser, with the latest download The interface is in English, Brazilian Portuguese (Português (Brasil)), Czech (Čeština), French (Français), German (Deutsch), Hungarian (Magyar), Japanese (日本語), Polish (Polski), Russian-(Русский), Simplified Chinese (简体中文) or Spanish (Español). **Auto**, the default, follows the-system or browser language; **Settings → Language** picks one and switches at once, and the choice-is kept between runs. Czech locales (`cs-CZ`, `cs_CZ.UTF-8`…) select Czech, German ones (`de-DE`,+(Русский), Simplified Chinese (简体中文), Spanish (Español) or Turkish (Türkçe). **Auto**, the default,+follows the system or browser language; **Settings → Language** picks one and switches at once, and the+choice is kept between runs. Czech locales (`cs-CZ`, `cs_CZ.UTF-8`…) select Czech, German ones (`de-DE`, `de-AT`, `de-CH`, `de_DE.UTF-8`…) German, French ones (`fr-FR`, `fr-CA`…) French, Hungarian ones (`hu`, `hu-HU`, `hu_HU.UTF-8`…) Hungarian, Japanese ones (`ja`, `ja-JP`, `ja_JP.UTF-8`…) Japanese, Polish ones (`pl`, `pl-PL`, `pl_PL.UTF-8`) Polish, Spanish ones (`es-ES`, `es-MX`, `es-419`…)-Spanish, and Portuguese ones (`pt-BR`, and `pt-PT` too, for now) Brazilian Portuguese. Simplified-Chinese locales (`zh-CN`, `zh-SG`, `zh-Hans`, and POSIX forms such as `zh_CN.UTF-8`) select-Chinese; Traditional Chinese ones don't. To try a language without changing the setting, start the-desktop app with `ARTCRAFT_LAUNCHER_LOCALE=pt-BR`, or add `?lang=ru` to the web address.+Spanish, Turkish ones (`tr`, `tr-TR`, `tr_TR.UTF-8`…) Turkish, and Portuguese ones (`pt-BR`, and+`pt-PT` too, for now) Brazilian Portuguese. Simplified Chinese locales (`zh-CN`, `zh-SG`, `zh-Hans`,+and POSIX forms such as `zh_CN.UTF-8`) select Chinese; Traditional Chinese ones don't. To try a+language without changing the setting, start the desktop app with `ARTCRAFT_LAUNCHER_LOCALE=tr`, or+add `?lang=tr` to the web address. The CJK languages are drawn with the system's own CJK font (Hiragino Sans or PingFang on macOS, Yu Gothic, Meiryo or Microsoft YaHei on Windows, Noto Sans CJK, IPA, Takao or WenQuanYi on Linux and@@ -22,7 +22,7 @@ impl Script { /// One supported UI language. pub struct LangInfo {- /// Canonical BCP 47 code (`en`, `ru`, `zh-CN`, `de`, `fr`, `pt-BR`, `es`, `cs`, `pl`, `hu`, `ja`).+ /// Canonical BCP 47 code (`en`, `ru`, `zh-CN`, `de`, `fr`, `pt-BR`, `es`, `cs`, `pl`, `hu`, `ja`, `tr`). /// Also the `interfaceLanguage` value. pub code: &'static str, /// The language's name in itself, shown in the Preferences dropdown.@@ -94,7 +94,7 @@ pub(super) fn plural_polish(n: u64) -> usize { } /// The registry. English first: it is the fallback and the source language.-pub static LANGUAGES: [LangInfo; 11] = [+pub static LANGUAGES: [LangInfo; 12] = [ LangInfo { code: "en", name: "English",@@ -216,6 +216,17 @@ pub static LANGUAGES: [LangInfo; 11] = [ complete_menus: true, catalog: OnceLock::new(), },+ LangInfo {+ code: "tr",+ name: "Türkçe",+ english_name: "Turkish",+ script: None,+ source: include_str!("tr.tsv"),+ plural: plural_none,+ plural_forms: 1,+ complete_menus: true,+ catalog: OnceLock::new(),+ }, ]; impl LangInfo {@@ -254,6 +265,7 @@ impl Lang { pub const PL: Lang = Lang(&LANGUAGES[8]); pub const HU: Lang = Lang(&LANGUAGES[9]); pub const JA: Lang = Lang(&LANGUAGES[10]);+ pub const TR: Lang = Lang(&LANGUAGES[11]); pub fn code(self) -> &'static str { self.0.code@@ -400,6 +400,24 @@ fn japanese_locales_and_counts_work() { assert_eq!(message(Lang::JA, "PhotoCraft updated to 0.5.0"), "PhotoCraft を 0.5.0 に更新しました"); } +#[test]+fn turkish_locales_and_plurals_work() {+ for tag in ["tr", "tr-TR", "tr_TR.UTF-8", "TR_tr"] {+ assert_eq!(lang_from_tag(tag), Some(Lang::TR), "{tag}");+ }+ assert_eq!(super::detect::first_supported(["xx-XX", "tr-TR", "en-US"]), Some(Lang::TR));+ // Turkish nouns do not inflect for number; one plural form covers every count.+ for n in [0, 1, 2, 11, 100] {+ assert_eq!(trn(Lang::TR, n, "{n} app", "{n} apps"), format!("{n} uygulama"));+ assert_eq!(trn(Lang::TR, n, "{n} day ago", "{n} days ago"), format!("{n} gün önce"));+ }+ assert_eq!(trn(Lang::TR, 2, "{n} unknown item", "{n} unknown items"), "2 unknown items");+ assert_eq!(tr(Lang::TR, "Untranslated diagnostic"), "Untranslated diagnostic");+ assert_eq!(super::tr_ctx(Lang::TR, "month", "Mar"), "Mar");+ assert_eq!(tr(Lang::TR, "{month} {day}, {year}"), "{day} {month} {year}");+ assert_eq!(message(Lang::TR, "PhotoCraft updated to 0.5.0"), "PhotoCraft, 0.5.0 sürümüne güncellendi");+}+ /// With the system's Chinese font installed, every UI family can draw the whole Chinese catalog. /// Machines without one (CI, the web) skip this; the UI then stays in English. #[test]@@ -558,7 +576,9 @@ fn picker_lists_english_first_then_names_alphabetically() { let pos = |code: &str| order.iter().position(|l| l.code() == code).unwrap_or_else(|| panic!("{code} registered")); assert!(pos("cs") < pos("de"), "Čeština sorts under C, not after Z"); assert!(pos("fr") < pos("hu"), "Magyar sorts under M, not under its code");- assert!(pos("pt-BR") < pos("ru"), "Latin names come before Cyrillic");+ assert!(pos("pt-BR") < pos("tr"), "Português sorts before Türkçe");+ assert!(pos("tr") < pos("ru"), "Latin names come before Cyrillic"); assert!(pos("ru") < pos("ja"), "Cyrillic names come before CJK"); assert_eq!(name_sort_key("Čeština"), "cestina");+ assert_eq!(name_sort_key("Türkçe"), "turkce"); }new file mode 100644@@ -0,0 +1,364 @@+# Turkish (tr) catalog for ArtCraft Launcher.+# Format: context<TAB>source<TAB>translation+# Empty context = plain UI string (tl!, t).+# @id = command-id keyed (tr_id).+# @plural = plural forms: one form for Turkish (nouns do not inflect for number).+# @msg = status/error message template (message, msg).+# Other context = disambiguation for tr_ctx.+#+# Clean-room: written from the meaning of ArtCraft Launcher's English labels, in natural,+# idiomatic Turkish computing vocabulary.+#+# Coverage: the whole interface: every menu string and tl! literal (complete_menus = true).+# Left in English on purpose: product name "ArtCraft Launcher" (and its "Launcher" tag), suite+# name "Craft App Suite", app names (PhotoCraft, LightCraft, FilmCraft,+# DesignCraft, VectorCraft, PdfCraft, EffectCraft, WordCraft, DeckCraft, GridCraft, CADCraft,+# SoundCraft, FigCraft), "GitHub", "Discord", "Finder", "makers".+# Trailing "…" (U+2026) must be preserved. Placeholders must appear in the translation:+# {ago}, {a}, {b}, {count}, {date}, {day}, {done}, {e}, {f}, {installed}, {latest}, {min},+# {month}, {name}, {n}, {os}, {platform}, {sources}, {total}, {version}, {v}, {year}.++ Launcher Launcher+ Craft App Suite Craft App Suite+ Open Source Tools for Creatives, Makers, and Builders Yaratıcılar, Üreticiler ve Geliştiriciler İçin Açık Kaynaklı Araçlar+ Settings Ayarlar+ Check for updates Güncellemeleri denetle+ Grid Izgara+ Table Tablo+ Show apps as cards Uygulamaları kart olarak göster+ Show apps as a table Uygulamaları tablo olarak göster+ All Tümü+ Updates Güncellemeler+ Not installed Yüklü değil+ Search apps Uygulama ara+ Sort Sırala+ Suite order Paket sırası+ Name Ad+ Inspired by Esinlenme+ Status Durum+ Installed version Yüklü sürüm+ Latest version En son sürüm+ Newest release En yeni sürüm+ Discord Discord+ GitHub GitHub+ Website Web sitesi+ Classic apps Klasik uygulamalar+ Classic Klasik+ New apps Yeni uygulamalar+ NEW YENİ+ Install Yükle+ Update to {v} {v} sürümüne güncelle+ Open Aç+ Download for {os} {os} için indir+ Download İndir+ Coming soon Yakında+ Checking… Denetleniyor…+ Not available Kullanılamıyor+ Offline Çevrimdışı+ Downloading {done} of {total} {total} içinden {done} indiriliyor+ Downloading… İndiriliyor…+ Reconnecting… Yeniden bağlanılıyor…+ Verifying… Doğrulanıyor…+ Installing, then restarting… Yükleniyor, ardından yeniden başlatılacak…+ Installing… Yükleniyor…+ Removing… Kaldırılıyor…+ Pause download İndirmeyi duraklat+ Cancel download İndirmeyi iptal et+ Resume download İndirmeyi sürdür+ Discard download İndirmeyi at+ Release notes Sürüm notları+ Show in Finder Finder'da göster+ Show in Explorer Dosya Gezgini'nde göster+ Show in Files Dosyalar'da göster+ Reinstall Yeniden yükle+ Uninstall… Kaldır…+ All releases Tüm sürümler+ ArtCraft Launcher {version} is available. ArtCraft Launcher {version} mevcut.+ Dismiss Kapat+ Update and restart Güncelle ve yeniden başlat+ A new version is available. Would you like to relaunch with the updated version? Yeni bir sürüm mevcut. Güncellenmiş sürümle yeniden başlatmak ister misiniz?+ A new version is available. Download it to replace this version? Yeni bir sürüm mevcut. Bu sürümün yerine indirmek ister misiniz?+ Later Daha sonra+ What's new Yenilikler+ No notes were published with this release. Bu sürümle birlikte herhangi bir not yayımlanmadı.+ Released {date} Yayımlanma: {date}+ Open on GitHub GitHub'da aç+ Close Kapat+ ArtCraft Launcher {version} ArtCraft Launcher {version}+ Only when I ask Yalnızca ben istediğimde+ Automatically download and install updates Güncellemeleri otomatik olarak indir ve yükle+ Notify me when an installed app has an update Yüklü bir uygulamanın güncellemesi olduğunda bana bildir+ Include pre-releases (betas and release candidates) Ön sürümleri (beta ve sürüm adayları) dahil et+ Installing on Linux Linux'ta yükleme+ Installing on Windows Windows'ta yükleme+ Install new apps as Yeni uygulamaları şu biçimde yükle:+ System package (recommended) Sistem paketi (önerilen)+ Updates always use the format an app was installed with. Güncellemeler her zaman uygulamanın yüklendiği biçimi kullanır.+ Running in the background Arka planda çalışma+ Keep running in the tray when the window is closed Pencere kapatıldığında sistem tepsisinde çalışmaya devam et+ ArtCraft Launcher is still running ArtCraft Launcher hâlâ çalışıyor+ It's in the tray: open it or quit it from the tray icon, or turn this off in the settings. Sistem tepsisinde: tepsi simgesinden açabilir ya da çıkabilirsiniz veya bunu ayarlardan kapatabilirsiniz.+ Show the window on the current desktop Pencereyi geçerli masaüstünde göster+ Start ArtCraft Launcher when I log in Oturum açtığımda ArtCraft Launcher'ı başlat+ Community Topluluk+ Questions, ideas and news from the ArtCraft team ArtCraft ekibinden sorular, fikirler ve haberler+ Appearance Görünüm+ Quit ArtCraft Launcher ArtCraft Launcher'dan çık+ Done Bitti+ Uninstall {name}? {name} kaldırılsın mı?+ The app will be moved to the Trash. Your documents and settings stay. Uygulama Çöp Sepeti'ne taşınacak. Belgeleriniz ve ayarlarınız korunur.+ Windows will remove it like any installed program. Your documents and settings stay. Windows bu uygulamayı normal bir program gibi kaldıracak. Belgeleriniz ve ayarlarınız korunur.+ Your system's package manager will remove it, and may ask for your password. Your documents and settings stay. Sisteminizin paket yöneticisi uygulamayı kaldıracak ve parolanızı isteyebilir. Belgeleriniz ve ayarlarınız korunur.+ The app will be removed. Your documents and settings stay. Uygulama kaldırılacak. Belgeleriniz ve ayarlarınız korunur.+ Uninstall Kaldır+ Cancel İptal+ Checked {ago} {ago} denetlendi+ just now az önce+ yesterday dün+ {month} {day}, {year} {day} {month} {year}+ Automatically Otomatik olarak+ Every Craft app Tüm Craft uygulamaları+ Apps on this computer Bu bilgisayardaki uygulamalar+ Installed apps with a newer version Daha yeni sürümü bulunan yüklü uygulamalar+ Apps you can install Yükleyebileceğiniz uygulamalar+ Hide App Uygulamayı Gizle+ Unhide App Uygulamayı Göster+ Hidden Apps Gizlenen Uygulamalar+ Apps you hid Gizlediğiniz uygulamalar+ Checked {ago} · using {sources} {ago} denetlendi · {sources} kullanılarak+ {a} and {b} {a} ve {b}+ Join the Discord Discord'a katılın+ Learn more Daha fazla bilgi+ Minimize Simge durumuna küçült+ Maximize Ekranı kapla+ Restore Geri yükle+ New Yeni+ OK Tamam+ Open link Bağlantıyı aç+ Update Güncelle+ {name} icon {name} simgesi+ Loading ArtCraft Launcher… ArtCraft Launcher yükleniyor…+ Cancel update Güncellemeyi iptal et+ Stop waiting; the update can be started again later Beklemeyi durdur; güncelleme daha sonra yeniden başlatılabilir+ Download again Yeniden indir+ Install cancelled Yükleme iptal edildi+ Install cancelled. The download is kept for the next try. Yükleme iptal edildi. İndirilen dosya bir sonraki deneme için saklandı.+ Update cancelled Güncelleme iptal edildi+ Uninstall cancelled Kaldırma iptal edildi+ Retry install Yüklemeyi yeniden dene+ Retry update to {version} {version} sürümüne güncellemeyi yeniden dene+ The download is still here. It's checked again, then installed. İndirilen dosya hâlâ burada. Tekrar kontrol edilip ardından yüklenecek.+ Waiting for another app… Başka bir uygulama bekleniyor…+ Waiting for other installs… Diğer yüklemeler bekleniyor…+ Installer (.msi) Yükleyici (.msi)+ Portable (.zip) Taşınabilir (.zip)+ Disk image (.dmg) Disk görüntüsü (.dmg)+ Debian package (.deb) Debian paketi (.deb)+ RPM package (.rpm) RPM paketi (.rpm)+ Arch package (.pkg.tar.zst) Arch paketi (.pkg.tar.zst)+ Flatpak bundle Flatpak paketi+ Tarball (.tar.gz) Tar arşivi (.tar.gz)+photocraft Image editing Görsel düzenleme+vectorcraft Vector illustration Vektörel çizim+filmcraft Video editing, color and sound Video düzenleme, renk ve ses+lightcraft Photo library and raw development Fotoğraf kitaplığı ve RAW geliştirme+pdfcraft Reading, organizing and protecting PDFs PDF okuma, düzenleme ve koruma+effectcraft Motion graphics and visual effects Hareketli grafikler ve görsel efektler+designcraft Page layout and publishing Sayfa mizanpajı ve yayıncılık+wordcraft Writing and document design Yazı ve belge tasarımı+deckcraft Presentations and slide shows Sunumlar ve slayt gösterileri+gridcraft Spreadsheets and data Elektronik tablolar ve veri+cadcraft Computer-aided design and drafting Bilgisayar destekli tasarım ve teknik çizim+soundcraft Recording, editing and mixing audio Ses kaydı, düzenleme ve miksaj+figcraft Interface design and prototyping Arayüz tasarımı ve prototipleme+month Jan Oca+month Feb Şub+month Mar Mar+month Apr Nis+month May May+month Jun Haz+month Jul Tem+month Aug Ağu+month Sep Eyl+month Oct Eki+month Nov Kas+month Dec Ara+ Not checked yet Henüz denetlenmedi+ GitHub's hourly limit was reached; full details return in {min} min GitHub'ın saatlik istek sınırına ulaşıldı; tüm ayrıntılar {min} dk. içinde tekrar görüntülenebilecek+ GitHub limit hit; back in {min} min GitHub sınırına ulaşıldı; {min} dk. içinde geri dönecek+ Installing for {platform} {platform} için yükleniyor+ Downloads for {platform} {platform} için indirmeler+ No downloads for this system Bu sistem için indirme bulunmuyor+ Join the ArtCraft community on Discord Discord'da ArtCraft topluluğuna katılın+ ArtCraft on {name} {name} üzerinde ArtCraft+ Couldn't open {name}: {e} {name} açılamadı: {e}+ Download cancelled İndirme iptal edildi+ Available to install Yüklenmeye hazır+ Available Kullanılabilir+ Installed · up to date Yüklü · güncel+ Update available Güncelleme mevcut+ Installed Yüklü+ installed yüklü+ Not available here Burada kullanılamıyor+ Updating… Güncelleniyor…+ Update paused Güncelleme duraklatıldı+ Download paused İndirme duraklatıldı+ {version} installed → {latest} released {version} yüklü → {latest} yayımlandı+ Version {version} Sürüm {version}+ {installed} installed · latest {latest} {installed} yüklü · en son {latest}+ Installed · latest {latest} Yüklü · en son {latest}+ Version {version} installed Sürüm {version} yüklü+ Version {latest} Sürüm {latest}+ No release published yet Henüz bir sürüm yayımlanmadı+ ArtCraft Launcher ArtCraft Launcher+ App Uygulama+ Latest En son+ Released Yayımlanma+ Auto Otomatik+ Language Dil+ Ascending Artan+ Descending Azalan+ Click to reverse the order Sıralamayı tersine çevirmek için tıklayın+ Click to sort by this column Bu sütuna göre sıralamak için tıklayın+ Like {name} {name} benzeri+ {done} of {total} {total} içinden {done}+ Downloading İndiriliyor+ Verifying checksum… Sağlama toplamı doğrulanıyor…+ Resume Sürdür+ {done} of {total} downloaded {total} içinden {done} indirildi+ {done} downloaded {done} indirildi+ Checking for updates… Güncellemeler denetleniyor…+ Downloads the new version, replaces this one and opens it again Yeni sürümü indirir, mevcut sürümle değiştirir ve yeniden açar+ Couldn't check for updates: {f} Güncellemeler denetlenemedi: {f}+ Website (coming soon) Web sitesi (yakında)+ GitHub repository GitHub deposu+ ArtCraft ArtCraft+ Update 1 app 1 uygulamayı güncelle+ Update all ({count}) Tümünü güncelle ({count})+ ⊞ Grid ⊞ Izgara+ ☰ Table ☰ Tablo+ 🔍 Search apps 🔍 Uygulama ara+ {name} {version} {name} {version}+ Match system Sistemle eşleş+ Dark Karanlık+ Light Aydınlık+ Full changelog Tam değişiklik günlüğü+ link bağlantı+ No apps match Eşleşen uygulama yok+ Open ArtCraft Launcher to update. Güncellemek için ArtCraft Launcher'ı açın.+ {name} {v} is available {name} {v} mevcut+ {count} updates are available {count} güncelleme mevcut+ These notes weren't fetched (GitHub's request limit was reached). They're on the release page. Bu notlar alınamadı (GitHub'ın istek sınırına ulaşıldı). Sürüm sayfasında yer alıyorlar.+ When on, opening the launcher from the menu bar brings its window to the desktop you're on. When off, macOS switches you to the desktop the window was on. Açık olduğunda, başlatıcıyı menü çubuğundan açmak penceresini bulunduğunuz masaüstüne getirir. Kapalı olduğunda macOS sizi pencerenin bulunduğu masaüstüne geçirir.+ Couldn't change the login item: {e} Oturum açma öğesi değiştirilemedi: {e}+column App Uygulama+column Installed Yüklü+column Latest En son+column Released Yayımlanma+filter Installed Yüklü+ App details Uygulama ayrıntıları+ More actions for {name} {name} için diğer işlemler+ Close (Esc) Kapat (Esc)+ Features Özellikler+ Latest release En son sürüm+ Version Sürüm+ Platforms Platformlar+ Releases Sürümler+ Enlarge picture Resmi büyüt+ Click to enlarge Büyütmek için tıklayın+ Previous picture (←) Önceki resim (←)+ Next picture (→) Sonraki resim (→)+ Loading pictures… Resimler yükleniyor…+ Pictures couldn't be loaded. Reopen this page to try again. Resimler yüklenemedi. Yeniden denemek için bu sayfayı tekrar açın.+ {name} details {name} ayrıntıları+@plural {n} app|{n} apps {n} uygulama+@plural {n} min ago|{n} min ago {n} dk. önce+@plural {n} h ago|{n} h ago {n} sa. önce+@plural {n} day ago|{n} days ago {n} gün önce+@msg Couldn't open {name}: {e} {name} açılamadı: {e}+@msg Download cancelled İndirme iptal edildi+@msg {name} updated to {version} {name}, {version} sürümüne güncellendi+@msg {name} installed: {version} {name} kuruldu: {version}+@msg {name} updated to {version} (this release publishes no checksum, so only its size was checked) {name}, {version} sürümüne güncellendi (bu sürüm sağlama toplamı yayımlamadığından yalnızca boyutu doğrulandı)+@msg {name} installed: {version} (this release publishes no checksum, so only its size was checked) {name} kuruldu: {version} (bu sürüm sağlama toplamı yayımlamadığından yalnızca boyutu doğrulandı)+@msg {name} was removed {name} kaldırıldı+@msg {name} is running. Quit it, then try again. {name} çalışıyor. Kapatıp tekrar deneyin.+@msg {name} was installed from the {repo} repository or the AUR ({pkg}). Update it with {cmd} or sudo pacman -Syu {name}, {repo} deposundan veya AUR'dan ({pkg}) kuruldu. {cmd} ya da sudo pacman -Syu ile güncelleyin+@msg {name} was installed from the {repo} repository or the AUR ({pkg}). Update it with your AUR helper (for example: yay -S {pkg}) or sudo pacman -Syu {name}, {repo} deposundan veya AUR'dan ({pkg}) kuruldu. AUR yardımcınızla (örneğin: yay -S {pkg}) ya da sudo pacman -Syu ile güncelleyin+@msg {name} was installed from the AUR ({pkg}). Update it with {cmd} {name}, AUR'dan ({pkg}) kuruldu. {cmd} ile güncelleyin+@msg {name} was installed from the AUR ({pkg}). Update it with your AUR helper (for example: yay -S {pkg}) {name}, AUR'dan ({pkg}) kuruldu. AUR yardımcınızla (örneğin: yay -S {pkg}) güncelleyin+@id app.install Yükle+@id app.update {v} sürümüne güncelle+@id app.open Aç+@id app.download {os} için indir+@id app.reveal Finder'da göster+@id app.reinstall Yeniden yükle+@id app.uninstall Kaldır…+@id app.notes Sürüm notları+@id app.website Web sitesi+@id app.github GitHub deposu+@id app.releases Tüm sürümler+@id launcher.update Güncelle ve yeniden başlat+@id launcher.download İndir+@id launcher.notes Yenilikler+@id launcher.dismiss Kapat+@id settings.open Ayarlar+@id settings.quit ArtCraft Launcher'dan çık+@id view.grid Izgara+@id view.table Tablo+@id filter.all Tümü+@id filter.installed Yüklü+@id filter.updates Güncellemeler+@id filter.notinstalled Yüklü değil+@id sort.suite Paket sırası+@id sort.name Ad+@id sort.inspired Esinlenme+@id sort.status Durum+@id sort.installed Yüklü sürüm+@id sort.latest En son sürüm+@id sort.released En yeni sürüm+@id help.discord Discord+@id help.github GitHub+@id help.website Web sitesi+@id update.check Güncellemeleri denetle+@id update.check_auto Güncellemeleri otomatik olarak denetle+@id update.notify Yüklü bir uygulamanın güncellemesi olduğunda bana bildir+@id update.prereleases Ön sürümleri (beta ve sürüm adayları) dahil et+@id linux.preferred_kind Yeni uygulamaları şu biçimde yükle:+@id tray.close_to_tray Pencere kapatıldığında sistem tepsisinde çalışmaya devam et+@id tray.show_on_current_desktop Pencereyi geçerli masaüstünde göster+@id tray.login_item Oturum açtığımda ArtCraft Launcher'ı başlat+@id appearance.theme Görünüm+ Show ArtCraft Launcher ArtCraft Launcher'ı Göster+ Check for Updates Güncellemeleri Denetle+ Visit getartcraft.com getartcraft.com adresini ziyaret edin+ ArtCraft on GitHub GitHub'da ArtCraft+ Join the ArtCraft Discord ArtCraft Discord'una Katılın+@plural ArtCraft Launcher · {n} update available|ArtCraft Launcher · {n} updates available ArtCraft Launcher · {n} güncelleme mevcut+ Install folder Kurulum klasörü+ Default install folder Varsayılan kurulum klasörü+ System default Sistem varsayılanı+ Browse… Gözat…+ Use default Varsayılanı kullan+ New installs use this folder. Updates stay in their current location. Yeni kurulumlar bu klasörü kullanır. Güncellemeler geçerli konumlarında kalır.+ Custom folders use AppImage on Linux. Özel klasörler Linux'ta AppImage kullanır.+ On Linux, custom folders use AppImage format. Linux'ta özel klasörler AppImage biçimini kullanır.+ The system manages install locations here. Sistem buradaki kurulum konumlarını yönetir.+@msg couldn't use install folder {path}: {reason} {path} kurulum klasörü kullanılamadı: {reason}+@msg this release has no AppImage for a custom install folder bu sürümde özel kurulum klasörü için bir AppImage yok+@msg custom install folders aren't supported on this system özel kurulum klasörleri bu sistemde desteklenmiyor+@msg {path} already exists and wasn't installed by ArtCraft Launcher {path} zaten mevcut ve ArtCraft Launcher tarafından kurulmamış+@msg couldn't move {path} to Trash ({reason}). Remove it in Finder instead. {path} Çöp Sepeti'ne taşınamadı ({reason}). Finder üzerinden kaldırın.+ Apps are placed inside this folder. Uygulamalar bu klasörün içine yerleştirilir.+ Replace what's there? Mevcut olanla değiştirilsin mi?+ {path} already exists. Installing {name} will overwrite it. {path} zaten mevcut. {name} uygulamasını yüklemek üzerine yazacaktır.+ Replace Değiştir+ Recently updated Son güncellenenler+ Name (A–Z) Ad (A–Z)+ Name (Z–A) Ad (Z–A)+ Frequently used Sık kullanılanlar+ Next app Sonraki uygulama+ Previous app Önceki uygulama+ Show {n} more changes {n} değişiklik daha göster+ Last updated: {date} Son güncelleme: {date}+column Version Sürümnew file mode 100644@@ -0,0 +1,129 @@+//! The Turkish UI, in its own test binary: the UI language is process-wide, so it can't share one+//! with the English UI tests. `ARTCRAFT_LAUNCHER_SNAPSHOTS=<dir>` also saves screenshots (run with+//! `-- --test-threads=1`, see `ui.rs`).++use std::cell::Cell;+use std::rc::Rc;++use artcraft_launcher_core::protocol::{Backend, Capabilities, Command, Event, JobPhase, LatestRelease, Origin, Source};+use artcraft_launcher_core::release::{Asset, Release};+use artcraft_launcher_core::status::InstallSource;+use artcraft_launcher_core::{Arch, Installed, Os, Platform, SUITE, version};+use artcraft_launcher_ui_egui::settings::ViewMode;+use artcraft_launcher_ui_egui::{Host, LauncherUi, Settings};+use egui_kittest::Harness;+use egui_kittest::kittest::Queryable;++const NOW: i64 = 1_791_500_000;++struct Fake {+ events: Vec<Event>,+ clock: Rc<Cell<i64>>,+}++impl Backend for Fake {+ fn send(&mut self, _command: Command) {}+ fn poll(&mut self) -> Vec<Event> {+ std::mem::take(&mut self.events)+ }+ fn capabilities(&self) -> Capabilities {+ Capabilities { manage_apps: true, reveal_label: "Show in Finder", self_update: true }+ }+ fn platform(&self) -> Option<Platform> {+ Some(Platform { os: Os::MacOs, arch: Arch::Arm64 })+ }+ fn now(&self) -> i64 {+ self.clock.get()+ }+}++struct NoHost;+impl Host for NoHost {}++fn release(id: &str, v: &str, at: i64) -> Release {+ let name = format!("{id}-{v}-macos-universal.dmg");+ Release {+ tag: format!("v{v}"),+ version: version::parse(v),+ name: format!("v{v}"),+ published_at: Some(at),+ html_url: format!("https://github.com/storytold/{id}/releases/tag/v{v}"),+ notes: String::new(),+ prerelease: false,+ assets: vec![Asset {+ name: name.clone(),+ size: 150 << 20,+ url: format!("https://github.com/storytold/{id}/releases/download/v{v}/{name}"),+ sha256: None,+ }],+ }+}++fn events() -> Vec<Event> {+ let mut ev = Vec::new();+ for (i, app) in SUITE.iter().enumerate() {+ let latest = LatestRelease::Found(release(app.id, "0.5.0", NOW - 40 * 86_400 - i as i64 * 600));+ ev.push(Event::Latest { app: app.id.into(), latest, from: Origin::ArtCraftApi });+ let installed = matches!(app.id, "photocraft" | "lightcraft").then(|| Installed {+ version: version::parse(if app.id == "photocraft" { "0.4.1" } else { "0.5.0" }),+ source: InstallSource::MacApp,+ location: format!("/Applications/{}.app", app.name),+ package: None,+ });+ ev.push(Event::Detected { app: app.id.into(), installed });+ }+ ev.push(Event::Progress { app: "filmcraft".into(), phase: JobPhase::Verifying });+ ev.push(Event::CheckFinished { at: NOW - 180, source: Source::Feed, rate_limited_until: None });+ // A backend message, translated through its `@msg` template where it's shown.+ ev.push(Event::JobFinished { app: "lightcraft".into(), result: Ok("LightCraft updated to 0.5.0".into()) });+ ev+}++fn harness(view: ViewMode) -> Harness<'static, Option<LauncherUi>> {+ artcraft_launcher_ui_egui::i18n::set_test_lang(artcraft_launcher_ui_egui::i18n::Lang::EN);+ let mut backend = Some(Fake { events: events(), clock: Rc::new(Cell::new(NOW)) });+ let settings =+ Settings { view, notify: false, language: "tr".into(), theme: artcraft_launcher_ui_egui::theme::ThemeChoice::Dark, ..Settings::default() };+ Harness::builder().with_size(egui::vec2(1180.0, 900.0)).with_theme(egui::Theme::Dark).build_ui_state(+ move |ui, state: &mut Option<LauncherUi>| {+ if state.is_none()+ && let Some(b) = backend.take()+ {+ *state = Some(LauncherUi::new(ui.ctx(), Box::new(b), settings.clone()));+ }+ if let Some(l) = state.as_mut() {+ l.logic(&ui.ctx().clone(), &mut NoHost);+ l.ui(ui, &mut NoHost);+ }+ },+ None,+ )+}++fn snapshot(h: &mut Harness<'_, Option<LauncherUi>>, name: &str) {+ let Some(dir) = std::env::var_os("ARTCRAFT_LAUNCHER_SNAPSHOTS") else { return };+ let img = h.render().unwrap();+ img.save(std::path::Path::new(&dir).join(format!("{name}.png"))).unwrap();+}++// One test: the UI language is process-wide.+#[test]+fn turkish_ui_translates_labels_dates_and_messages() {+ let mut h = harness(ViewMode::Grid);+ h.run_steps(8);+ snapshot(&mut h, "grid-tr-dark");+ // Product names stay in English.+ assert!(h.query_by_label("Launcher").is_none());+ h.get_by_label("Craft App Suite");+ h.get_by_label("Görsel düzenleme");+ h.get_by_label("0.5.0 sürümüne güncelle");+ h.get_by_label_contains("Sağlama toplamı doğrulanıyor…");+ h.get_by_label_contains("3 dk. önce denetlendi · ArtCraft API kullanılarak");+ h.get_by_label("LightCraft, 0.5.0 sürümüne güncellendi");++ let mut table = harness(ViewMode::Table);+ table.run_steps(8);+ snapshot(&mut table, "table-tr-dark");+ table.get_by_label("Yüklü");+ assert!(table.query_all_by_label_contains("Ağu 2026").count() >= 1);+}