فهرست منبع

Fix Hebrew and Arabic RTL layout across the app.

Apply mirrored sidebar rows, trailing-edge placement, and layout-direction helpers so icons, text, and navigation align correctly for RTL languages.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 ماه پیش
والد
کامیت
8a2b3f515b

+ 1 - 0
meetings_app/AppDelegate.swift

@@ -14,6 +14,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
     private var statusBarController: StatusBarController?
 
     func applicationDidFinishLaunching(_ aNotification: Notification) {
+        AppLanguageManager.applyGlobalLayoutDirection()
         // Always sync to current macOS appearance on launch.
         // (User can still toggle in-app later.)
         let darkEnabled = systemPrefersDarkMode()

+ 4 - 2
meetings_app/LaunchSplashView.swift

@@ -83,6 +83,7 @@ final class LaunchSplashView: NSView {
 
     private func setupView() {
         translatesAutoresizingMaskIntoConstraints = false
+        AppLanguageManager.applyLayoutDirection(to: self)
 
         iconView.translatesAutoresizingMaskIntoConstraints = false
         iconView.imageScaling = .scaleProportionallyUpOrDown
@@ -102,11 +103,12 @@ final class LaunchSplashView: NSView {
         loadingFillView.translatesAutoresizingMaskIntoConstraints = false
 
         statusLabel.translatesAutoresizingMaskIntoConstraints = false
-        statusLabel.alignment = .left
+        statusLabel.alignment = AppLanguageManager.textAlignment
+        statusLabel.baseWritingDirection = AppLanguageManager.baseWritingDirection
         statusLabel.font = NSFont.monospacedSystemFont(ofSize: 10, weight: .semibold)
 
         percentLabel.translatesAutoresizingMaskIntoConstraints = false
-        percentLabel.alignment = .right
+        percentLabel.alignment = AppLanguageManager.trailingEdgeTextAlignment
         percentLabel.font = NSFont.monospacedDigitSystemFont(ofSize: 10, weight: .semibold)
 
         taglineLabel.translatesAutoresizingMaskIntoConstraints = false

+ 68 - 0
meetings_app/Localization/AppLanguageManager.swift

@@ -1,3 +1,4 @@
+import AppKit
 import Foundation
 
 extension Notification.Name {
@@ -130,11 +131,78 @@ enum AppLanguageManager {
         }
     }
 
+    /// Locale identifier used for layout direction (selected language or system default).
+    static var activeLanguageIdentifier: String {
+        if let code = selectedLanguageCode {
+            return code
+        }
+        return Locale.preferredLanguages.first ?? Locale.current.identifier
+    }
+
+    static var isRightToLeft: Bool {
+        let identifier = activeLanguageIdentifier
+        let locale = Locale(identifier: identifier)
+        let languageCode = locale.languageCode
+            ?? identifier.split(whereSeparator: { $0 == "-" || $0 == "_" }).first.map(String.init)
+            ?? identifier
+        if languageCode == "ar" || languageCode == "he" {
+            return true
+        }
+        return Locale.characterDirection(forLanguage: languageCode) == .rightToLeft
+    }
+
+    static var userInterfaceLayoutDirection: NSUserInterfaceLayoutDirection {
+        isRightToLeft ? .rightToLeft : .leftToRight
+    }
+
+    static var baseWritingDirection: NSWritingDirection {
+        isRightToLeft ? .rightToLeft : .leftToRight
+    }
+
+    static var textAlignment: NSTextAlignment {
+        isRightToLeft ? .right : .left
+    }
+
+    /// Alignment for labels pinned to the trailing edge (e.g. numeric counters).
+    static var trailingEdgeTextAlignment: NSTextAlignment {
+        isRightToLeft ? .left : .right
+    }
+
+    static var disclosureChevron: String {
+        isRightToLeft ? "‹" : "›"
+    }
+
+    static func applyGlobalLayoutDirection() {
+        for window in NSApp.windows {
+            if let contentView = window.contentView {
+                applyLayoutDirection(to: contentView)
+            }
+        }
+    }
+
+    static func configureTextFieldForLayout(_ field: NSTextField, alignment: NSTextAlignment? = nil) {
+        field.alignment = alignment ?? textAlignment
+        field.baseWritingDirection = baseWritingDirection
+        field.userInterfaceLayoutDirection = userInterfaceLayoutDirection
+    }
+
+    static func configureContainerForLayout(_ view: NSView) {
+        view.userInterfaceLayoutDirection = userInterfaceLayoutDirection
+    }
+
+    static func applyLayoutDirection(to view: NSView) {
+        view.userInterfaceLayoutDirection = userInterfaceLayoutDirection
+        for subview in view.subviews {
+            applyLayoutDirection(to: subview)
+        }
+    }
+
     static func setLanguage(code: String?) {
         let normalized = code?.trimmingCharacters(in: .whitespacesAndNewlines)
         let cleaned = (normalized?.isEmpty == false) ? normalized : nil
         guard cleaned != selectedLanguageCode else { return }
         selectedLanguageCode = cleaned
+        applyGlobalLayoutDirection()
         NotificationCenter.default.post(name: .appLanguageDidChange, object: nil)
     }
 }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 207 - 171
meetings_app/ViewController.swift


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است