Explorar el Código

feat:多语言,新增广告id

kailen hace 1 mes
padre
commit
6419976b6b

+ 3 - 3
Podfile.lock

@@ -178,7 +178,7 @@ CHECKOUT OPTIONS:
     :git: https://gitee.com/WanlanNeel/tsvideo-kit.git
 
 SPEC CHECKSUMS:
-  ADManager: 82b2c255aadfb314141275088e13287ccc3dcd14
+  ADManager: 69cd1b8805b2e64a72315ed2abfa1f1c02f8f879
   AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58
   Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
   BetterSegmentedControl: 09607b27861d49cbce48b7673b74f9150a3d371a
@@ -198,11 +198,11 @@ SPEC CHECKSUMS:
   SJVideoPlayer: 4f09814f58522e0975cb2dccfda925f6c8643467
   SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
   SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
-  TSVideoKit: 922402ea051d72e78224f22d37c10fdb2e378f60
+  TSVideoKit: 16761d4bf8bb9e8af192459ae9eb01a213fc1531
   TYCyclePagerView: 2b051dade0615c70784aa34f40c646feeddb7344
   TZImagePickerController: d084a7b97c82d387e7669dd86dc9a9057500aacf
   YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
 
 PODFILE CHECKSUM: 436b32429cb708cca90f47b70a0a376c1a6e0417
 
-COCOAPODS: 1.16.2
+COCOAPODS: 1.15.2

+ 34 - 0
TSLiveWallpaper.xcodeproj/project.pbxproj

@@ -109,6 +109,7 @@
 		606372E32D55A995005C82CF /* ADLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606372E22D55A995005C82CF /* ADLoadingViewController.swift */; };
 		606372E52D55BAB8005C82CF /* GuideBubbleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606372E42D55BAB8005C82CF /* GuideBubbleView.swift */; };
 		606372E72D5705F4005C82CF /* MusicPlaylistContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 606372E62D5705F4005C82CF /* MusicPlaylistContainerViewController.swift */; };
+		609B6EA52D6F1221007942D4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 609B6EA32D6F1221007942D4 /* Localizable.strings */; };
 		60F82C0F2D43295100FFB08D /* MusicHomeContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60F82C0E2D43295100FFB08D /* MusicHomeContainerViewController.swift */; };
 		60F82C112D43298800FFB08D /* MusicContainerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60F82C102D43298800FFB08D /* MusicContainerViewModel.swift */; };
 		A81CA4652D15685F00A3AAC8 /* TSLaunchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81CA4642D15685D00A3AAC8 /* TSLaunchVC.swift */; };
@@ -317,6 +318,15 @@
 		606372E22D55A995005C82CF /* ADLoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADLoadingViewController.swift; sourceTree = "<group>"; };
 		606372E42D55BAB8005C82CF /* GuideBubbleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuideBubbleView.swift; sourceTree = "<group>"; };
 		606372E62D5705F4005C82CF /* MusicPlaylistContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicPlaylistContainerViewController.swift; sourceTree = "<group>"; };
+		609B6E9F2D6F11D0007942D4 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
+		609B6EA02D6F11D5007942D4 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
+		609B6EA12D6F11E0007942D4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
+		609B6EA22D6F11E6007942D4 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
+		609B6EA42D6F1221007942D4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
+		609B6EA62D6F1227007942D4 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
+		609B6EA72D6F1230007942D4 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
+		609B6EA82D6F1231007942D4 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; };
+		609B6EA92D6F1231007942D4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
 		60F82C0E2D43295100FFB08D /* MusicHomeContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicHomeContainerViewController.swift; sourceTree = "<group>"; };
 		60F82C102D43298800FFB08D /* MusicContainerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicContainerViewModel.swift; sourceTree = "<group>"; };
 		71E5F623537702A8306DF3C8 /* Pods-TSLiveWallpaper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TSLiveWallpaper.release.xcconfig"; path = "Target Support Files/Pods-TSLiveWallpaper/Pods-TSLiveWallpaper.release.xcconfig"; sourceTree = "<group>"; };
@@ -1168,6 +1178,7 @@
 				A8E56BED2D1520EC003C54AF /* Assets.xcassets */,
 				A8E56BEE2D1520EC003C54AF /* Info.plist */,
 				A8E56BF02D1520EC003C54AF /* LaunchScreen.storyboard */,
+				609B6EA32D6F1221007942D4 /* Localizable.strings */,
 			);
 			path = TSLiveWallpaper;
 			sourceTree = "<group>";
@@ -1270,6 +1281,10 @@
 			knownRegions = (
 				en,
 				Base,
+				de,
+				fr,
+				es,
+				"pt-PT",
 			);
 			mainGroup = A8E56BCB2D1520DD003C54AF;
 			minimizedProjectReferenceProxies = 1;
@@ -1292,6 +1307,7 @@
 				606372D82D545E6C005C82CF /* Example Music.mp3 in Resources */,
 				A8C4C0A42D24218A003C46FC /* metadata.mov in Resources */,
 				60553FC42D3B528A00BAAD7F /* IJKPlayer.md in Resources */,
