feat(i18n): add Turkish (tr) locale support

Add complete Turkish translation across all 7 i18n namespaces:
- common: actions, playback controls, locale metadata
- launch: HUD tooltips, audio/webcam controls, source selector
- editor: error messages, export, project, recording permissions
- dialogs: export progress, trim tutorial, unsaved changes, file dialogs
- settings: all panels (zoom, speed, trim, layout, effects, background,
  crop, export, annotations, custom fonts, language, audio)
- shortcuts: keyboard shortcuts panel and all actions
- timeline: toolbar buttons, hints, labels, errors, success messages

Also adds "tr" to SUPPORTED_LOCALES config and i18n validation script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nadir A.
2026-04-07 03:05:21 +03:00
parent 24928164ca
commit c36349d950
9 changed files with 438 additions and 2 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ import path from "node:path";
const LOCALES_DIR = path.resolve("src/i18n/locales");
const BASE_LOCALE = "en";
const COMPARE_LOCALES = ["zh-CN", "es"];
const COMPARE_LOCALES = ["zh-CN", "es", "tr"];
function getKeys(obj, prefix = "") {
const keys = [];
+1 -1
View File
@@ -1,5 +1,5 @@
export const DEFAULT_LOCALE = "en" as const;
export const SUPPORTED_LOCALES = ["en", "zh-CN", "es"] as const;
export const SUPPORTED_LOCALES = ["en", "zh-CN", "es", "tr"] as const;
export const I18N_NAMESPACES = [
"common",
"dialogs",
+29
View File
@@ -0,0 +1,29 @@
{
"actions": {
"cancel": "İptal",
"save": "Kaydet",
"delete": "Sil",
"close": "Kapat",
"share": "Paylaş",
"done": "Tamam",
"open": "Aç",
"upload": "Yükle",
"export": "Dışa Aktar",
"file": "Dosya",
"edit": "Düzenle",
"view": "Görünüm",
"window": "Pencere",
"quit": "Çıkış",
"stopRecording": "Kaydı Durdur"
},
"playback": {
"play": "Oynat",
"pause": "Duraklat",
"fullscreen": "Tam Ekran",
"exitFullscreen": "Tam Ekrandan Çık"
},
"locale": {
"name": "Türkçe",
"short": "TR"
}
}
+68
View File
@@ -0,0 +1,68 @@
{
"export": {
"complete": "Dışa Aktarım Tamamlandı",
"yourFormatReady": "{{format}} dosyanız hazır",
"showInFolder": "Klasörde Göster",
"finalizingVideo": "Video dışa aktarımı sonlandırılıyor...",
"compilingGifProgress": "GIF derleniyor... %{{progress}}",
"compilingGifWait": "GIF derleniyor... Bu biraz zaman alabilir",
"takeMoment": "Bu biraz zaman alabilir...",
"failed": "Dışa Aktarım Başarısız",
"tryAgain": "Lütfen tekrar deneyin",
"finalizingVideoTitle": "Video Sonlandırılıyor",
"compilingGif": "GIF Derleniyor",
"exportingFormat": "{{format}} Dışa Aktarılıyor",
"compiling": "Derleniyor",
"renderingFrames": "Kareler İşleniyor",
"processing": "İşleniyor...",
"finalizing": "Sonlandırılıyor...",
"compilingStatus": "Derleniyor...",
"status": "Durum",
"format": "Biçim",
"frames": "Kareler",
"cancelExport": "Dışa Aktarımı İptal Et",
"savedSuccessfully": "{{format}} başarıyla kaydedildi!"
},
"tutorial": {
"triggerLabel": "Kırpma nasıl çalışır",
"title": "Kırpma Nasıl Çalışır",
"description": "Videonuzun istenmeyen bölümlerini nasıl keseceğinizi anlayın.",
"explanation": "Kırpma aracı, kaldırmak istediğiniz bölümleri tanımlayarak çalışır.",
"explanationRemove": "kaldırmak",
"explanationCovered": "kaplanan",
"explanationEnd": "kırmızı kırpma bölgesi ile işaretlenen kısımlar dışa aktarımda kesilecektir.",
"visualExample": "Görsel Örnek",
"removed": "KALDIRILDI",
"kept": "Korundu",
"part1": "Bölüm 1",
"part2": "Bölüm 2",
"part3": "Bölüm 3",
"finalVideo": "Son Video",
"step1Title": "1. Kırpma Ekle",
"step1Description": "Kaldırılacak bölümü işaretlemek için T tuşuna basın veya makas simgesine tıklayın.",
"step2Title": "2. Ayarla",
"step2Description": "Kesmek istediğiniz kısmı tam olarak kaplamak için kırmızı bölgenin kenarlarını sürükleyin."
},
"unsavedChanges": {
"title": "Kaydedilmemiş Değişiklikler",
"message": "Kaydedilmemiş değişiklikleriniz var.",
"detail": "Kapatmadan önce projenizi kaydetmek ister misiniz?",
"saveAndClose": "Kaydet ve Kapat",
"discardAndClose": "Kaydetmeden Kapat",
"loadProject": "Proje Yükle…",
"saveProject": "Proje Kaydet…",
"saveProjectAs": "Farklı Kaydet…"
},
"fileDialogs": {
"saveGif": "Dışa Aktarılan GIF'i Kaydet",
"saveVideo": "Dışa Aktarılan Videoyu Kaydet",
"selectVideo": "Video Dosyası Seç",
"saveProject": "OpenScreen Projesini Kaydet",
"openProject": "OpenScreen Projesini Aç",
"gifImage": "GIF Görüntüsü",
"mp4Video": "MP4 Video",
"videoFiles": "Video Dosyaları",
"openscreenProject": "OpenScreen Projesi",
"allFiles": "Tüm Dosyalar"
}
}
+35
View File
@@ -0,0 +1,35 @@
{
"errors": {
"noVideoLoaded": "Video yüklenmedi",
"videoNotReady": "Video hazır değil",
"unableToDetermineSourcePath": "Kaynak video yolu belirlenemiyor",
"failedToSaveGif": "GIF kaydedilemedi",
"gifExportFailed": "GIF dışa aktarımı başarısız oldu",
"failedToSaveVideo": "Video kaydedilemedi",
"exportFailed": "Dışa aktarım başarısız oldu",
"exportFailedWithError": "Dışa aktarım başarısız: {{error}}",
"failedToSaveExport": "Dışa aktarım kaydedilemedi",
"failedToSaveExportedVideo": "Dışa aktarılan video kaydedilemedi",
"failedToRevealInFolder": "Klasörde gösterme hatası: {{error}}"
},
"export": {
"canceled": "Dışa aktarım iptal edildi",
"exportedSuccessfully": "{{format}} başarıyla dışa aktarıldı"
},
"project": {
"saveCanceled": "Proje kaydetme iptal edildi",
"failedToSave": "Proje kaydedilemedi",
"savedTo": "Proje şuraya kaydedildi: {{path}}",
"failedToLoad": "Proje yüklenemedi",
"invalidFormat": "Geçersiz proje dosyası biçimi",
"loadedFrom": "Proje şuradan yüklendi: {{path}}"
},
"recording": {
"failedCameraAccess": "Kamera erişimi istenemedi.",
"cameraBlocked": "Kamera erişimi engellendi. Kamerayı kullanmak için sistem ayarlarından izin verin.",
"systemAudioUnavailable": "Sistem sesi kullanılamıyor. Sistem sesi olmadan kaydediliyor.",
"microphoneDenied": "Mikrofon erişimi reddedildi. Kayıt ses olmadan devam edecek.",
"cameraDenied": "Kamera erişimi reddedildi. Kayıt kamera olmadan devam edecek.",
"permissionDenied": "Kayıt izni reddedildi. Lütfen ekran kaydına izin verin."
}
}
+48
View File
@@ -0,0 +1,48 @@
{
"tooltips": {
"hideHUD": "Kontrol panelini gizle",
"closeApp": "Uygulamayı kapat",
"restartRecording": "Kaydı yeniden başlat",
"cancelRecording": "Kaydı iptal et",
"pauseRecording": "Kaydı duraklat",
"resumeRecording": "Kayda devam et",
"openVideoFile": "Video dosyası aç",
"openProject": "Proje aç"
},
"audio": {
"enableSystemAudio": "Sistem sesini etkinleştir",
"disableSystemAudio": "Sistem sesini devre dışı bırak",
"enableMicrophone": "Mikrofonu etkinleştir",
"disableMicrophone": "Mikrofonu devre dışı bırak",
"defaultMicrophone": "Varsayılan Mikrofon",
"enableNoiseReduction": "Gürültü azaltmayı etkinleştir (yapay zeka destekli)",
"disableNoiseReduction": "Gürültü azaltmayı devre dışı bırak",
"noiseReduction": "Gürültü azaltma",
"clickToCycle": "Seviye değiştirmek için tıklayın",
"nrLevel": {
"light": "Hafif",
"moderate": "Orta",
"aggressive": "Güçlü"
},
"noiseReductionPrompt": "Daha net ses için yapay zeka destekli gürültü azaltmayı etkinleştirmek ister misiniz?",
"enableNoiseReductionShort": "Etkinleştir"
},
"webcam": {
"enableWebcam": "Kamerayı etkinleştir",
"disableWebcam": "Kamerayı devre dışı bırak",
"defaultCamera": "Varsayılan Kamera",
"searching": "Aranıyor...",
"noneFound": "Kamera bulunamadı",
"unavailable": "Kamera kullanılamıyor"
},
"sourceSelector": {
"loading": "Kaynaklar yükleniyor...",
"screens": "Ekranlar ({{count}})",
"windows": "Pencereler ({{count}})",
"defaultSourceName": "Ekran"
},
"recording": {
"selectSource": "Lütfen kayıt için bir kaynak seçin"
},
"language": "Dil"
}
+170
View File
@@ -0,0 +1,170 @@
{
"zoom": {
"level": "Yakınlaştırma Seviyesi",
"selectRegion": "Ayarlamak için bir yakınlaştırma bölgesi seçin",
"deleteZoom": "Yakınlaştırmayı Sil",
"focusMode": {
"title": "Odak Modu",
"manual": "Manuel",
"auto": "Otomatik",
"autoDescription": "Kamera kaydedilen imleç konumunu takip eder"
}
},
"speed": {
"playbackSpeed": "Oynatma Hızı",
"selectRegion": "Ayarlamak için bir hız bölgesi seçin",
"deleteRegion": "Hız Bölgesini Sil"
},
"trim": {
"deleteRegion": "Kırpma Bölgesini Sil"
},
"layout": {
"title": "Düzen",
"preset": "Ön Ayar",
"selectPreset": "Ön ayar seçin",
"pictureInPicture": "Resim İçinde Resim",
"verticalStack": "Dikey Yığın",
"webcamShape": "Kamera Şekli"
},
"effects": {
"title": "Video Efektleri",
"blurBg": "Arka Planı Bulanıklaştır",
"motionBlur": "Hareket Bulanıklığı",
"off": "kapalı",
"shadow": "Gölge",
"roundness": "Yuvarlaklık",
"padding": "Dolgu"
},
"background": {
"title": "Arka Plan",
"image": "Görüntü",
"color": "Renk",
"gradient": "Gradyan",
"uploadCustom": "Özel Yükle",
"gradientLabel": "Gradyan {{index}}"
},
"crop": {
"title": "Kırpma",
"cropVideo": "Videoyu Kırp",
"dragInstruction": "Kırpma alanını ayarlamak için her kenarı sürükleyin",
"ratio": "Oran",
"free": "Serbest",
"done": "Tamam",
"lockAspectRatio": "En boy oranını kilitle",
"unlockAspectRatio": "En boy oranının kilidini aç"
},
"exportFormat": {
"mp4": "MP4",
"gif": "GIF",
"mp4Video": "MP4 Video",
"mp4Description": "Yüksek kaliteli video dosyası",
"gifAnimation": "GIF Animasyon",
"gifDescription": "Paylaşım için hareketli görüntü"
},
"exportQuality": {
"title": "Dışa Aktarım Kalitesi",
"low": "Düşük",
"medium": "Orta",
"high": "Yüksek"
},
"gifSettings": {
"frameRate": "GIF Kare Hızı",
"size": "GIF Boyutu",
"loop": "GIF Döngüsü"
},
"project": {
"save": "Projeyi Kaydet",
"load": "Proje Yükle"
},
"export": {
"videoButton": "Videoyu Dışa Aktar",
"gifButton": "GIF Olarak Dışa Aktar",
"chooseSaveLocation": "Kayıt Konumu Seç"
},
"links": {
"reportBug": "Hata Bildir",
"starOnGithub": "GitHub'da Yıldızla"
},
"imageUpload": {
"invalidFileType": "Geçersiz dosya türü",
"jpgOnly": "Lütfen bir JPG veya JPEG görüntü dosyası yükleyin.",
"uploadSuccess": "Özel görüntü başarıyla yüklendi!",
"failedToUpload": "Görüntü yüklenemedi",
"errorReading": "Dosya okunurken bir hata oluştu."
},
"annotation": {
"title": "Açıklama Ayarları",
"active": "Aktif",
"typeText": "Metin",
"typeImage": "Görüntü",
"typeArrow": "Ok",
"textContent": "Metin İçeriği",
"textPlaceholder": "Metninizi girin...",
"fontStyle": "Yazı Tipi Stili",
"selectStyle": "Stil seçin",
"size": "Boyut",
"customFonts": "Özel Yazı Tipleri",
"textColor": "Metin Rengi",
"background": "Arka Plan",
"none": "Yok",
"color": "Renk",
"clearBackground": "Arka Planı Temizle",
"uploadImage": "Görüntü Yükle",
"supportedFormats": "Desteklenen biçimler: JPG, PNG, GIF, WebP",
"arrowDirection": "Ok Yönü",
"strokeWidth": "Çizgi Kalınlığı: {{width}}px",
"arrowColor": "Ok Rengi",
"deleteAnnotation": "Açıklamayı Sil",
"shortcutsAndTips": "Kısayollar ve İpuçları",
"tipMovePlayhead": "Oynatma imlecini çakışan açıklama bölümüne taşıyın ve bir öğe seçin.",
"tipTabCycle": "Çakışan öğeler arasında geçiş yapmak için Tab tuşunu kullanın.",
"tipShiftTabCycle": "Geriye doğru geçiş yapmak için Shift+Tab kullanın.",
"invalidImageType": "Geçersiz dosya türü",
"imageFormatsOnly": "Lütfen bir JPG, PNG, GIF veya WebP görüntü dosyası yükleyin.",
"imageUploadSuccess": "Görüntü başarıyla yüklendi!",
"failedImageUpload": "Görüntü yüklenemedi"
},
"fontStyles": {
"classic": "Klasik",
"editor": "Editör",
"strong": "Kalın",
"typewriter": "Daktilo",
"deco": "Dekoratif",
"simple": "Sade",
"modern": "Modern",
"clean": "Temiz"
},
"customFont": {
"dialogTitle": "Google Yazı Tipi Ekle",
"urlLabel": "Google Fonts İçe Aktarım URL'si",
"urlPlaceholder": "https://fonts.googleapis.com/css2?family=Roboto&display=swap",
"urlHelp": "Google Fonts'tan alabilirsiniz: Bir yazı tipi seçin → \"Get font\"a tıklayın → @import URL'sini kopyalayın",
"nameLabel": "Görünen Ad",
"namePlaceholder": "Özel Yazı Tipim",
"nameHelp": "Yazı tipinin seçicide nasıl görüneceğini belirler",
"addButton": "Yazı Tipi Ekle",
"addingButton": "Ekleniyor...",
"errorEmptyUrl": "Lütfen bir Google Fonts içe aktarım URL'si girin",
"errorInvalidUrl": "Lütfen geçerli bir Google Fonts URL'si girin",
"errorEmptyName": "Lütfen bir yazı tipi adı girin",
"errorExtractFailed": "URL'den yazı tipi ailesi çıkarılamadı",
"successMessage": "\"{{fontName}}\" yazı tipi başarıyla eklendi",
"failedToAdd": "Yazı tipi eklenemedi",
"errorTimeout": "Yazı tipinin yüklenmesi çok uzun sürdü. Lütfen URL'yi kontrol edip tekrar deneyin.",
"errorLoadFailed": "Yazı tipi yüklenemedi. Lütfen Google Fonts URL'sinin doğruluğunu kontrol edin."
},
"language": {
"title": "Dil"
},
"audio": {
"title": "Ses",
"noiseReduction": "Gürültü Azaltma",
"level": "Seviye",
"nrLevel": {
"light": "Hafif",
"moderate": "Orta",
"aggressive": "Güçlü"
},
"nrDescription": "Yapay zeka destekli gürültü azaltma arka plan gürültüsünü temizler. Daha yüksek seviyeler daha agresiftir ancak ses kalitesini etkileyebilir."
}
}
+36
View File
@@ -0,0 +1,36 @@
{
"title": "Klavye Kısayolları",
"customize": "Özelleştir",
"configurable": "Yapılandırılabilir",
"fixed": "Sabit",
"pressKey": "Bir tuşa basın…",
"clickToChange": "Değiştirmek için tıklayın",
"pressEscToCancel": "İptal etmek için Esc tuşuna basın",
"helpText": "Bir kısayola tıklayın, ardından yeni tuş kombinasyonuna basın. İptal etmek için Esc tuşuna basın.",
"resetToDefaults": "Varsayılanlara sıfırla",
"alreadyUsedBy": "\"{{action}}\" tarafından zaten kullanılıyor",
"swap": "Değiştir",
"reservedShortcut": "Bu kısayol \"{{label}}\" için ayrılmıştır ve yeniden atanamaz.",
"savedToast": "Klavye kısayolları kaydedildi",
"resetToast": "Varsayılan kısayollara sıfırlandı — uygulamak için Kaydet'e tıklayın",
"actions": {
"addZoom": "Yakınlaştırma Ekle",
"addTrim": "Kırpma Ekle",
"addSpeed": "Hız Ekle",
"addAnnotation": "Açıklama Ekle",
"addKeyframe": "Anahtar Kare Ekle",
"deleteSelected": "Seçileni Sil",
"playPause": "Oynat / Duraklat"
},
"fixedActions": {
"undo": "Geri Al",
"redo": "Yinele",
"cycleAnnotationsForward": "Açıklamalar Arasında İleri Geç",
"cycleAnnotationsBackward": "Açıklamalar Arasında Geri Geç",
"deleteSelectedAlt": "Seçileni Sil (alternatif)",
"panTimeline": "Zaman Çizelgesini Kaydır",
"zoomTimeline": "Zaman Çizelgesini Yakınlaştır",
"frameBack": "Önceki Kare",
"frameForward": "Sonraki Kare"
}
}
+50
View File
@@ -0,0 +1,50 @@
{
"buttons": {
"addZoom": "Yakınlaştırma Ekle (Z)",
"suggestZooms": "İmleçten Yakınlaştırma Öner",
"addTrim": "Kırpma Ekle (T)",
"addAnnotation": "Açıklama Ekle (A)",
"addSpeed": "Hız Ekle (S)"
},
"hints": {
"pressZoom": "Yakınlaştırma eklemek için Z tuşuna basın",
"pressTrim": "Kırpma eklemek için T tuşuna basın",
"pressAnnotation": "Açıklama eklemek için A tuşuna basın",
"pressSpeed": "Hız eklemek için S tuşuna basın"
},
"labels": {
"pan": "Kaydır",
"zoom": "Yakınlaştır",
"zoomItem": "Yakınlaştırma {{index}}",
"trimItem": "Kırpma {{index}}",
"speedItem": "Hız {{index}}",
"annotationItem": "Açıklama",
"imageItem": "Görüntü",
"emptyText": "Boş metin"
},
"emptyState": {
"noVideo": "Video Yüklenmedi",
"dragAndDrop": "Düzenlemeye başlamak için bir video sürükleyip bırakın"
},
"errors": {
"cannotPlaceZoom": "Buraya yakınlaştırma yerleştirilemiyor",
"zoomExistsAtLocation": "Bu konumda zaten bir yakınlaştırma var veya yeterli alan yok.",
"zoomSuggestionUnavailable": "Yakınlaştırma öneri işleyicisi kullanılamıyor",
"noCursorTelemetry": "İmleç telemetrisi mevcut değil",
"noCursorTelemetryDescription": "İmleç tabanlı öneriler oluşturmak için önce bir ekran kaydı yapın.",
"noUsableTelemetry": "Kullanılabilir imleç telemetrisi yok",
"noUsableTelemetryDescription": "Kayıt yeterli imleç hareketi verisi içermiyor.",
"noDwellMoments": "Belirgin imleç bekleme anları bulunamadı",
"noDwellMomentsDescription": "Önemli işlemlerde daha yavaş imleç duraklamaları olan bir kayıt deneyin.",
"noAutoZoomSlots": "Otomatik yakınlaştırma alanı yok",
"noAutoZoomSlotsDescription": "Algılanan bekleme noktaları mevcut yakınlaştırma bölgeleriyle çakışıyor.",
"cannotPlaceTrim": "Buraya kırpma yerleştirilemiyor",
"trimExistsAtLocation": "Bu konumda zaten bir kırpma var veya yeterli alan yok.",
"cannotPlaceSpeed": "Buraya hız yerleştirilemiyor",
"speedExistsAtLocation": "Bu konumda zaten bir hız bölgesi var veya yeterli alan yok."
},
"success": {
"addedZoomSuggestions": "{{count}} imleç tabanlı yakınlaştırma önerisi eklendi",
"addedZoomSuggestionsPlural": "{{count}} imleç tabanlı yakınlaştırma önerisi eklendi"
}
}