210 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Swift
		
	
	
	
		
		
			
		
	
	
			210 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Swift
		
	
	
	
|  | // | |||
|  | //  CLUI.swift | |||
|  | //  Crush | |||
|  | // | |||
|  | //  Created by Leon on 2025/7/11. | |||
|  | // | |||
|  | 
 | |||
|  | import Foundation | |||
|  | 
 | |||
|  | let EPConfigShadowPrefix = "@SHA:" | |||
|  | let EPConfigGradientPrefix = "@GRA:" | |||
|  | 
 | |||
|  | class CLBaseTokens { | |||
|  |     static var shared = CLBaseTokens() | |||
|  |     // MARK: - Properties | |||
|  |      | |||
|  |     var globalTokens: [String: Any]? | |||
|  |     var sysDarkTokens: [String: Any]? | |||
|  |     var sysLightTokens: [String: Any]? | |||
|  |      | |||
|  |     var globalKeys: [String]? | |||
|  |     var sysDarkKeys: [String]? | |||
|  |     var sysLightKeys: [String]? | |||
|  |      | |||
|  |     // MARK: - Singleton | |||
|  |     // static let shared = CLBaseTokens() | |||
|  |      | |||
|  |     init() { | |||
|  |         initialTokens() | |||
|  |     } | |||
|  |      | |||
|  |     // MARK: - Initial | |||
|  |     private func initialTokens() { | |||
|  |         // 加载 global tokens | |||
|  |         if let json1Path = Bundle.main.path(forResource: "token_global", ofType: "json"), | |||
|  |            let json1Data = try? Data(contentsOf: URL(fileURLWithPath: json1Path)), | |||
|  |            let dict1 = try? JSONSerialization.jsonObject(with: json1Data, options: []) as? [String: Any] { | |||
|  |             globalTokens = dict1 | |||
|  |             globalKeys = dict1.keys.sorted() | |||
|  |             //assert(dict1 != nil, "json should be valid") | |||
|  |         } | |||
|  |          | |||
|  |         // 加载 sysDark tokens | |||
|  |         if let json2Path = Bundle.main.path(forResource: "token_sys_normal", ofType: "json"), | |||
|  |            let json2Data = try? Data(contentsOf: URL(fileURLWithPath: json2Path)), | |||
|  |            let dict2 = try? JSONSerialization.jsonObject(with: json2Data, options: []) as? [String: Any] { | |||
|  |             sysDarkTokens = dict2 | |||
|  |             sysDarkKeys = dict2.keys.sorted() | |||
|  |         } | |||
|  |          | |||
|  |         assert(sysDarkTokens != nil) | |||
|  |     } | |||
|  |      | |||
|  |     // MARK: - Public Methods | |||
|  |      | |||
|  |     /// ⚠️ 只针对单 token 的情况,保留此方法,不推荐使用 | |||
|  |     func getTokenByKey(_ key: String) -> String { | |||
|  |         var value: String? | |||
|  |          | |||
|  |         if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) { | |||
|  |             value = sysDarkTokens?[key] as? String | |||
|  |         } | |||
|  |          | |||
|  |         if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { | |||
|  |             value = globalTokens?[key] as? String | |||
|  |         } | |||
|  |          | |||
|  |         guard let finalValue = value else { | |||
|  |             print("\(key) UI Token Key may doesn't exist") | |||
|  |             return "" | |||
|  |         } | |||
|  |          | |||
|  |         if finalValue.contains("$") { | |||
|  |             let keyNew = finalValue.replacingOccurrences(of: "$", with: "") | |||
|  |             return getTokenByKey(keyNew) | |||
|  |         } | |||
|  |          | |||
|  |         return finalValue | |||
|  |     } | |||
|  |      | |||
|  |     func getTokensByKey(_ key: String) -> [String] { | |||
|  |         var value: String? | |||
|  |          | |||
|  | 
 | |||
|  |         if let sysKeys = sysDarkKeys { | |||
|  |             if sysKeys.contains(key){ | |||
|  |                 value = sysDarkTokens?[key] as? String | |||
|  |             } | |||
|  |         } | |||
|  |          | |||
|  |         if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { | |||
|  |             value = globalTokens?[key] as? String | |||
|  |         } | |||
|  |          | |||
|  |         guard let finalValue = value else { | |||
|  |             print("❌\(key)❌ UI Token Key doesn't exist ❌❌") | |||
|  |             return [] | |||
|  |         } | |||
|  |          | |||
|  |         let params = finalValue.components(separatedBy: ",") | |||
|  |         var arrayM: [String] = [] | |||
|  |          | |||
|  |         for per in params { | |||
|  |             let dealPer = per.trimmingCharacters(in: .whitespacesAndNewlines) | |||
|  |             if dealPer.contains("$") { | |||
|  |                 var keyNew = dealPer | |||
|  |                 keyNew = keyNew.replacingOccurrences(of: EPConfigShadowPrefix, with: "") | |||
|  |                 keyNew = keyNew.replacingOccurrences(of: EPConfigGradientPrefix, with: "") | |||
|  |                  | |||
|  |                 if keyNew.contains("&") { | |||
|  |                     let keys = keyNew.components(separatedBy: "&") | |||
|  |                     var multi: [String] = [] | |||
|  |                      | |||
|  |                     for perKey in keys { | |||
|  |                         let keyNew2 = perKey.replacingOccurrences(of: "$", with: "") | |||
|  |                         let value = getTokenByKey(keyNew2) | |||
|  |                         multi.append(value) | |||
|  |                     } | |||
|  |                      | |||
|  |                     let covertValues = multi.joined(separator: "&") | |||
|  |                     arrayM.append(covertValues) | |||
|  |                 } else { | |||
|  |                     var values: [String] = [] | |||
|  |                     var tempKey = keyNew | |||
|  |                     while tempKey.contains("$") { | |||
|  |                         tempKey = tempKey.replacingOccurrences(of: "$", with: "") | |||
|  |                         values = getTokensByKey(tempKey) | |||
|  |                         arrayM.append(contentsOf: values) | |||
|  |                     } | |||
|  |                 } | |||
|  |             } else { | |||
|  |                 arrayM.append(dealPer) | |||
|  |             } | |||
|  |         } | |||
|  |          | |||
|  |         return arrayM | |||
|  |     } | |||
|  |      | |||
|  |     // MARK: - Always Dark | |||
|  |      | |||
|  |     /// ⚠️ 只针对单 token 的情况,保留此方法,不推荐使用 | |||
|  |     func getDarkToken(_ key: String) -> String { | |||
|  |         var value: String? | |||
|  |          | |||
|  |         if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) { | |||
|  |             value = sysDarkTokens?[key] as? String | |||
|  |         } | |||
|  |          | |||
|  |         if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { | |||
|  |             value = globalTokens?[key] as? String | |||
|  |         } | |||
|  |          | |||
|  |         guard let finalValue = value else { | |||
|  |             print("❌\(key)❌ UI Token Key doesn't exist ❌❌") | |||
|  |             return "" | |||
|  |         } | |||
|  |          | |||
|  |         if finalValue.contains("$") { | |||
|  |             let keyNew = finalValue.replacingOccurrences(of: "$", with: "") | |||
|  |             return getTokenByKey(keyNew) | |||
|  |         } | |||
|  |          | |||
|  |         return finalValue | |||
|  |     } | |||
|  |      | |||
|  |     func getDarkTokens(_ key: String) -> [String] { | |||
|  |         var value: String? | |||
|  |          | |||
|  |         if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) { | |||
|  |             value = sysDarkTokens?[key] as? String | |||
|  |         } | |||
|  |          | |||
|  |         if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) { | |||
|  |             value = globalTokens?[key] as? String | |||
|  |         } | |||
|  |          | |||
|  |         guard let finalValue = value else { | |||
|  |             print("❌\(key)❌ UI Token Key doesn't exist ❌❌") | |||
|  |             return [] | |||
|  |         } | |||
|  |          | |||
|  |         let params = finalValue.components(separatedBy: ",") | |||
|  |         var arrayM: [String] = [] | |||
|  |          | |||
|  |         for per in params { | |||
|  |             let dealPer = per.trimmingCharacters(in: .whitespacesAndNewlines) | |||
|  |             if dealPer.contains("$") { | |||
|  |                 var keyNew = dealPer | |||
|  |                 keyNew = keyNew.replacingOccurrences(of: EPConfigShadowPrefix, with: "") | |||
|  |                 keyNew = keyNew.replacingOccurrences(of: EPConfigGradientPrefix, with: "") | |||
|  |                  | |||
|  |                 var values: [String] = [] | |||
|  |                 while keyNew.contains("$") { | |||
|  |                     keyNew = keyNew.replacingOccurrences(of: "$", with: "") | |||
|  |                     values = getTokensByKey(keyNew) | |||
|  |                     arrayM.append(contentsOf: values) | |||
|  |                 } | |||
|  |             } else { | |||
|  |                 arrayM.append(dealPer) | |||
|  |             } | |||
|  |         } | |||
|  |          | |||
|  |         return arrayM | |||
|  |     } | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 |