+				609B6EA52D6F1221007942D4 /* Localizable.strings in Resources */,
 				A8E56BF92D1520EC003C54AF /* Assets.xcassets in Resources */,
 				A81F5B522D19685900740085 /* response.json in Resources */,
 				A8E56BFB2D1520EC003C54AF /* LaunchScreen.storyboard in Resources */,
@@ -1565,10 +1581,26 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXVariantGroup section */
+		609B6EA32D6F1221007942D4 /* Localizable.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				609B6EA42D6F1221007942D4 /* en */,
+				609B6EA62D6F1227007942D4 /* fr */,
+				609B6EA72D6F1230007942D4 /* de */,
+				609B6EA82D6F1231007942D4 /* pt-PT */,
+				609B6EA92D6F1231007942D4 /* es */,
+			);
+			name = Localizable.strings;
+			sourceTree = "<group>";
+		};
 		A8E56BF02D1520EC003C54AF /* LaunchScreen.storyboard */ = {
 			isa = PBXVariantGroup;
 			children = (
 				A8E56BEF2D1520EC003C54AF /* Base */,
+				609B6E9F2D6F11D0007942D4 /* de */,
+				609B6EA02D6F11D5007942D4 /* fr */,
+				609B6EA12D6F11E0007942D4 /* es */,
+				609B6EA22D6F11E6007942D4 /* pt-PT */,
 			);
 			name = LaunchScreen.storyboard;
 			sourceTree = "<group>";
@@ -1661,6 +1693,7 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
@@ -1724,6 +1757,7 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";

BIN
TSLiveWallpaper/Assets.xcassets/.DS_Store


+ 28 - 14
TSLiveWallpaper/Business/AdMob/ADScene.swift

@@ -16,20 +16,28 @@ import Foundation
 // TODO: !!!
 
 // #if DEBUG
-// private let GAD_ID_Launch                   = "ca-app-pub-3940256099942544/5575463023"
-// private let GAD_ID_Search_Insert            = "ca-app-pub-3940256099942544/4411468910"
-// private let GAD_ID_Play_Insert              = "ca-app-pub-3940256099942544/4411468910"
-// private let GAD_ID_Download_Reward          = "ca-app-pub-3940256099942544/1712485313"
+ private let GAD_ID_Launch                   = "ca-app-pub-3940256099942544/5575463023"
+ private let GAD_ID_Search_Insert            = "ca-app-pub-3940256099942544/4411468910"
+ private let GAD_ID_Play_Insert              = "ca-app-pub-3940256099942544/4411468910"
+ private let GAD_ID_Download_Reward          = "ca-app-pub-3940256099942544/1712485313"
+ private let GAD_ID_Playlist                 = "ca-app-pub-3940256099942544/4411468910"
+ private let GAD_ID_Pause                    = "ca-app-pub-3940256099942544/4411468910"
+
 // #else
 
-// 开屏广告
-private let GAD_ID_Launch = "ca-app-pub-4941656534177879/5488145330"
-// 点击搜索时弹出的插屏广告
-private let GAD_ID_Search_Insert = "ca-app-pub-4941656534177879/9397376852"
-// 播放视频时弹出的插屏广告
-private let GAD_ID_Play_Insert = "ca-app-pub-4941656534177879/2201413111"
-// 下载视频弹出的激励广告
-private let GAD_ID_Download_Reward = "ca-app-pub-4941656534177879/9888331446"
+//// 开屏广告
+//private let GAD_ID_Launch = "ca-app-pub-4941656534177879/5488145330"
+//// 点击搜索时弹出的插屏广告
+//private let GAD_ID_Search_Insert = "ca-app-pub-4941656534177879/9397376852"
+//// 播放视频时弹出的插屏广告
+//private let GAD_ID_Play_Insert = "ca-app-pub-4941656534177879/2201413111"
+//// 下载视频弹出的激励广告
+//private let GAD_ID_Download_Reward = "ca-app-pub-4941656534177879/9888331446"
+//// 歌单
+//private let GAD_ID_Playlist = "ca-app-pub-4941656534177879/3683573641"
+//// 暂停
+//private let GAD_ID_Pause = "ca-app-pub-4941656534177879/7350252261"
+
 // #endif
 
 enum ADScene: CaseIterable, ADSceneProtocol {
@@ -39,9 +47,11 @@ enum ADScene: CaseIterable, ADSceneProtocol {
     case searchInsert // 进入搜索,插屏广告
     case playInsert // 第一次进入视频播放,插屏广告
     case downloadReward // 下载视频,激励广告
+    case playlist
+    case pause
 
     static var prepareScenes: [ADScene] {
-        return [.searchInsert, .playInsert, .downloadReward]
+        return [.searchInsert, .playInsert, .downloadReward, .playlist, .pause]
     }
 
     var adId: String {
@@ -54,6 +64,10 @@ enum ADScene: CaseIterable, ADSceneProtocol {
             return GAD_ID_Play_Insert
         case .downloadReward:
             return GAD_ID_Download_Reward
+        case .playlist:
+            return GAD_ID_Playlist
+        case .pause:
+            return GAD_ID_Pause
         case .unknow:
             return ""
         }
@@ -63,7 +77,7 @@ enum ADScene: CaseIterable, ADSceneProtocol {
         switch self {
         case .launch:
             return .launch
-        case .searchInsert, .playInsert:
+        case .searchInsert, .playInsert, .playlist,.pause:
             return .interstitial
         case .downloadReward:
             return .reward

+ 2 - 2
TSLiveWallpaper/Business/TSMusic/Custom/BubbleMenuView.swift

@@ -65,11 +65,11 @@ class BubbleMenuView: UIView {
             make.height.equalTo(44)
         }
 
-        videoButton.setLocalizedImageAndTitle(image: UIImage(named: "ic-ring-import-video".localized()), title: "From Photo".localized(), for: .normal)
+        videoButton.setLocalizedImageAndTitle(image: UIImage(named: "ic-ring-import-video"), title: "From Photo".localized(), for: .normal)
         videoButton.setTitleColor(.white, for: .normal)
         videoButton.titleLabel?.font = .systemFont(ofSize: 14)
 
-        fileButton.setLocalizedImageAndTitle(image: UIImage(named: "ic-ring-import-file".localized()), title: "From Files".localized(), for: .normal)
+        fileButton.setLocalizedImageAndTitle(image: UIImage(named: "ic-ring-import-file"), title: "From Files".localized(), for: .normal)
         fileButton.setTitleColor(.white, for: .normal)
         fileButton.titleLabel?.font = .systemFont(ofSize: 14)
 

+ 1 - 1
TSLiveWallpaper/Business/TSMusic/Detail/PlayerManager.swift

@@ -89,7 +89,7 @@ class PlayerManager {
            player.playControl.player.isPlaying,
            let rootVc = rootVc {
             rootVc.presentingViewController?.dismiss(animated: false)
-//            ADManager.shared.showAd(scene: ADScene.pauseInsert, from: rootVc)
+            ADManager.shared.showAd(scene: ADScene.pause, from: rootVc)
         }
         player.playControl.pauseOrPlay()
     }

+ 1 - 1
TSLiveWallpaper/Business/TSMusic/Helper/CWOperateViewController.swift

@@ -26,7 +26,7 @@ class CWOperateViewController: LWBaseViewController {
     lazy var songlistCell: OperateTopView = OperateTopView()
     lazy var bgView: UIView = .simpleView(color: .hexColor("#222222"))
     lazy var vStack: UIStackView = .vStack
-    lazy var likeItem: CWOperateItemView = .init(imgName: "ic_like_n", title: "Add to like", type: .like)
+    lazy var likeItem: CWOperateItemView = .init(imgName: "ic_like_n", title: "Add to like".localized(), type: .like)
     lazy var addPlaylistItem: CWOperateItemView = .init(imgName: "ic_add_playlist", title: "Add to playlist".localized(), type: .addPlaylist)
     lazy var removeFromPlaylist: CWOperateItemView = .init(imgName: "ic_remove_playlist", title: "Remove from playlist".localized(), type: .removeFromPlaylist)
     lazy var shareItem: CWOperateItemView = .init(imgName: "ic_share", title: "Share".localized(), type: .share)

+ 14 - 14
TSLiveWallpaper/Business/TSMusic/PlayList/Controller/PlaylistViewController.swift

@@ -5,6 +5,7 @@
 //  Created by ni on 2024/9/18.
 //
 
+import ADManager
 import Combine
 import Foundation
 import TSVideoKit
@@ -55,7 +56,6 @@ class PlaylistViewController: LWBGViewController, UITableViewDelegate {
 
         NotificationCenter.default.addObserver(self, selector: #selector(reloadData), name: .K_RefreshNotifaction, object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(reloadData), name: kDataChangedNotifactionName, object: nil)
-
     }
 
     @objc func reloadData() {
@@ -110,19 +110,19 @@ class PlaylistViewController: LWBGViewController, UITableViewDelegate {
         } else if indexPath.section == 1 {
             showLikeViewController()
         } else {
-//            ADManager.shared.showAd(scene: ADScene.playlist, from: self) { state in
-//                if state == .finished || state == .fail {
-//                    if indexPath.row < self.viewModel.playLists.count {
-            let list = viewModel.playLists[indexPath.row]
-            let vModel: PlayListDetaiViewModel = .init()
-            vModel.playlist = list
-            vModel.listType = .playlist
-            let vc = PlaylistDetailViewController(viewModel: vModel)
-            vc.hidesBottomBarWhenPushed = true
-            navigationController?.pushViewController(vc, animated: true)
-//                    }
-//                }
-//            }
+            ADManager.shared.showAd(scene: ADScene.playlist, from: self) { state in
+                if state == .finished || state == .fail {
+                    if indexPath.row < self.viewModel.playLists.count {
+                        let list = self.viewModel.playLists[indexPath.row]
+                        let vModel: PlayListDetaiViewModel = .init()
+                        vModel.playlist = list
+                        vModel.listType = .playlist
+                        let vc = PlaylistDetailViewController(viewModel: vModel)
+                        vc.hidesBottomBarWhenPushed = true
+                        self.navigationController?.pushViewController(vc, animated: true)
+                    }
+                }
+            }
         }
     }
 

+ 4 - 4
TSLiveWallpaper/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift

@@ -160,7 +160,7 @@ class TSPurchaseVC: TSBaseVC {
                 case .verifyFail:
                 #if DEBUG
                     TSToastShared.hideLoading()
-                    let message = (object as? String) ?? "Verify receipt failed"
+                    let message = (object as? String) ?? "Verify receipt failed".localized()
                     TSToastShared.showToast(text:message)
 
                 #endif
@@ -220,16 +220,16 @@ struct PurchaseView :View {
                     VStack(alignment: .leading,spacing: 8) {
                         HStack(spacing: 8) {
                             Image("check").resizable().frame(width: 24, height: 24)
-                            Text("All Premium Wallpapers")
+                            Text("All Premium Wallpapers".localized())
                         }
                         HStack(spacing: 8) {
                             Image("check").resizable().frame(width: 24, height: 24)
-                            Text("Unlimited Video To Live")
+                            Text("Unlimited Video To Live".localized())
                         }
                         
                         HStack(spacing: 8) {
                             Image("check").resizable().frame(width: 24, height: 24)
-                            Text("100% No Ads").multilineTextAlignment(.leading)
+                            Text("100% No Ads".localized()).multilineTextAlignment(.leading)
                         }
                     }.font(.font(size: 16)).foregroundColor(UIColor.lesserText.color)
                 }

+ 6 - 3
TSLiveWallpaper/Business/TSTabBarController/TSTabBarController.swift

@@ -45,7 +45,10 @@ class TSTabBarController: UITabBarController {
     }
 
     @objc private func setUpData() {
-        viewControllerArray = ["MusicHomeContainerViewController","MusicPlaylistContainerViewController", "TSHomeVC", "TSMineVC"]
+        viewControllerArray = ["MusicHomeContainerViewController",
+                               "MusicPlaylistContainerViewController",
+                               "TSHomeVC",
+                               "TSMineVC"]
 
         selectedImageArray = [
             "tabbar_select_music",
@@ -55,8 +58,8 @@ class TSTabBarController: UITabBarController {
         ]
         unselectedImageArray = [
             "tabbar_unSelect_music",
-            "tabbar_unselect_playlist",
-            "tabbar_unSelect_home",
+            "tabbar_unSelect_playlist",
+            "tabbar_unSelect_random",
             "tabbar_unSelect_mine",
         ]
 

+ 1 - 2
TSLiveWallpaper/Common/Ex/NSString+Ex.swift

@@ -110,8 +110,7 @@ extension String {
 extension String {
     
     var localized:String{
-        return self
-//        return NSLocalizedString(self, comment: self)
+        return self.localized()
     }
 }
 

+ 1 - 0
TSLiveWallpaper/de.lproj/LaunchScreen.strings

@@ -0,0 +1 @@
+

+ 110 - 0
TSLiveWallpaper/de.lproj/Localizable.strings

@@ -0,0 +1,110 @@
+/* 
+  Localizable.strings
+  TSLiveWallpaper
+
+  Created by nkl on 2025/2/26.
+  
+*/
+
+/* Unlock Message */
+"It will be unlocked after an ad." = "Es wird nach einer Werbung freigeschaltet.";
+
+/* Unlocking */
+"Unlocking..." = "Wird freigeschaltet...";
+
+/* Loading */
+"Loading Failed" = "Laden fehlgeschlagen";
+
+/* Search */
+"Search" = "Suchen";
+
+/* Music */
+"No Music" = "Keine Musik";
+
+/* Network */
+"Network error, please check." = "Netzwerkfehler, bitte überprüfen.";
+
+/* Data */
+"No Data" = "Keine Daten";
+
+/* Reload */
+"Reload" = "Neu laden";
+
+/* Rename */
+"Rename" = "Umbenennen";
+
+/* Playlist */
+"Delete Playlist" = "Playlist löschen";
+"Create Playlist" = "Playlist erstellen";
+"Playlist Name" = "Playlist-Name";
+"input name" = "Name eingeben";
+"Playlist" = "Playlist";
+"Shuffle All" = "Alle mischen";
+
+/* Confirmation */
+"Are you sure to delete" = "Möchten Sie dies wirklich löschen?";
+
+/* Actions */
+"Like" = "Gefällt mir";
+"Delete" = "Löschen";
+"Add to Playlist" = "Zur Playlist hinzufügen";
+"Remove from playlist" = "Aus Playlist entfernen";
+"Created Successfully" = "Erfolgreich erstellt";
+"OK" = "OK";
+"Recently" = "Kürzlich";
+"Already Exists" = "Existiert bereits";
+"Up Next" = "Als Nächstes";
+"UnKnown" = "Unbekannt";
+"Select All" = "Alle auswählen";
+"Play All" = "Alle abspielen";
+"Done" = "Fertig";
+"Find your favorite songs" = "Finden Sie Ihre Lieblingssongs";
+"Sort By" = "Sortieren nach";
+"Ascending order by time" = "Aufsteigend nach Zeit";
+"Descending order by time" = "Absteigend nach Zeit";
+"Ascending order by name" = "Aufsteigend nach Name";
+"Descending order by name" = "Absteigend nach Name";
+"Add to like" = "Zu Favoriten hinzufügen";
+"Remove from like" = "Aus Favoriten entfernen";
+"Removed Successfully" = "Erfolgreich entfernt";
+"Added Successfully" = "Erfolgreich hinzugefügt";
+"Delete Successfully" = "Erfolgreich gelöscht";
+"Search Music" = "Musik suchen";
+"History" = "Verlauf";
+"Delete all" = "Alle löschen";
+"Sleep Mode" = "Schlafmodus";
+"Turn Off" = "Ausschalten";
+"Downloading" = "Wird heruntergeladen";
+"Retry" = "Erneut versuchen";
+"From Photo" = "Aus Foto";
+"From Files" = "Aus Dateien";
+"Go to Add" = "Zum Hinzufügen gehen";
+"Getting price" = "Preis wird abgerufen";
+"Get price failure, Will automatically retry in 5 seconds" = "Preisabruf fehlgeschlagen, automatischer Versuch in 5 Sekunden";
+"Purchasing now" = "Kauf wird durchgeführt";
+"Congratulation you have become VIP" = "Herzlichen Glückwunsch, Sie sind jetzt VIP";
+"Finish" = "Fertig";
+"Restoring now" = "Wird wiederhergestellt";
+"Couldn't Restore Subscription" = "Abonnement konnte nicht wiederhergestellt werden";
+"Failed to restore subscribe, please try again" = "Wiederherstellung des Abonnements fehlgeschlagen, bitte versuchen Sie es erneut";
+"Verify receipt failed" = "Überprüfung des Belegs fehlgeschlagen";
+"Continue" = "Fortsetzen";
+
+"Save Successfully" = "Erfolgreich gespeichert";
+"View" = "Anzeigen";
+"Create Live Wallpaper" = "Live-Hintergrund erstellen";
+"DIY Live Wallpaper" = "DIY Live-Hintergrund";
+"DIY Successfully" = "DIY erfolgreich";
+"Upload Video" = "Video hochladen";
+"How to set shuffle packs" = "Wie man Shuffle-Packs einstellt";
+"Save All" = "Alle speichern";
+"Upgrade" = "Upgrade";
+"Update" = "Aktualisieren";
+"Rate us" = "Bewerte uns";
+"Share us" = "Teile uns";
+"Privacy Policy" = "Datenschutzrichtlinie";
+"Terms of Service" = "Nutzungsbedingungen";
+"About us" = "Über uns";
+"Save" = "Speichern";
+"Save Fail" = "Speichern fehlgeschlagen";
+"ScreenRecorder unAvailable" = "Bildschirmrecorder nicht verfügbar";

+ 111 - 0
TSLiveWallpaper/en.lproj/Localizable.strings

@@ -0,0 +1,111 @@
+/* 
+  Localizable.strings
+  TSLiveWallpaper
+
+  Created by nkl on 2025/2/26.
+  
+*/
+
+/* Unlock Message */
+"It will be unlocked after an ad." = "It will be unlocked after an ad.";
+
+/* Unlocking */
+"Unlocking..." = "Unlocking...";
+
+/* Loading */
+"Loading Failed" = "Loading Failed";
+
+/* Search */
+"Search" = "Search";
+
+/* Music */
+"No Music" = "No Music";
+
+/* Network */
+"Network error, please check." = "Network error, please check.";
+
+/* Data */
+"No Data" = "No Data";
+
+/* Reload */
+"Reload" = "Reload";
+
+/* Rename */
+"Rename" = "Rename";
+
+/* Playlist */
+"Delete Playlist" = "Delete Playlist";
+"Create Playlist" = "Create Playlist";
+"Playlist Name" = "Playlist Name";
+"input name" = "input name";
+"Playlist" = "Playlist";
+"Shuffle All" = "Shuffle All";
+
+/* Confirmation */
+"Are you sure to delete" = "Are you sure to delete";
+
+/* Actions */
+"Like" = "Like";
+"Delete" = "Delete";
+"Add to Playlist" = "Add to Playlist";
+"Remove from playlist" = "Remove from playlist";
+"Created Successfully" = "Created Successfully";
+"OK" = "OK";
+"Recently" = "Recently";
+"Already Exists" = "Already Exists";
+"Up Next" = "Up Next";
+"UnKnown" = "UnKnown";
+"Select All" = "Select All";
+"Play All" = "Play All";
+"Done" = "Done";
+"Find your favorite songs" = "Find your favorite songs";
+"Sort By" = "Sort By";
+"Ascending order by time" = "Ascending order by time";
+"Descending order by time" = "Descending order by time";
+"Ascending order by name" = "Ascending order by name";
+"Descending order by name" = "Descending order by name";
+"Add to like" = "Add to like";
+"Remove from like" = "Remove from like";
+"Removed Successfully" = "Removed Successfully";
+"Added Successfully" = "Added Successfully";
+"Delete Successfully" = "Delete Successfully";
+"Search Music" = "Search Music";
+"History" = "History";
+"Delete all" = "Delete all";
+"Sleep Mode" = "Sleep Mode";
+"Turn Off" = "Turn Off";
+"Downloading" = "Downloading";
+"Retry" = "Retry";
+"From Photo" = "From Photo";
+"From Files" = "From Files";
+"Go to Add" = "Go to Add";
+"Getting price" = "Getting price";
+"Get price failure, Will automatically retry in 5 seconds" = "Get price failure, Will automatically retry in 5 seconds";
+"Purchasing now" = "Purchasing now";
+"Congratulation you have become VIP" = "Congratulation you have become VIP";
+"Finish" = "Finish";
+"Restoring now" = "Restoring now";
+"Couldn't Restore Subscription" = "Couldn't Restore Subscription";
+"Failed to restore subscribe, please try again" = "Failed to restore subscribe, please try again";
+"Verify receipt failed" = "Verify receipt failed";
+"Continue" = "Continue";
+
+
+"Save Successfully" = "Save Successfully";
+"View" = "View";
+"Create Live Wallpaper" = "Create Live Wallpaper";
+"DIY Live Wallpaper" = "DIY Live Wallpaper";
+"DIY Successfully" = "DIY Successfully";
+"Upload Video" = "Upload Video";
+"How to set shuffle packs" = "How to set shuffle packs";
+"Save All" = "Save All";
+"Upgrade" = "Upgrade";
+"Update" = "Update";
+"Rate us" = "Rate us";
+"Share us" = "Share us";
+"Privacy Policy" = "Privacy Policy";
+"Terms of Service" = "Terms of Service";
+"About us" = "About us";
+"Save" = "Save";
+"Save Fail" = "Save Fail";
+"ScreenRecorder unAvailable" = "ScreenRecorder unAvailable";

+ 1 - 0
TSLiveWallpaper/es.lproj/LaunchScreen.strings

@@ -0,0 +1 @@
+

+ 110 - 0
TSLiveWallpaper/es.lproj/Localizable.strings

@@ -0,0 +1,110 @@
+/* 
+  Localizable.strings
+  TSLiveWallpaper
+
+  Created by nkl on 2025/2/26.
+  
+*/
+/* Unlock Message */
+"It will be unlocked after an ad." = "Se desbloqueará después de un anuncio.";
+
+/* Unlocking */
+"Unlocking..." = "Desbloqueando...";
+
+/* Loading */
+"Loading Failed" = "Error al cargar";
+
+/* Search */
+"Search" = "Buscar";
+
+/* Music */
+"No Music" = "No hay música";
+
+/* Network */
+"Network error, please check." = "Error de red, por favor verifique.";
+
+/* Data */
+"No Data" = "No hay datos";
+
+/* Reload */
+"Reload" = "Recargar";
+
+/* Rename */
+"Rename" = "Renombrar";
+
+/* Playlist */
+"Delete Playlist" = "Eliminar lista de reproducción";
+"Create Playlist" = "Crear lista de reproducción";
+"Playlist Name" = "Nombre de la lista de reproducción";
+"input name" = "ingrese un nombre";
+"Playlist" = "Lista de reproducción";
+"Shuffle All" = "Mezclar todo";
+
+/* Confirmation */
+"Are you sure to delete" = "¿Estás seguro de eliminar?";
+
+/* Actions */
+"Like" = "Me gusta";
+"Delete" = "Eliminar";
+"Add to Playlist" = "Añadir a la lista de reproducción";
+"Remove from playlist" = "Eliminar de la lista de reproducción";
+"Created Successfully" = "Creado exitosamente";
+"OK" = "OK";
+"Recently" = "Recientemente";
+"Already Exists" = "Ya existe";
+"Up Next" = "A continuación";
+"UnKnown" = "Desconocido";
+"Select All" = "Seleccionar todo";
+"Play All" = "Reproducir todo";
+"Done" = "Hecho";
+"Find your favorite songs" = "Encuentra tus canciones favoritas";
+"Sort By" = "Ordenar por";
+"Ascending order by time" = "Orden ascendente por tiempo";
+"Descending order by time" = "Orden descendente por tiempo";
+"Ascending order by name" = "Orden ascendente por nombre";
+"Descending order by name" = "Orden descendente por nombre";
+"Add to like" = "Añadir a favoritos";
+"Remove from like" = "Eliminar de favoritos";
+"Removed Successfully" = "Eliminado exitosamente";
+"Added Successfully" = "Añadido exitosamente";
+"Delete Successfully" = "Eliminado exitosamente";
+"Search Music" = "Buscar música";
+"History" = "Historial";
+"Delete all" = "Eliminar todo";
+"Sleep Mode" = "Modo de suspensión";
+"Turn Off" = "Apagar";
+"Downloading" = "Descargando";
+"Retry" = "Reintentar";
+"From Photo" = "Desde la foto";
+"From Files" = "Desde archivos";
+"Go to Add" = "Ir a añadir";
+"Getting price" = "Obteniendo precio";
+"Get price failure, Will automatically retry in 5 seconds" = "Error al obtener el precio, se reintentará automáticamente en 5 segundos";
+"Purchasing now" = "Comprando ahora";
+"Congratulation you have become VIP" = "Felicidades, te has convertido en VIP";
+"Finish" = "Finalizar";
+"Restoring now" = "Restaurando ahora";
+"Couldn't Restore Subscription" = "No se pudo restaurar la suscripción";
+"Failed to restore subscribe, please try again" = "Error al restaurar la suscripción, por favor inténtalo de nuevo";
+"Verify receipt failed" = "Error al verificar el recibo";
+"Continue" = "Continuar";
+
+
+"Save Successfully" = "Guardado exitosamente";
+"View" = "Ver";
+"Create Live Wallpaper" = "Crear fondo de pantalla en vivo";
+"DIY Live Wallpaper" = "Fondo de pantalla en vivo DIY";
+"DIY Successfully" = "DIY exitoso";
+"Upload Video" = "Subir video";
+"How to set shuffle packs" = "Cómo configurar paquetes aleatorios";
+"Save All" = "Guardar todo";
+"Upgrade" = "Actualizar";
+"Update" = "Actualización";
+"Rate us" = "Califícanos";
+"Share us" = "Compártenos";
+"Privacy Policy" = "Política de Privacidad";
+"Terms of Service" = "Términos de Servicio";
+"About us" = "Sobre nosotros";
+"Save" = "Guardar";
+"Save Fail" = "Error al guardar";
+"ScreenRecorder unAvailable" = "Grabador de pantalla no disponible";

+ 1 - 0
TSLiveWallpaper/fr.lproj/LaunchScreen.strings

@@ -0,0 +1 @@
+

+ 110 - 0
TSLiveWallpaper/fr.lproj/Localizable.strings

@@ -0,0 +1,110 @@
+/* 
+  Localizable.strings
+  TSLiveWallpaper
+
+  Created by nkl on 2025/2/26.
+  
+*/
+
+/* Unlock Message */
+"It will be unlocked after an ad." = "Il sera débloqué après une publicité.";
+
+/* Unlocking */
+"Unlocking..." = "Déverrouillage...";
+
+/* Loading */
+"Loading Failed" = "Échec du chargement";
+
+/* Search */
+"Search" = "Rechercher";
+
+/* Music */
+"No Music" = "Aucune musique";
+
+/* Network */
+"Network error, please check." = "Erreur réseau, veuillez vérifier.";
+
+/* Data */
+"No Data" = "Aucune donnée";
+
+/* Reload */
+"Reload" = "Recharger";
+
+/* Rename */
+"Rename" = "Renommer";
+
+/* Playlist */
+"Delete Playlist" = "Supprimer la playlist";
+"Create Playlist" = "Créer une playlist";
+"Playlist Name" = "Nom de la playlist";
+"input name" = "saisir un nom";
+"Playlist" = "Playlist";
+"Shuffle All" = "Mélanger tout";
+
+/* Confirmation */
+"Are you sure to delete" = "Êtes-vous sûr de vouloir supprimer ?";
+
+/* Actions */
+"Like" = "J'aime";
+"Delete" = "Supprimer";
+"Add to Playlist" = "Ajouter à la playlist";
+"Remove from playlist" = "Retirer de la playlist";
+"Created Successfully" = "Créé avec succès";
+"OK" = "OK";
+"Recently" = "Récemment";
+"Already Exists" = "Existe déjà";
+"Up Next" = "À suivre";
+"UnKnown" = "Inconnu";
+"Select All" = "Tout sélectionner";
+"Play All" = "Tout lire";
+"Done" = "Terminé";
+"Find your favorite songs" = "Trouvez vos chansons préférées";
+"Sort By" = "Trier par";
+"Ascending order by time" = "Ordre croissant par temps";
+"Descending order by time" = "Ordre décroissant par temps";
+"Ascending order by name" = "Ordre croissant par nom";
+"Descending order by name" = "Ordre décroissant par nom";
+"Add to like" = "Ajouter aux favoris";
+"Remove from like" = "Retirer des favoris";
+"Removed Successfully" = "Retiré avec succès";
+"Added Successfully" = "Ajouté avec succès";
+"Delete Successfully" = "Supprimé avec succès";
+"Search Music" = "Rechercher de la musique";
+"History" = "Historique";
+"Delete all" = "Tout supprimer";
+"Sleep Mode" = "Mode veille";
+"Turn Off" = "Éteindre";
+"Downloading" = "Téléchargement en cours";
+"Retry" = "Réessayer";
+"From Photo" = "Depuis la photo";
+"From Files" = "Depuis les fichiers";
+"Go to Add" = "Aller à Ajouter";
+"Getting price" = "Obtention du prix";
+"Get price failure, Will automatically retry in 5 seconds" = "Échec de l'obtention du prix, nouvelle tentative automatique dans 5 secondes";
+"Purchasing now" = "Achat en cours";
+"Congratulation you have become VIP" = "Félicitations, vous êtes devenu VIP";
+"Finish" = "Terminer";
+"Restoring now" = "Restauration en cours";
+"Couldn't Restore Subscription" = "Impossible de restaurer l'abonnement";
+"Failed to restore subscribe, please try again" = "Échec de la restauration de l'abonnement, veuillez réessayer";
+"Verify receipt failed" = "Échec de la vérification du reçu";
+"Continue" = "Continuer";
+
+"Save Successfully" = "Enregistré avec succès";
+"View" = "Voir";
+"Create Live Wallpaper" = "Créer un fond d'écran animé";
+"DIY Live Wallpaper" = "Fond d'écran animé DIY";
+"DIY Successfully" = "DIY réussi";
+"Upload Video" = "Télécharger une vidéo";
+"How to set shuffle packs" = "Comment configurer les packs aléatoires";
+"Save All" = "Tout enregistrer";
+"Upgrade" = "Mettre à niveau";
+"Update" = "Mettre à jour";
+"Rate us" = "Évaluez-nous";
+"Share us" = "Partagez-nous";
+"Privacy Policy" = "Politique de confidentialité";
+"Terms of Service" = "Conditions d'utilisation";
+"About us" = "À propos de nous";
+"Save" = "Enregistrer";
+"Save Fail" = "Échec de l'enregistrement";
+"ScreenRecorder unAvailable" = "Enregistreur d'écran non disponible";

+ 1 - 0
TSLiveWallpaper/pt-PT.lproj/LaunchScreen.strings

@@ -0,0 +1 @@
+

+ 109 - 0
TSLiveWallpaper/pt-PT.lproj/Localizable.strings

@@ -0,0 +1,109 @@
+/* 
+  Localizable.strings
+  TSLiveWallpaper
+
+  Created by nkl on 2025/2/26.
+  
+*/
+/* Unlock Message */
+"It will be unlocked after an ad." = "Será desbloqueado após um anúncio.";
+
+/* Unlocking */
+"Unlocking..." = "Desbloqueando...";
+
+/* Loading */
+"Loading Failed" = "Falha ao carregar";
+
+/* Search */
+"Search" = "Pesquisar";
+
+/* Music */
+"No Music" = "Nenhuma música";
+
+/* Network */
+"Network error, please check." = "Erro de rede, por favor verifique.";
+
+/* Data */
+"No Data" = "Nenhum dado";
+
+/* Reload */
+"Reload" = "Recarregar";
+
+/* Rename */
+"Rename" = "Renomear";
+
+/* Playlist */
+"Delete Playlist" = "Excluir playlist";
+"Create Playlist" = "Criar playlist";
+"Playlist Name" = "Nome da playlist";
+"input name" = "insira o nome";
+"Playlist" = "Playlist";
+"Shuffle All" = "Embaralhar tudo";
+
+/* Confirmation */
+"Are you sure to delete" = "Tem certeza que deseja excluir?";
+
+/* Actions */
+"Like" = "Curtir";
+"Delete" = "Excluir";
+"Add to Playlist" = "Adicionar à playlist";
+"Remove from playlist" = "Remover da playlist";
+"Created Successfully" = "Criado com sucesso";
+"OK" = "OK";
+"Recently" = "Recentemente";
+"Already Exists" = "Já existe";
+"Up Next" = "A seguir";
+"UnKnown" = "Desconhecido";
+"Select All" = "Selecionar tudo";
+"Play All" = "Reproduzir tudo";
+"Done" = "Concluído";
+"Find your favorite songs" = "Encontre suas músicas favoritas";
+"Sort By" = "Ordenar por";
+"Ascending order by time" = "Ordem crescente por tempo";
+"Descending order by time" = "Ordem decrescente por tempo";
+"Ascending order by name" = "Ordem crescente por nome";
+"Descending order by name" = "Ordem decrescente por nome";
+"Add to like" = "Adicionar aos favoritos";
+"Remove from like" = "Remover dos favoritos";
+"Removed Successfully" = "Removido com sucesso";
+"Added Successfully" = "Adicionado com sucesso";
+"Delete Successfully" = "Excluído com sucesso";
+"Search Music" = "Pesquisar música";
+"History" = "Histórico";
+"Delete all" = "Excluir tudo";
+"Sleep Mode" = "Modo de espera";
+"Turn Off" = "Desligar";
+"Downloading" = "Baixando";
+"Retry" = "Tentar novamente";
+"From Photo" = "Da foto";
+"From Files" = "Dos arquivos";
+"Go to Add" = "Ir para adicionar";
+"Getting price" = "Obtendo preço";
+"Get price failure, Will automatically retry in 5 seconds" = "Falha ao obter preço, tentativa automática em 5 segundos";
+"Purchasing now" = "Comprando agora";
+"Congratulation you have become VIP" = "Parabéns, você se tornou VIP";
+"Finish" = "Concluir";
+"Restoring now" = "Restaurando agora";
+"Couldn't Restore Subscription" = "Não foi possível restaurar a assinatura";
+"Failed to restore subscribe, please try again" = "Falha ao restaurar a assinatura, por favor tente novamente";
+"Verify receipt failed" = "Falha ao verificar o recibo";
+"Continue" = "Continuar";
+
+"Save Successfully" = "Salvo com sucesso";
+"View" = "Ver";
+"Create Live Wallpaper" = "Criar papel de parede ao vivo";
+"DIY Live Wallpaper" = "Papel de parede ao vivo DIY";
+"DIY Successfully" = "DIY concluído com sucesso";
+"Upload Video" = "Carregar vídeo";
+"How to set shuffle packs" = "Como configurar pacotes aleatórios";
+"Save All" = "Salvar tudo";
+"Upgrade" = "Atualizar";
+"Update" = "Atualização";
+"Rate us" = "Avalie-nos";
+"Share us" = "Compartilhe-nos";
+"Privacy Policy" = "Política de Privacidade";
+"Terms of Service" = "Termos de Serviço";
+"About us" = "Sobre nós";
+"Save" = "Salvar";
+"Save Fail" = "Falha ao salvar";
+"ScreenRecorder unAvailable" = "Gravador de tela indisponível";