{subscriptions.isLoading ? (
) : (
diff --git a/apps/renderer/src/pages/(external)/invitation.tsx b/apps/renderer/src/pages/(external)/invitation.tsx
index 1122941ceb..84cf6e4cce 100644
--- a/apps/renderer/src/pages/(external)/invitation.tsx
+++ b/apps/renderer/src/pages/(external)/invitation.tsx
@@ -24,6 +24,7 @@ import { Input } from "~/components/ui/input"
import { Tooltip, TooltipContent, TooltipTrigger } from "~/components/ui/tooltip"
import { SocialMediaLinks } from "~/constants/social"
import { useSignOut } from "~/hooks/biz/useSignOut"
+import { tipcClient } from "~/lib/client"
import { getFetchErrorMessage } from "~/lib/error-parser"
import confettiUrl from "~/lottie/confetti.lottie?url"
import { useInvitationMutation } from "~/queries/invitations"
@@ -139,8 +140,13 @@ export function Component() {
variant="ghost"
type="button"
onClick={() => {
- signOut()
- window.location.href = "/"
+ if (window.electron) {
+ tipcClient?.clearAllData().then(() => {
+ window.location.href = "/"
+ })
+ } else {
+ signOut()
+ }
}}
>
diff --git a/apps/renderer/src/providers/root-providers.tsx b/apps/renderer/src/providers/root-providers.tsx
index c14d309e2c..16715f979b 100644
--- a/apps/renderer/src/providers/root-providers.tsx
+++ b/apps/renderer/src/providers/root-providers.tsx
@@ -5,6 +5,7 @@ import { Provider } from "jotai"
import type { FC, PropsWithChildren } from "react"
import { HotkeysProvider } from "react-hotkeys-hook"
+import { LottieRenderContainer } from "~/components/ui/lottie-container"
import { ModalStackProvider } from "~/components/ui/modal"
import { Toaster } from "~/components/ui/sonner"
import { HotKeyScopeMap } from "~/constants"
@@ -39,6 +40,7 @@ export const RootProviders: FC
= ({ children }) => (
+
{import.meta.env.DEV && }
diff --git a/locales/app/ar-iq.json b/locales/app/ar-IQ.json
similarity index 100%
rename from locales/app/ar-iq.json
rename to locales/app/ar-IQ.json
diff --git a/locales/app/ar-kw.json b/locales/app/ar-KW.json
similarity index 100%
rename from locales/app/ar-kw.json
rename to locales/app/ar-KW.json
diff --git a/locales/app/ar-tn.json b/locales/app/ar-TN.json
similarity index 100%
rename from locales/app/ar-tn.json
rename to locales/app/ar-TN.json
diff --git a/locales/app/tr.json b/locales/app/tr.json
new file mode 100644
index 0000000000..fca76847ed
--- /dev/null
+++ b/locales/app/tr.json
@@ -0,0 +1,244 @@
+{
+ "achievement.all_done": "Tüm tamamlandı!",
+ "achievement.first_claim_feed": "Besleme Sahibi",
+ "achievement.first_claim_feed_description": "Follow'da beslemenizi sahibi olun.",
+ "achievement.mint_more_power": "Sert çalışan bir oyuncu olun ve daha fazla kazanın.",
+ "ai_daily.title": "Öne Çıkan Haberler - {{title}}",
+ "ai_daily.tooltip.content": "Burada, zaman çizelgenizden ( - ) AI tarafından seçilen ve sizin için önemli olabilecek haberler bulunmaktadır.",
+ "ai_daily.tooltip.update_schedule": "Her gün saat 08:00 ve 20:00'de güncellenir.",
+ "app.copy_logo_svg": "Logo SVG'sini Kopyala",
+ "app.toggle_sidebar": "Kenar Çubuğunu Aç/Kapat",
+ "discover.any_url_or_keyword": "Herhangi bir URL veya Anahtar Kelime",
+ "discover.default_option": " (varsayılan)",
+ "discover.feed_description": "Bu beslemesinin açıklaması aşağıdaki gibidir ve ilgili bilgilerle parametre formunu doldurabilirsiniz.",
+ "discover.feed_maintainers": "Bu besleme RSSHub tarafından sağlanmaktadır, katkılarıyla",
+ "discover.import.click_to_upload": "OPML dosyasını yüklemek için tıklayın",
+ "discover.import.conflictItems": "Çakışan Öğeler",
+ "discover.import.noItems": "Öğe yok",
+ "discover.import.opml": "OPML dosyası",
+ "discover.import.parsedErrorItems": "Ayrıştırma Hatası Olan Öğeler",
+ "discover.import.result": " besleme başarıyla içe aktarıldı, zaten aboneliğiniz vardı ve içe aktarılamadı.",
+ "discover.import.successfulItems": "Başarılı Öğeler",
+ "discover.popular": "Popüler",
+ "discover.preview": "Önizleme",
+ "discover.rss_hub_route": "RSSHub Rotası",
+ "discover.rss_url": "RSS URL'si",
+ "discover.select_placeholder": "Seçin",
+ "discover.target.feeds": "Beslemeler",
+ "discover.target.label": "Arama hedefi",
+ "discover.target.lists": "Listeler",
+ "early_access": "Erken Erişim",
+ "entry_actions.copy_link": "Bağlantıyı kopyala",
+ "entry_actions.failed_to_save_to_eagle": "Eagle'a kaydetme başarısız oldu.",
+ "entry_actions.failed_to_save_to_instapaper": "Instapaper'a kaydetme başarısız oldu.",
+ "entry_actions.failed_to_save_to_readwise": "Readwise'a kaydetme başarısız oldu.",
+ "entry_actions.link_copied": "Bağlantı panoya kopyalandı.",
+ "entry_actions.mark_as_read": "Okundu olarak işaretle",
+ "entry_actions.mark_as_unread": "Okunmadı olarak işaretle",
+ "entry_actions.open_in_browser": "Tarayıcıda aç",
+ "entry_actions.save_media_to_eagle": "Medyayı Eagle'a kaydet",
+ "entry_actions.save_to_instapaper": "Instapaper'a kaydet",
+ "entry_actions.save_to_readwise": "Readwise'a kaydet",
+ "entry_actions.saved_to_eagle": "Eagle'a kaydedildi.",
+ "entry_actions.saved_to_instapaper": "Instapaper'a kaydedildi.",
+ "entry_actions.saved_to_readwise": "Readwise'a kaydedildi.",
+ "entry_actions.share": "Paylaş",
+ "entry_actions.star": "Yıldızla",
+ "entry_actions.starred": "Yıldızlandı.",
+ "entry_actions.tip": "Bahşiş",
+ "entry_actions.unstar": "Yıldızı kaldır",
+ "entry_actions.unstarred": "Yıldız kaldırıldı.",
+ "entry_column.filtered_content_tip": "Filtrelenmiş içeriğiniz gizlendi.",
+ "entry_column.filtered_content_tip_2": "Yukarıda gösterilen girişlere ek olarak, filtrelenmiş içerik de bulunmaktadır.",
+ "entry_column.refreshing": "Yeni girişler yenileniyor...",
+ "entry_content.ai_summary": "AI özeti",
+ "entry_content.fetching_content": "Orijinal içerik alınıyor ve işleniyor...",
+ "entry_content.header.play_tts": "TTS'i Oynat",
+ "entry_content.header.readability": "Okunabilirlik",
+ "entry_content.no_content": "Medya mevcut değil",
+ "entry_content.readability_notice": "Bu içerik Okunabilirlik tarafından sağlanmaktadır. Tipografik anomaliler bulursanız, lütfen orijinal içeriği görmek için kaynak siteye gidin.",
+ "entry_content.render_error": "Oluşturma hatası:",
+ "entry_content.report_issue": "Sorun bildir",
+ "entry_content.support_amount": "{{amount}} kişi bu beslemesinin yaratıcısını destekledi.",
+ "entry_content.support_creator": "Yaratıcıyı Destekle",
+ "entry_content.web_app_notice": "Web uygulaması bu içerik türünü desteklemiyor olabilir. Ancak masaüstü uygulamasını indirebilirsiniz.",
+ "entry_list.zero_unread": "Okunmamış Yok",
+ "entry_list_header.daily_report": "Günlük Rapor",
+ "entry_list_header.hide_no_image_items": "Resimsiz girişleri gizle.",
+ "entry_list_header.items": "öğe",
+ "entry_list_header.new_entries_available": "Yeni girişler mevcut",
+ "entry_list_header.refetch": "Yeniden getir",
+ "entry_list_header.refresh": "Yenile",
+ "entry_list_header.show_all": "Tümünü göster",
+ "entry_list_header.show_all_items": "Tüm giriş öğelerini göster",
+ "entry_list_header.show_unread_only": "Sadece okunmamışları göster",
+ "entry_list_header.switch_to_grid": "Izgara görünümüne geç",
+ "entry_list_header.switch_to_masonry": "Masonry görünümüne geç",
+ "entry_list_header.unread": "okunmamış",
+ "feed_claim_modal.choose_verification_method": "Doğrulama için üç yöntem arasından seçim yapabilirsiniz.",
+ "feed_claim_modal.claim_button": "Talep Et",
+ "feed_claim_modal.content_instructions": "Aşağıdaki içeriği kopyalayın ve en son RSS beslemesine gönderin.",
+ "feed_claim_modal.description_current": "Mevcut açıklama:",
+ "feed_claim_modal.description_instructions": "Aşağıdaki içeriği kopyalayın ve RSS beslemesinin
alanına yapıştırın.",
+ "feed_claim_modal.failed_to_load": "Talep mesajı yüklenemedi",
+ "feed_claim_modal.rss_format_choice": "RSS oluşturucuları genellikle iki format sunar. Lütfen ihtiyacınıza göre aşağıdaki XML ve JSON formatlarını kopyalayın.",
+ "feed_claim_modal.rss_instructions": "Aşağıdaki kodu kopyalayın ve RSS oluşturucunuza yapıştırın.",
+ "feed_claim_modal.rss_json_format": "JSON Formatı",
+ "feed_claim_modal.rss_xml_format": "XML Formatı",
+ "feed_claim_modal.rsshub_notice": "Bu besleme, 1 saatlik önbellek süresiyle RSSHub tarafından sağlanmaktadır. İçerik yayınlandıktan sonra değişikliklerin görünmesi 1 saate kadar sürebilir.",
+ "feed_claim_modal.tab_content": "İçerik",
+ "feed_claim_modal.tab_description": "Açıklama",
+ "feed_claim_modal.tab_rss": "RSS Etiketi",
+ "feed_claim_modal.title": "Besleme Talep",
+ "feed_claim_modal.verify_ownership": "Bu beslemeyi kendinize ait olarak talep etmek için sahipliğinizi doğrulamanız gerekiyor.",
+ "feed_form.add_follow": "Takip ekle",
+ "feed_form.category": "Kategori",
+ "feed_form.category_description": "Varsayılan olarak, takipleriniz web sitesine göre gruplandırılacaktır.",
+ "feed_form.error_fetching_feed": "Besleme getirilirken hata oluştu.",
+ "feed_form.fee": "Takip ücreti",
+ "feed_form.fee_description": "Bu listenin takip edilmesi için listenin sahibine bir ücret ödenmelidir.",
+ "feed_form.feed_not_found": "Besleme bulunamadı.",
+ "feed_form.feedback": "Geri bildirim",
+ "feed_form.follow": "Takip et",
+ "feed_form.follow_with_fee": "{{fee}} Güç ile takip et",
+ "feed_form.followed": "🎉 Takip edildi.",
+ "feed_form.private_follow": "Özel Takip",
+ "feed_form.private_follow_description": "Bu takibin profil sayfanızda herkese açık olarak görünüp görünmeyeceği.",
+ "feed_form.retry": "Yeniden dene",
+ "feed_form.title": "Başlık",
+ "feed_form.title_description": "Bu Besleme için özel başlık. Varsayılanı kullanmak için boş bırakın.",
+ "feed_form.unfollow": "Takibi bırak",
+ "feed_form.update": "Güncelle",
+ "feed_form.update_follow": "Takibi güncelle",
+ "feed_form.updated": "🎉 Güncellendi.",
+ "feed_form.view": "Görüntüle",
+ "feed_item.claimed_by_owner": "Bu besleme şu kişi tarafından talep edildi:",
+ "feed_item.claimed_by_unknown": "sahibi.",
+ "feed_item.claimed_by_you": "Sizin tarafınızdan talep edildi",
+ "feed_item.claimed_feed": "Talep Edilen Besleme",
+ "feed_item.error_since": "Hata başlangıcı",
+ "feed_item.not_publicly_visible": "Profil sayfanızda herkese açık olarak görünmüyor",
+ "feed_view_type.articles": "Makaleler",
+ "feed_view_type.audios": "Sesler",
+ "feed_view_type.notifications": "Bildirimler",
+ "feed_view_type.pictures": "Resimler",
+ "feed_view_type.social_media": "Sosyal Medya",
+ "feed_view_type.videos": "Videolar",
+ "mark_all_read_button.auto_confirm_info": "3 saniye sonra otomatik olarak onaylanacak.",
+ "mark_all_read_button.confirm": "Onayla",
+ "mark_all_read_button.confirm_mark_all": "{{which}} okundu olarak işaretlensin mi?",
+ "mark_all_read_button.confirm_mark_all_info": "Tümünü okundu olarak işaretlemeyi onaylıyor musunuz?",
+ "mark_all_read_button.mark_all_as_read": "Tümünü okundu olarak işaretle",
+ "mark_all_read_button.mark_as_read": "{{which}} okundu olarak işaretle",
+ "mark_all_read_button.undo": "Geri al",
+ "notify.unfollow_feed": " takibi bırakıldı.",
+ "player.back_10s": "10 saniye geri",
+ "player.close": "Kapat",
+ "player.download": "İndir",
+ "player.exit_full_screen": "Tam Ekrandan Çık",
+ "player.forward_10s": "10 saniye ileri",
+ "player.full_screen": "Tam Ekran",
+ "player.mute": "Sessize Al",
+ "player.open_entry": "Girişi Aç",
+ "player.pause": "Duraklat",
+ "player.play": "Oynat",
+ "player.playback_rate": "Oynatma Hızı",
+ "player.unmute": "Sesi Aç",
+ "player.volume": "Ses",
+ "resize.tooltip.double_click_to_collapse": "Çift tıkla kapat",
+ "resize.tooltip.drag_to_resize": "Sürükle yeniden boyutlandır",
+ "search.empty.no_results": "Sonuç bulunamadı.",
+ "search.group.entries": "Girişler",
+ "search.group.feeds": "Beslemeler",
+ "search.options.all": "Tümü",
+ "search.options.entries": "Girişler",
+ "search.options.feeds": "Beslemeler",
+ "search.options.search_type": "Arama Türü",
+ "search.placeholder": "Ara...",
+ "search.result_count_local_mode": "(Yerel mod)",
+ "search.tooltip.local_search": "Bu arama yerel olarak mevcut verileri kapsar. En son verileri dahil etmek için Yeniden Getir'i deneyin.",
+ "shortcuts.guide.title": "Kısayollar Kılavuzu",
+ "sidebar.add_more_feeds": "Daha fazla besleme ekle",
+ "sidebar.category_remove_dialog.cancel": "İptal",
+ "sidebar.category_remove_dialog.continue": "Devam Et",
+ "sidebar.category_remove_dialog.description": "Bu işlem kategorinizi silecek, ancak içerdiği beslemeler korunacak ve web sitesine göre gruplandırılacaktır.",
+ "sidebar.category_remove_dialog.title": "Kategoriyi Kaldır",
+ "sidebar.feed_actions.claim": "Talep Et",
+ "sidebar.feed_actions.claim_feed": "Beslemeyi Talep Et",
+ "sidebar.feed_actions.copy_feed_id": "Besleme ID'sini kopyala",
+ "sidebar.feed_actions.copy_feed_url": "Besleme URL'sini kopyala",
+ "sidebar.feed_actions.copy_list_id": "Liste ID'sini kopyala",
+ "sidebar.feed_actions.copy_list_url": "Liste URL'sini kopyala",
+ "sidebar.feed_actions.edit": "Düzenle",
+ "sidebar.feed_actions.edit_feed": "Beslemeyi düzenle",
+ "sidebar.feed_actions.edit_list": "Listeyi düzenle",
+ "sidebar.feed_actions.feed_owned_by_you": "Bu besleme size ait",
+ "sidebar.feed_actions.list_owned_by_you": "Bu liste size ait",
+ "sidebar.feed_actions.mark_all_as_read": "Tümünü okundu olarak işaretle",
+ "sidebar.feed_actions.navigate_to_feed": "Beslemeye git",
+ "sidebar.feed_actions.navigate_to_list": "Listeye git",
+ "sidebar.feed_actions.open_feed_in_browser": "Beslemeyi tarayıcıda aç",
+ "sidebar.feed_actions.open_list_in_browser": "Listeyi tarayıcıda aç",
+ "sidebar.feed_actions.open_site_in_browser": "Siteyi tarayıcıda aç",
+ "sidebar.feed_actions.unfollow": "Takibi bırak",
+ "sidebar.feed_actions.unfollow_feed": "Besleme takibini bırak",
+ "sidebar.feed_column.context_menu.change_to_other_view": "Diğer görünüme geç",
+ "sidebar.feed_column.context_menu.delete_category": "Kategoriyi sil",
+ "sidebar.feed_column.context_menu.delete_category_confirmation": "{{folderName}} kategorisini silmek istiyor musunuz?",
+ "sidebar.feed_column.context_menu.mark_as_read": "Okundu olarak işaretle",
+ "sidebar.feed_column.context_menu.rename_category": "Kategoriyi yeniden adlandır",
+ "sidebar.select_sort_method": "Bir sıralama yöntemi seçin",
+ "signin.continue_with_github": "GitHub ile devam et",
+ "signin.continue_with_google": "Google ile devam et",
+ "signin.sign_in_to": "Giriş yap",
+ "sync_indicator.disabled": "Güvenlik nedeniyle senkronizasyon devre dışı bırakıldı.",
+ "sync_indicator.offline": "Çevrimdışı",
+ "sync_indicator.synced": "Sunucu ile senkronize edildi",
+ "tip_modal.amount": "Miktar",
+ "tip_modal.claim_feed": "Bu beslemeyi talep et",
+ "tip_modal.create_wallet": "Ücretsiz Oluştur",
+ "tip_modal.feed_owner": "Besleme Sahibi",
+ "tip_modal.low_balance": "Bakiyeniz bu bahşiş için yeterli değil. Lütfen miktarı ayarlayın.",
+ "tip_modal.no_wallet": "Henüz bir cüzdanınız yok. Bahşiş vermek için lütfen bir cüzdan oluşturun.",
+ "tip_modal.tip_amount_sent": "yazara gönderildi.",
+ "tip_modal.tip_now": "Şimdi Bahşiş Ver",
+ "tip_modal.tip_sent": "Bahşiş başarıyla gönderildi! Desteğiniz için teşekkür ederiz.",
+ "tip_modal.tip_support": "⭐ Desteğinizi göstermek için bahşiş verin!",
+ "tip_modal.unclaimed_feed": "Henüz kimse bu beslemeyi talep etmedi. Alınan Power, talep edilene kadar blok zinciri sözleşmesinde güvenli bir şekilde tutulacaktır.",
+ "user_button.account": "Hesap",
+ "user_button.achievement": "Başarılar",
+ "user_button.download_desktop_app": "Masaüstü uygulamasını indir",
+ "user_button.log_out": "Çıkış yap",
+ "user_button.power": "Güç",
+ "user_button.preferences": "Tercihler",
+ "user_button.profile": "Profil",
+ "user_profile.close": "Kapat",
+ "user_profile.edit": "Düzenle",
+ "user_profile.loading": "Yükleniyor",
+ "user_profile.share": "Paylaş",
+ "user_profile.toggle_item_style": "Öğe Stilini Değiştir",
+ "words.achievement": "Başarılar",
+ "words.add": "Ekle",
+ "words.confirm": "Onayla",
+ "words.discover": "Keşfet",
+ "words.email": "E-posta",
+ "words.feeds": "Beslemeler",
+ "words.import": "İçe Aktar",
+ "words.items": "Öğeler",
+ "words.language": "Dil",
+ "words.lists": "Listeler",
+ "words.load_archived_entries": "Arşivlenmiş girişleri yükle",
+ "words.login": "Giriş",
+ "words.mint": "Mint",
+ "words.power": "Güç",
+ "words.rss": "RSS",
+ "words.rss3": "RSS3",
+ "words.rsshub": "RSSHub",
+ "words.search": "Ara",
+ "words.starred": "Yıldızlı",
+ "words.undo": "Geri al",
+ "words.unread": "Okunmamış",
+ "words.user": "Kullanıcı",
+ "words.which.all": "tümü",
+ "words.zero_items": "Sıfır öğe"
+}
diff --git a/locales/common/tr.json b/locales/common/tr.json
new file mode 100644
index 0000000000..8dbd4ffbbb
--- /dev/null
+++ b/locales/common/tr.json
@@ -0,0 +1,34 @@
+{
+ "app.copied_to_clipboard": "Panoya kopyalandı",
+ "cancel": "İptal",
+ "close": "Kapat",
+ "confirm": "Onayla",
+ "ok": "Tamam",
+ "quantifier.piece": "",
+ "time.last_night": "Dün Gece",
+ "time.the_night_before_last": "Evvelsi Gece",
+ "time.today": "Bugün",
+ "time.yesterday": "Dün",
+ "tips.load-lng-error": "Dil paketi yüklenemedi",
+ "words.actions": "İşlemler",
+ "words.back": "Geri",
+ "words.copy": "Kopyala",
+ "words.create": "Oluştur",
+ "words.edit": "Düzenle",
+ "words.entry": "Giriş",
+ "words.id": "ID",
+ "words.items_one": "Öğe",
+ "words.items_other": "Öğeler",
+ "words.local": "yerel",
+ "words.manage": "Yönet",
+ "words.record": "kayıt",
+ "words.record_one": "kayıt",
+ "words.record_other": "kayıtlar",
+ "words.result": "sonuç",
+ "words.result_one": "sonuç",
+ "words.result_other": "sonuçlar",
+ "words.space": " ",
+ "words.submit": "Gönder",
+ "words.update": "Güncelle",
+ "words.which.all": "Tümü"
+}
diff --git a/locales/common/zh-CN.json b/locales/common/zh-CN.json
index a6d242e22c..00d462cfe6 100644
--- a/locales/common/zh-CN.json
+++ b/locales/common/zh-CN.json
@@ -10,7 +10,7 @@
"time.today": "今天",
"time.yesterday": "昨天",
"tips.load-lng-error": "加载语言包失败",
- "words.actions": "自动化",
+ "words.actions": "操作",
"words.back": "返回",
"words.copy": "复制",
"words.edit": "编辑",
diff --git a/locales/errors/tr.json b/locales/errors/tr.json
new file mode 100644
index 0000000000..b1e4f899c9
--- /dev/null
+++ b/locales/errors/tr.json
@@ -0,0 +1,29 @@
+{
+ "1000": "Yetkisiz",
+ "1001": "Oturum oluşturma başarısız",
+ "1002": "Geçersiz parametre",
+ "1003": "Geçersiz davet",
+ "2000": "Yalnızca yöneticiler beslemeleri yenileyebilir",
+ "2001": "Besleme bulunamadı",
+ "2002": "feedId veya url gerekli",
+ "2003": "Besleme getirme hatası",
+ "2004": "Besleme ayrıştırılamadı",
+ "2010": "Sahiplik doğrulaması başarısız oldu",
+ "2011": "Abonelik limiti aşıldı",
+ "3000": "Giriş bulunamadı",
+ "3001": "Giriş kullanıcıya ait değil",
+ "4000": "Zaten talep edilmiş",
+ "4001": "Kullanıcı cüzdan hatası",
+ "4002": "Yetersiz bakiye",
+ "4003": "Beslemenin çekilebilir bakiyesi yetersiz",
+ "4004": "Hedef kullanıcı cüzdan hatası",
+ "5000": "Davet limiti aşıldı. Lütfen birkaç gün sonra tekrar deneyin.",
+ "5001": "Davet zaten mevcut.",
+ "5002": "Davet kodu zaten kullanılmış.",
+ "5003": "Davet kodu mevcut değil.",
+ "6000": "Kullanıcı bulunamadı",
+ "7000": "Ayar bulunamadı",
+ "7001": "Geçersiz ayar sekmesi",
+ "7002": "Geçersiz ayar yükü",
+ "7003": "Ayar yükü çok büyük"
+}
diff --git a/locales/external/ar-iq.json b/locales/external/ar-IQ.json
similarity index 100%
rename from locales/external/ar-iq.json
rename to locales/external/ar-IQ.json
diff --git a/locales/external/ar-tn.json b/locales/external/ar-TN.json
similarity index 100%
rename from locales/external/ar-tn.json
rename to locales/external/ar-TN.json
diff --git a/locales/external/tr.json b/locales/external/tr.json
new file mode 100644
index 0000000000..f7fc56e1ef
--- /dev/null
+++ b/locales/external/tr.json
@@ -0,0 +1,36 @@
+{
+ "copied_link": "Bağlantı panoya kopyalandı",
+ "feed.feeds_one": "besleme",
+ "feed.feeds_other": "besleme",
+ "feed.follower_one": "takipçi",
+ "feed.follower_other": "takipçi",
+ "feed.follower_to_view_all": "takipçi",
+ "feed.followsAndFeeds": "{{subscriptionCount}} {{subscriptionNoun}} ve {{feedsCount}} {{feedsNoun}} {{appName}} üzerinde",
+ "feed.followsAndReads": "{{appName}} üzerinde {{readCount}} {{readNoun}} ile {{subscriptionCount}} {{subscriptionNoun}}",
+ "feed.read_one": "okuma",
+ "feed.read_other": "okuma",
+ "header.app": "Uygulama",
+ "header.download": "İndir",
+ "invitation.activate": "Etkinleştir",
+ "invitation.codeOptions.1": "Sizi davet edecek herhangi bir alfa test kullanıcısı aranıyor.",
+ "invitation.codeOptions.2": "Ara sıra yapılan çekilişler için Discord sunucumuza katılın.",
+ "invitation.codeOptions.3": "Ara sıra yapılan çekilişler için X hesabımızı takip edin.",
+ "invitation.earlyAccess": "Follow şu anda erken erişimde ve kullanmak için bir davet kodu gerektiriyor.",
+ "invitation.earlyAccessMessage": "😰 Üzgünüz, Follow şu anda erken erişimde ve kullanmak için bir davet kodu gerektiriyor.",
+ "invitation.generateButton": "Yeni kod oluştur",
+ "invitation.generateCost": "Arkadaşlarınız için bir davet kodu oluşturmak için {{INVITATION_PRICE}} Güç harcayabilirsiniz.",
+ "invitation.getCodeMessage": "Aşağıdaki yollarla bir davet kodu alabilirsiniz:",
+ "invitation.title": "Davet Kodu",
+ "login.backToWebApp": "Web Uygulamasına Geri Dön",
+ "login.continueWithGitHub": "GitHub ile devam et",
+ "login.continueWithGoogle": "Google ile devam et",
+ "login.logInTo": "Giriş yap ",
+ "login.openApp": "Uygulamayı Aç",
+ "login.redirecting": "Yönlendiriliyor",
+ "login.signOut": "Çıkış yap",
+ "login.welcomeTo": "Hoş geldiniz ",
+ "redirect.continueInBrowser": "Tarayıcıda Devam Et",
+ "redirect.instruction": "Şimdi {{APP_NAME}} uygulamasını açma ve bu sayfayı güvenle kapatma zamanı.",
+ "redirect.openApp": "{{APP_NAME}} Uygulamasını Aç",
+ "redirect.successMessage": "{{APP_NAME}} Hesabına başarıyla bağlandınız."
+}
diff --git a/locales/lang/ar-DZ.json b/locales/lang/ar-DZ.json
index 0be67b1278..15f35f4690 100644
--- a/locales/lang/ar-DZ.json
+++ b/locales/lang/ar-DZ.json
@@ -14,6 +14,7 @@
"langs.ko": "الكورية",
"langs.pt": "البرتغالية",
"langs.ru": "الروسية",
+ "langs.tr": "التركية",
"langs.zh-CN": "الصينية المبسطة",
"langs.zh-HK": "الصينية التقليدية (هونغ كونغ)",
"langs.zh-TW": "الصينية التقليدية (تايوان)",
diff --git a/locales/lang/ar-IQ.json b/locales/lang/ar-IQ.json
index e548b1c1eb..652d8a756f 100644
--- a/locales/lang/ar-IQ.json
+++ b/locales/lang/ar-IQ.json
@@ -14,6 +14,7 @@
"langs.ko": "الكورية",
"langs.pt": "البرتغالية",
"langs.ru": "الروسية",
+ "langs.tr": "التركية",
"langs.zh-CN": "الصينية المبسطة",
"langs.zh-HK": "الصينية التقليدية (هونغ كونغ)",
"langs.zh-TW": "الصينية التقليدية (تايوان)",
diff --git a/locales/lang/ar-KW.json b/locales/lang/ar-KW.json
index 8665a12511..ceb5b1a41d 100644
--- a/locales/lang/ar-KW.json
+++ b/locales/lang/ar-KW.json
@@ -14,6 +14,7 @@
"langs.ko": "الكورية",
"langs.pt": "البرتغالية",
"langs.ru": "الروسية",
+ "langs.tr": "التركية",
"langs.zh-CN": "الصينية المبسطة",
"langs.zh-HK": "الصينية التقليدية (هونغ كونغ)",
"langs.zh-TW": "الصينية التقليدية (تايوان)",
diff --git a/locales/lang/ar-MA.json b/locales/lang/ar-MA.json
index fd318c4ade..f4bdf41cb6 100644
--- a/locales/lang/ar-MA.json
+++ b/locales/lang/ar-MA.json
@@ -14,6 +14,7 @@
"langs.ko": "الكورية",
"langs.pt": "البرتغالية",
"langs.ru": "الروسية",
+ "langs.tr": "التركية",
"langs.zh-CN": "الصينية المبسطة",
"langs.zh-HK": "الصينية التقليدية (هونغ كونغ)",
"langs.zh-TW": "الصينية التقليدية (تايوان)",
diff --git a/locales/lang/ar-TN.json b/locales/lang/ar-TN.json
index 32f1b2bd1b..6a58394cf8 100644
--- a/locales/lang/ar-TN.json
+++ b/locales/lang/ar-TN.json
@@ -14,6 +14,7 @@
"langs.ko": "الكورية",
"langs.pt": "البرتغالية",
"langs.ru": "الروسية",
+ "langs.tr": "التركية",
"langs.zh-CN": "الصينية المبسطة",
"langs.zh-HK": "الصينية التقليدية (هونغ كونغ)",
"langs.zh-TW": "الصينية التقليدية (تايوان)",
diff --git a/locales/lang/en.json b/locales/lang/en.json
index b3d487c245..a4495991e8 100644
--- a/locales/lang/en.json
+++ b/locales/lang/en.json
@@ -14,6 +14,7 @@
"langs.ko": "Korean",
"langs.pt": "Portuguese",
"langs.ru": "Russian",
+ "langs.tr": "Turkish",
"langs.zh-CN": "Simplified Chinese",
"langs.zh-HK": "Traditional Chinese (Hong Kong)",
"langs.zh-TW": "Traditional Chinese (Taiwan)",
diff --git a/locales/lang/es.json b/locales/lang/es.json
index 9c9555db94..24420b752e 100644
--- a/locales/lang/es.json
+++ b/locales/lang/es.json
@@ -14,6 +14,7 @@
"langs.ko": "Coreano",
"langs.pt": "Portugués",
"langs.ru": "Ruso",
+ "langs.tr": "Turco",
"langs.zh-CN": "Chino simplificado",
"langs.zh-HK": "Chino tradicional (Hong Kong)",
"langs.zh-TW": "Chino tradicional (Taiwán)",
diff --git a/locales/lang/fi.json b/locales/lang/fi.json
index 07e5153644..d05e7da833 100644
--- a/locales/lang/fi.json
+++ b/locales/lang/fi.json
@@ -14,6 +14,7 @@
"langs.ko": "Kore",
"langs.pt": "Portugali",
"langs.ru": "Venäjä",
+ "langs.tr": "Turkki",
"langs.zh-CN": "Yksinkertaistettu kiina",
"langs.zh-HK": "Perinteinen kiina (Hongkong)",
"langs.zh-TW": "Perinteinen kiina (Taiwan)",
diff --git a/locales/lang/fr.json b/locales/lang/fr.json
index 88826624b7..07bcd9e67f 100644
--- a/locales/lang/fr.json
+++ b/locales/lang/fr.json
@@ -14,6 +14,7 @@
"langs.ko": "Coréen",
"langs.pt": "Portugais",
"langs.ru": "Russe",
+ "langs.tr": "Turc",
"langs.zh-CN": "Chinois simplifié",
"langs.zh-HK": "Chinois traditionnel (Hong Kong)",
"langs.zh-TW": "Chinois traditionnel (Taïwan)",
diff --git a/locales/lang/it.json b/locales/lang/it.json
index 93b139723e..c5307bc01b 100644
--- a/locales/lang/it.json
+++ b/locales/lang/it.json
@@ -14,6 +14,7 @@
"langs.ko": "Coreano",
"langs.pt": "Portoghese",
"langs.ru": "Russo",
+ "langs.tr": "Turco",
"langs.zh-CN": "Cinese semplificato",
"langs.zh-HK": "Cinese tradizionale (Hong Kong)",
"langs.zh-TW": "Cinese tradizionale (Taiwan)",
diff --git a/locales/lang/ja.json b/locales/lang/ja.json
index 1fc5d29db7..288f4577f9 100644
--- a/locales/lang/ja.json
+++ b/locales/lang/ja.json
@@ -14,6 +14,7 @@
"langs.ko": "韓国語",
"langs.pt": "ポルトガル語",
"langs.ru": "ロシア語",
+ "langs.tr": "トルコ語",
"langs.zh-CN": "簡体字中国語",
"langs.zh-HK": "繁体字中国語(香港)",
"langs.zh-TW": "繁体字中国語(台湾)",
diff --git a/locales/lang/ko.json b/locales/lang/ko.json
index e0b184431d..a648d776fb 100644
--- a/locales/lang/ko.json
+++ b/locales/lang/ko.json
@@ -14,6 +14,7 @@
"langs.ko": "한국어",
"langs.pt": "포르투갈어",
"langs.ru": "러시아어",
+ "langs.tr": "터키어",
"langs.zh-CN": "간체 중국어",
"langs.zh-HK": "번체 중국어 (홍콩)",
"langs.zh-TW": "번체 중국어 (대만)",
diff --git a/locales/lang/pt.json b/locales/lang/pt.json
index 02806b008b..5bc119db00 100644
--- a/locales/lang/pt.json
+++ b/locales/lang/pt.json
@@ -14,6 +14,7 @@
"langs.ko": "Coreano",
"langs.pt": "Português",
"langs.ru": "Russo",
+ "langs.tr": "Turco",
"langs.zh-CN": "Chinês simplificado",
"langs.zh-HK": "Chinês tradicional (Hong Kong)",
"langs.zh-TW": "Chinês tradicional (Taiwan)",
diff --git a/locales/lang/ru.json b/locales/lang/ru.json
index 439b0d4af1..e11f9e070b 100644
--- a/locales/lang/ru.json
+++ b/locales/lang/ru.json
@@ -14,6 +14,7 @@
"langs.ko": "Корейский",
"langs.pt": "Португальский",
"langs.ru": "Русский",
+ "langs.tr": "Турецкий",
"langs.zh-CN": "Упрощенный китайский",
"langs.zh-HK": "Традиционный китайский (Гонконг)",
"langs.zh-TW": "Традиционный китайский (Тайвань)",
diff --git a/locales/lang/tr.json b/locales/lang/tr.json
new file mode 100644
index 0000000000..6a8bf4841d
--- /dev/null
+++ b/locales/lang/tr.json
@@ -0,0 +1,22 @@
+{
+ "langs.ar-DZ": "Arapça (Cezayir)",
+ "langs.ar-IQ": "Arapça (Irak)",
+ "langs.ar-KW": "Arapça (Kuveyt)",
+ "langs.ar-MA": "Arapça (Fas)",
+ "langs.ar-SA": "Arapça (Suudi Arabistan)",
+ "langs.ar-TN": "Arapça (Tunus)",
+ "langs.en": "İngilizce",
+ "langs.es": "İspanyolca",
+ "langs.fi": "Fince",
+ "langs.fr": "Fransızca",
+ "langs.it": "İtalyanca",
+ "langs.ja": "Japonca",
+ "langs.ko": "Korece",
+ "langs.pt": "Portekizce",
+ "langs.ru": "Rusça",
+ "langs.tr": "Türkçe",
+ "langs.zh-CN": "Basitleştirilmiş Çince",
+ "langs.zh-HK": "Geleneksel Çince (Hong Kong)",
+ "langs.zh-TW": "Geleneksel Çince (Tayvan)",
+ "name": "Türkçe"
+}
diff --git a/locales/lang/zh-CN.json b/locales/lang/zh-CN.json
index e1af9571ac..fcd629207d 100644
--- a/locales/lang/zh-CN.json
+++ b/locales/lang/zh-CN.json
@@ -14,6 +14,7 @@
"langs.ko": "韩语",
"langs.pt": "葡萄牙语",
"langs.ru": "俄语",
+ "langs.tr": "土耳其语",
"langs.zh-CN": "简体中文",
"langs.zh-HK": "繁体中文(香港)",
"langs.zh-TW": "繁体中文(台湾)",
diff --git a/locales/lang/zh-HK.json b/locales/lang/zh-HK.json
index 203120a7d8..d8447c4b57 100644
--- a/locales/lang/zh-HK.json
+++ b/locales/lang/zh-HK.json
@@ -14,6 +14,7 @@
"langs.ko": "韓語",
"langs.pt": "葡萄牙語",
"langs.ru": "俄語",
+ "langs.tr": "土耳其語",
"langs.zh-CN": "簡體中文",
"langs.zh-HK": "繁體中文(香港)",
"langs.zh-TW": "繁體中文(台灣)",
diff --git a/locales/lang/zh-TW.json b/locales/lang/zh-TW.json
index 97a30fbe99..aeb7cc9eb3 100644
--- a/locales/lang/zh-TW.json
+++ b/locales/lang/zh-TW.json
@@ -14,6 +14,7 @@
"langs.ko": "韓語",
"langs.pt": "葡萄牙語",
"langs.ru": "俄語",
+ "langs.tr": "土耳其語",
"langs.zh-CN": "簡體中文",
"langs.zh-HK": "繁體中文(香港)",
"langs.zh-TW": "繁體中文(台灣)",
diff --git a/locales/native/ar-iq.json b/locales/native/ar-IQ.json
similarity index 100%
rename from locales/native/ar-iq.json
rename to locales/native/ar-IQ.json
diff --git a/locales/native/ar-kw.json b/locales/native/ar-KW.json
similarity index 100%
rename from locales/native/ar-kw.json
rename to locales/native/ar-KW.json
diff --git a/locales/native/ar-tn.json b/locales/native/ar-TN.json
similarity index 100%
rename from locales/native/ar-tn.json
rename to locales/native/ar-TN.json
diff --git a/locales/native/tr.json b/locales/native/tr.json
new file mode 100644
index 0000000000..c7cb63a67e
--- /dev/null
+++ b/locales/native/tr.json
@@ -0,0 +1,68 @@
+{
+ "contextMenu.copy": "Kopyala",
+ "contextMenu.copyImage": "Resmi Kopyala",
+ "contextMenu.copyImageAddress": "Resim Adresini Kopyala",
+ "contextMenu.copyLink": "Bağlantıyı Kopyala",
+ "contextMenu.copyVideoAddress": "Video Adresini Kopyala",
+ "contextMenu.cut": "Kes",
+ "contextMenu.inspect": "Öğeyi İncele",
+ "contextMenu.learnSpelling": "Yazımı Öğren",
+ "contextMenu.lookUpSelection": "Seçimi Ara",
+ "contextMenu.openImageInBrowser": "Resmi Tarayıcıda Aç",
+ "contextMenu.openLinkInBrowser": "Bağlantıyı Tarayıcıda Aç",
+ "contextMenu.paste": "Yapıştır",
+ "contextMenu.saveImage": "Resmi Kaydet",
+ "contextMenu.saveImageAs": "Resmi Farklı Kaydet...",
+ "contextMenu.saveLinkAs": "Bağlantıyı Farklı Kaydet...",
+ "contextMenu.saveVideo": "Videoyu Kaydet",
+ "contextMenu.saveVideoAs": "Videoyu Farklı Kaydet...",
+ "contextMenu.searchWithGoogle": "Google ile Ara",
+ "contextMenu.selectAll": "Tümünü Seç",
+ "contextMenu.services": "Hizmetler",
+ "dialog.clearAllData": "Tüm verileri temizlemek istediğinize emin misiniz?",
+ "dialog.no": "Hayır",
+ "dialog.yes": "Evet",
+ "menu.about": "{{name}} Hakkında",
+ "menu.actualSize": "Gerçek Boyut",
+ "menu.bringAllToFront": "Tümünü Öne Getir",
+ "menu.checkForUpdates": "Güncellemeleri Kontrol Et",
+ "menu.clearAllData": "Tüm verileri temizle",
+ "menu.close": "Kapat",
+ "menu.copy": "Kopyala",
+ "menu.cut": "Kes",
+ "menu.debug": "Hata Ayıklama",
+ "menu.delete": "Sil",
+ "menu.discover": "Keşfet",
+ "menu.edit": "Düzenle",
+ "menu.file": "Dosya",
+ "menu.followReleases": "Sürümleri takip et",
+ "menu.forceReload": "Zorla Yenile",
+ "menu.front": "Öne Getir",
+ "menu.help": "Yardım",
+ "menu.hide": "{{name}} Uygulamasını Gizle",
+ "menu.hideOthers": "Diğerlerini Gizle",
+ "menu.minimize": "Simge Durumuna Küçült",
+ "menu.openLogFile": "Günlük dosyasını aç",
+ "menu.paste": "Yapıştır",
+ "menu.pasteAndMatchStyle": "Yapıştır ve Stili Eşleştir",
+ "menu.quickAdd": "Hızlı Ekle",
+ "menu.quit": "{{name}} Uygulamasından Çık",
+ "menu.quitAndInstallUpdate": "Hata Ayıklama: Çık ve Güncellemeyi Yükle",
+ "menu.redo": "Yinele",
+ "menu.reload": "Yenile",
+ "menu.search": "Ara",
+ "menu.selectAll": "Tümünü Seç",
+ "menu.services": "Hizmetler",
+ "menu.settings": "Ayarlar...",
+ "menu.speech": "Konuşma",
+ "menu.startSpeaking": "Konuşmaya Başla",
+ "menu.stopSpeaking": "Konuşmayı Durdur",
+ "menu.toggleDevTools": "Geliştirici Araçlarını Aç/Kapat",
+ "menu.toggleFullScreen": "Tam Ekranı Aç/Kapat",
+ "menu.undo": "Geri Al",
+ "menu.view": "Görünüm",
+ "menu.window": "Pencere",
+ "menu.zoom": "Yakınlaştır",
+ "menu.zoomIn": "Yakınlaştır",
+ "menu.zoomOut": "Uzaklaştır"
+}
diff --git a/locales/settings/tr.json b/locales/settings/tr.json
new file mode 100644
index 0000000000..9f05b4a87f
--- /dev/null
+++ b/locales/settings/tr.json
@@ -0,0 +1,236 @@
+{
+ "about.changelog": "Değişiklik Günlüğü",
+ "about.feedbackInfo": "{{appName}} ({{commitSha}}) geliştirmenin erken aşamalarındadır. Herhangi bir geri bildiriminiz veya öneriniz varsa, lütfen GitHub'ımızda bir konu açmaktan çekinmeyin.",
+ "about.iconLibrary": "Kullanılan simge kütüphanesi tarafından telif hakkıyla korunmaktadır ve yeniden dağıtılamaz.",
+ "about.licenseInfo": "{{appName}} her zaman ücretsiz ve açık kaynaklı bir proje olacaktır. {{license}} lisansı altında lisanslanmıştır.",
+ "about.sidebar_title": "Hakkında",
+ "about.socialMedia": "Sosyal Medya",
+ "actions.actionName": "Eylem {{number}}",
+ "actions.action_card.add": "Ekle",
+ "actions.action_card.all": "Tümü",
+ "actions.action_card.block_rules": "Engelleme Kuralları",
+ "actions.action_card.custom_filters": "Özel filtreler",
+ "actions.action_card.enable_readability": "Okunabilirliği etkinleştir",
+ "actions.action_card.entry_options.all": "Tümü",
+ "actions.action_card.entry_options.author": "Yazar",
+ "actions.action_card.entry_options.content": "İçerik",
+ "actions.action_card.entry_options.order": "Sıralama",
+ "actions.action_card.entry_options.title": "Başlık",
+ "actions.action_card.entry_options.url": "URL",
+ "actions.action_card.feed_options.category": "Kategori",
+ "actions.action_card.feed_options.feed_url": "Besleme URL'si",
+ "actions.action_card.feed_options.site_url": "Site URL'si",
+ "actions.action_card.feed_options.title": "Başlık",
+ "actions.action_card.feed_options.view": "Görünüm",
+ "actions.action_card.field": "Alan",
+ "actions.action_card.from": "Kimden",
+ "actions.action_card.generate_summary": "Yapay zeka kullanarak özet oluştur",
+ "actions.action_card.name": "İsim",
+ "actions.action_card.operation_options.contains": "içerir",
+ "actions.action_card.operation_options.does_not_contain": "içermez",
+ "actions.action_card.operation_options.is_equal_to": "eşittir",
+ "actions.action_card.operation_options.is_greater_than": "büyüktür",
+ "actions.action_card.operation_options.is_less_than": "küçüktür",
+ "actions.action_card.operation_options.is_not_equal_to": "eşit değildir",
+ "actions.action_card.operation_options.matches_regex": "regex ile eşleşir",
+ "actions.action_card.operator": "Operatör",
+ "actions.action_card.rewrite_rules": "Yeniden Yazma Kuralları",
+ "actions.action_card.then_do": "Sonra yap…",
+ "actions.action_card.to": "Kime",
+ "actions.action_card.translate_into": "Şu dile çevir",
+ "actions.action_card.value": "Değer",
+ "actions.action_card.when_feeds_match": "Beslemeler eşleştiğinde…",
+ "actions.newRule": "Yeni Kural",
+ "actions.save": "Kaydet",
+ "actions.saveSuccess": "🎉 Eylemler kaydedildi.",
+ "actions.sidebar_title": "Eylemler",
+ "actions.title": "Eylemler",
+ "appearance.code_highlight_theme": "Kod vurgulama teması",
+ "appearance.content": "İçerik",
+ "appearance.content_font": "İçerik Yazı Tipi",
+ "appearance.custom_font": "Özel Yazı Tipi",
+ "appearance.fonts": "Yazı Tipleri",
+ "appearance.general": "Genel",
+ "appearance.guess_code_language.description": "Etiketlenmemiş kod bloklarını çıkarmak için modeller kullanan başlıca programlama dilleri",
+ "appearance.guess_code_language.label": "Kod dilini tahmin et",
+ "appearance.misc": "Çeşitli",
+ "appearance.modal_overlay.description": "Modal arka planını göster",
+ "appearance.modal_overlay.label": "Modal arka planını göster",
+ "appearance.opaque_sidebars.label": "Opak kenar çubukları",
+ "appearance.reader_render_inline_style.description": "Orijinal HTML'nin satır içi stilinin işlenmesine izin verir.",
+ "appearance.reader_render_inline_style.label": "Satır içi stili işle",
+ "appearance.reduce_motion.description": "Performansı artırmak ve enerji tüketimini azaltmak için öğelerin hareketini azaltma",
+ "appearance.reduce_motion.label": "Hareketi azalt",
+ "appearance.save": "Kaydet",
+ "appearance.show_dock_badge.label": "Dock rozeti olarak göster",
+ "appearance.sidebar_show_unread_count.label": "Kenar çubuğunda göster",
+ "appearance.sidebar_title": "Görünüm",
+ "appearance.text_size": "Metin boyutu",
+ "appearance.theme.dark": "Koyu",
+ "appearance.theme.label": "Tema",
+ "appearance.theme.light": "Açık",
+ "appearance.theme.system": "Sistem",
+ "appearance.title": "Görünüm",
+ "appearance.ui_font": "Arayüz Yazı Tipi",
+ "appearance.unread_count": "Okunmamış sayısı",
+ "appearance.use_pointer_cursor.description": "Herhangi bir etkileşimli öğenin üzerine gelindiğinde imleci bir işaretçiye dönüştürün.",
+ "appearance.use_pointer_cursor.label": "İşaretçi imlecini kullan",
+ "common.give_star": "Ürünümüzü beğendiniz mi? GitHub'da bize bir yıldız verin!",
+ "feeds.claimTips": "Beslemelerinizi talep etmek ve bahşiş almak için, abonelik listenizde beslemeye sağ tıklayın ve Talep Et'i seçin.",
+ "feeds.noFeeds": "Talep edilmiş besleme yok",
+ "feeds.tableHeaders.entryCount": "Girdiler",
+ "feeds.tableHeaders.name": "İsim",
+ "feeds.tableHeaders.subscriptionCount": "Abonelikler",
+ "feeds.tableHeaders.tipAmount": "Alınan bahşişler",
+ "general.app": "Uygulama",
+ "general.data_persist.description": "Çevrimdışı erişimi ve yerel aramayı etkinleştirmek için verileri yerel olarak sakla.",
+ "general.data_persist.label": "Çevrimdışı kullanım için verileri sakla",
+ "general.group_by_date.description": "Girdileri tarihe göre grupla.",
+ "general.group_by_date.label": "Tarihe göre grupla",
+ "general.language": "Dil",
+ "general.launch_at_login": "Oturum açıldığında başlat",
+ "general.mark_as_read.hover.description": "Üzerine gelindiğinde girdileri otomatik olarak okundu olarak işaretle.",
+ "general.mark_as_read.hover.label": "Üzerine gelindiğinde okundu olarak işaretle",
+ "general.mark_as_read.render.description": "Tek seviyeli girdileri (örn. sosyal medya gönderileri, resimler, video görüntülemeleri) görünüme girdiklerinde otomatik olarak okundu olarak işaretle.",
+ "general.mark_as_read.render.label": "Görünümde olduğunda okundu olarak işaretle",
+ "general.mark_as_read.scroll.description": "Görünümden kaydırıldığında girdileri otomatik olarak okundu olarak işaretle.",
+ "general.mark_as_read.scroll.label": "Kaydırıldığında okundu olarak işaretle",
+ "general.network": "Ağ",
+ "general.privacy_data": "Gizlilik ve Veri",
+ "general.proxy.description": "Ağ trafiği yönlendirmesi için proxy ayarla, örn., socks://proxy.example.com:1080",
+ "general.proxy.label": "Proxy",
+ "general.rebuild_database.button": "Yeniden Oluştur",
+ "general.rebuild_database.description": "Görüntüleme sorunları yaşıyorsanız, veritabanını yeniden oluşturmak bu sorunları çözebilir.",
+ "general.rebuild_database.label": "Veritabanını Yeniden Oluştur",
+ "general.rebuild_database.title": "Veritabanını Yeniden Oluştur",
+ "general.rebuild_database.warning.line1": "Veritabanını yeniden oluşturmak tüm yerel verilerinizi temizleyecektir.",
+ "general.rebuild_database.warning.line2": "Devam etmek istediğinizden emin misiniz?",
+ "general.send_anonymous_data.description": "Anonim telemetri verisi göndermeyi seçerek, Follow'un genel kullanıcı deneyimini iyileştirmeye katkıda bulunursunuz.",
+ "general.send_anonymous_data.label": "Anonim veri gönder",
+ "general.show_unread_on_launch.description": "Başlangıçta okunmamış içeriği göster",
+ "general.show_unread_on_launch.label": "Başlangıçta okunmamış içeriği göster",
+ "general.sidebar_title": "Genel",
+ "general.timeline": "Zaman Çizelgesi",
+ "general.unread": "Okunmamış",
+ "general.voices": "Sesler",
+ "integration.eagle.enable.description": "Mevcut olduğunda 'Medyayı Eagle'a kaydet' düğmesini göster.",
+ "integration.eagle.enable.label": "Etkinleştir",
+ "integration.eagle.title": "Eagle",
+ "integration.instapaper.enable.description": "Mevcut olduğunda 'Instapaper'a kaydet' düğmesini göster.",
+ "integration.instapaper.enable.label": "Etkinleştir",
+ "integration.instapaper.password.label": "Instapaper Şifresi",
+ "integration.instapaper.title": "Instapaper",
+ "integration.instapaper.username.label": "Instapaper Kullanıcı Adı",
+ "integration.readwise.enable.description": "Mevcut olduğunda 'Readwise'a kaydet' düğmesini göster.",
+ "integration.readwise.enable.label": "Etkinleştir",
+ "integration.readwise.title": "Readwise",
+ "integration.readwise.token.description": "Buradan alabilirsiniz: readwise.io/access_token.",
+ "integration.readwise.token.label": "Readwise Erişim Tokeni",
+ "integration.sidebar_title": "Entegrasyon",
+ "integration.tip": "İpucu: Hassas verileriniz yerel olarak saklanır ve sunucuya yüklenmez.",
+ "integration.title": "Entegrasyon",
+ "invitation.activate": "Etkinleştir",
+ "invitation.codeOptions.betaUser": "1. Sizi davet eden bir beta kullanıcısı bulun.",
+ "invitation.codeOptions.discord": "2. Discord sunucumuza katılın ve zaman zaman hediyeler alın.",
+ "invitation.codeOptions.xAccount": "3. X hesabımızı takip edin ve zaman zaman hediyeler alın.",
+ "invitation.confirmModal.cancel": "İptal",
+ "invitation.confirmModal.confirm": "Devam etmek istiyor musunuz?",
+ "invitation.confirmModal.continue": "Devam",
+ "invitation.confirmModal.message": "Bir davet kodu oluşturmak size {{INVITATION_PRICE}} Power'a mal olacak.",
+ "invitation.confirmModal.title": "Onayla",
+ "invitation.earlyAccess": "Follow şu anda erken erişim aşamasındadır ve kullanmak için bir davet kodu gerektirir.",
+ "invitation.earlyAccessMessage": "😰 Üzgünüz, Follow şu anda erken erişim aşamasındadır ve kullanmak için bir davet kodu gerektirir.",
+ "invitation.generateButton": "Yeni kod oluştur",
+ "invitation.generateCost": "Arkadaşlarınız için bir davet kodu oluşturmak için {{INVITATION_PRICE}} Power harcayabilirsiniz.",
+ "invitation.getCodeMessage": "Aşağıdaki yöntemlerle bir davet kodu alabilirsiniz:",
+ "invitation.limitationMessage": "Kullanım sürenize bağlı olarak, en fazla {{limitation}} davet kodu oluşturabilirsiniz.",
+ "invitation.newInvitationSuccess": "🎉 Yeni davet oluşturuldu, davet kodu kopyalandı",
+ "invitation.noInvitations": "Davet yok",
+ "invitation.notUsed": "Kullanılmadı",
+ "invitation.sidebar_title": "Davetler",
+ "invitation.tableHeaders.code": "Kod",
+ "invitation.tableHeaders.creationTime": "Oluşturma Zamanı",
+ "invitation.tableHeaders.usedBy": "Kullanan",
+ "invitation.title": "Davet Kodu",
+ "lists.create": "Yeni Liste Oluştur",
+ "lists.created.error": "Liste oluşturulamadı.",
+ "lists.created.success": "Liste başarıyla oluşturuldu!",
+ "lists.description": "Açıklama",
+ "lists.edit.error": "Liste düzenlenemedi.",
+ "lists.edit.label": "Düzenle",
+ "lists.edit.success": "Liste başarıyla düzenlendi!",
+ "lists.fee.description": "Bu listenin üyeliği için diğerlerinin ödemesi gereken ücret.",
+ "lists.fee.label": "Ücret",
+ "lists.feeds.actions": "Eylemler",
+ "lists.feeds.add.error": "Besleme listesine eklenemedi.",
+ "lists.feeds.add.label": "Ekle",
+ "lists.feeds.add.success": "Besleme listesine başarıyla eklendi.",
+ "lists.feeds.delete.error": "Besleme listesinden kaldırılamadı.",
+ "lists.feeds.delete.success": "Besleme listesinden başarıyla kaldırıldı.",
+ "lists.feeds.id": "Besleme ID'si",
+ "lists.feeds.label": "Beslemeler",
+ "lists.feeds.manage": "Beslemeleri Yönet",
+ "lists.feeds.owner": "Sahibi",
+ "lists.feeds.search": "Besleme Ara",
+ "lists.feeds.title": "Başlık",
+ "lists.image": "Resim",
+ "lists.info": "Listeniz, diğerlerinin abone olabileceği beslemelerin bir koleksiyonudur. Aboneler, liste içindeki tüm beslemeleri senkronize eder ve erişir.",
+ "lists.noLists": "Liste yok",
+ "lists.submit": "Gönder",
+ "lists.title": "Başlık",
+ "lists.view": "Görüntüle",
+ "profile.avatar.label": "Avatar",
+ "profile.handle.description": "Benzersiz tanımlayıcınız.",
+ "profile.handle.label": "Kullanıcı Adı",
+ "profile.name.description": "Herkese açık görünen adınız.",
+ "profile.name.label": "Görünen Ad",
+ "profile.sidebar_title": "Profil",
+ "profile.submit": "Gönder",
+ "profile.title": "Profil Ayarları",
+ "profile.updateSuccess": "Profil güncellendi.",
+ "titles.about": "Hakkında",
+ "titles.actions": "Eylemler",
+ "titles.appearance": "Görünüm",
+ "titles.feeds": "Beslemeler",
+ "titles.general": "Genel",
+ "titles.integration": "Entegrasyon",
+ "titles.invitations": "Davetler",
+ "titles.power": "Power",
+ "titles.profile": "Profil",
+ "titles.shortcuts": "Kısayollar",
+ "wallet.address.title": "Adresiniz",
+ "wallet.balance.title": "Bakiyeniz",
+ "wallet.balance.withdrawable": "Çekilebilir",
+ "wallet.balance.withdrawableTooltip": "Çekilebilir Power, aldığınız bahşişleri ve yeniden yüklediğiniz Power'ı içerir.",
+ "wallet.claim.button.claim": "Günlük Power'ı Al",
+ "wallet.claim.button.claimed": "Bugün alındı",
+ "wallet.claim.tooltip.alreadyClaimed": "Bugün zaten aldınız.",
+ "wallet.claim.tooltip.canClaim": "{{amount}} Günlük Power'ınızı şimdi alın!",
+ "wallet.create.button": "Cüzdan Oluştur",
+ "wallet.create.description": "İçerik katkılarınız için ödüllendirilmek ve ayrıca içerik oluşturucuları ödüllendirmek için kullanılabilecek Power almak için ücretsiz bir cüzdan oluşturun.",
+ "wallet.power.dailyClaim": "Günlük olarak {{amount}} ücretsiz Power alabilirsiniz, bu Follow'da RSS girdilerine bahşiş vermek için kullanılabilir.",
+ "wallet.power.description": "Power, {{blockchainName}} blok zincirinde bir ERC-20 token'dır.",
+ "wallet.sidebar_title": "Power",
+ "wallet.transactions.amount": "Miktar",
+ "wallet.transactions.date": "Tarih",
+ "wallet.transactions.from": "Gönderen",
+ "wallet.transactions.noTransactions": "İşlem yok",
+ "wallet.transactions.title": "İşlemler",
+ "wallet.transactions.to": "Alıcı",
+ "wallet.transactions.tx": "İşlem",
+ "wallet.transactions.type": "Tür",
+ "wallet.transactions.types.burn": "yakma",
+ "wallet.transactions.types.mint": "basma",
+ "wallet.transactions.types.purchase": "satın alma",
+ "wallet.transactions.types.tip": "bahşiş",
+ "wallet.transactions.types.withdraw": "çekme",
+ "wallet.transactions.you": "Siz",
+ "wallet.withdraw.addressLabel": "Ethereum Adresiniz",
+ "wallet.withdraw.amountLabel": "Miktar",
+ "wallet.withdraw.availableBalance": "Cüzdanınızda çekilebilir Power var.",
+ "wallet.withdraw.button": "Çek",
+ "wallet.withdraw.error": "Çekme işlemi başarısız oldu: {{error}}",
+ "wallet.withdraw.modalTitle": "Power Çek",
+ "wallet.withdraw.submitButton": "Gönder",
+ "wallet.withdraw.success": "Çekme işlemi başarılı!"
+}
diff --git a/locales/shortcuts/tr.json b/locales/shortcuts/tr.json
new file mode 100644
index 0000000000..5a104e6479
--- /dev/null
+++ b/locales/shortcuts/tr.json
@@ -0,0 +1,24 @@
+{
+ "keys.audio.playPause": "Oynat/Duraklat (Ses oynatıcı açıkken)",
+ "keys.entries.markAllAsRead": "Tümünü Okundu Olarak İşaretle",
+ "keys.entries.next": "Sonraki Girdi",
+ "keys.entries.previous": "Önceki Girdi",
+ "keys.entries.refetch": "Yeniden Getir",
+ "keys.entries.toggleUnreadOnly": "Sadece Okunmamışları Göster/Gizle",
+ "keys.entry.copyLink": "Bağlantıyı Kopyala",
+ "keys.entry.openInBrowser": "Tarayıcıda Aç",
+ "keys.entry.openInNewTab": "Yeni Sekmede Aç",
+ "keys.entry.scrollDown": "Aşağı Kaydır",
+ "keys.entry.scrollUp": "Yukarı Kaydır",
+ "keys.entry.share": "Paylaş",
+ "keys.entry.tip": "Bahşiş Gücü",
+ "keys.entry.toggleRead": "Okundu/Okunmadı Olarak İşaretle",
+ "keys.entry.toggleStarred": "Yıldızlı/Yıldızsız Olarak İşaretle",
+ "keys.entry.tts": "Metinden Sese Oynat",
+ "keys.feeds.add": "Abonelik Ekle",
+ "keys.feeds.switchBetweenViews": "Görünümler Arası Geçiş",
+ "keys.feeds.switchToView": "Görünüme Geç",
+ "keys.layout.showShortcuts": "Kısayolları Göster/Gizle",
+ "keys.layout.toggleSidebar": "Besleme Kenar Çubuğunu Göster/Gizle",
+ "sidebar_title": "Kısayollar"
+}
diff --git a/packages/shared/src/bridge.ts b/packages/shared/src/bridge.ts
index 31a6a3237b..d7192b3e2c 100644
--- a/packages/shared/src/bridge.ts
+++ b/packages/shared/src/bridge.ts
@@ -4,6 +4,7 @@ import type { toast } from "sonner"
import type { GeneralSettings, UISettings } from "./interface/settings"
const PREFIX = "__follow"
+
interface RenderGlobalContext {
showSetting: (path?: string) => void
getGeneralSettings: () => GeneralSettings
@@ -19,22 +20,32 @@ export const registerGlobalContext = (context: RenderGlobalContext) => {
globalThis[PREFIX] = context
}
-export function callGlobalContextMethod(
- window: BrowserWindow,
- method: T,
-
- // @ts-expect-error
- args: Parameters = [] as any,
-): Promise>
-export function callGlobalContextMethod(window: BrowserWindow, method: string, args?: any[]): void
-
-export function callGlobalContextMethod(
- window: BrowserWindow,
- method: T,
-
- args: Parameters = [] as any,
-) {
- return window.webContents.executeJavaScript(
- `globalThis.${PREFIX}.${method}(${args.map((arg) => JSON.stringify(arg)).join(",")})`,
- )
+function createProxy(window: BrowserWindow, path: string[] = []): T {
+ return new Proxy((() => {}) as any, {
+ get(_, prop: string) {
+ const newPath = [...path, prop]
+
+ return createProxy(window, newPath)
+ },
+ apply(_, __, args: any[]) {
+ const methodPath = path.join(".")
+
+ return window.webContents.executeJavaScript(
+ `globalThis.${PREFIX}.${methodPath}(${args.map((arg) => JSON.stringify(arg)).join(",")})`,
+ )
+ },
+ })
+}
+type AddPromise = T extends (...args: infer A) => Promise
+ ? (...args: A) => Promise
+ : T extends (...args: infer A) => infer R
+ ? (...args: A) => Promise>
+ : any
+
+type Fn = {
+ [K in keyof T]: AddPromise &
+ (T[K] extends object ? { [P in keyof T[K]]: AddPromise } : never)
+}
+export function callWindowExpose(window: BrowserWindow) {
+ return createProxy(window) as Fn
}