Compare commits
2 Commits
54742c4a67
...
8bbb3d10ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bbb3d10ad | ||
|
|
e0163dabe3 |
@ -17,6 +17,29 @@
|
|||||||
031FDEBA2EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEB92EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift */; };
|
031FDEBA2EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEB92EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift */; };
|
||||||
031FDEBC2EB0C97A00F4CAC7 /* FAOldVideoRechargeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEBB2EB0C97A00F4CAC7 /* FAOldVideoRechargeView.swift */; };
|
031FDEBC2EB0C97A00F4CAC7 /* FAOldVideoRechargeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEBB2EB0C97A00F4CAC7 /* FAOldVideoRechargeView.swift */; };
|
||||||
031FDEBE2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEBD2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift */; };
|
031FDEBE2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEBD2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift */; };
|
||||||
|
031FDEC02EB1C08900F4CAC7 /* FAMeCoinsPackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEBF2EB1C08900F4CAC7 /* FAMeCoinsPackButton.swift */; };
|
||||||
|
031FDEC22EB1E19D00F4CAC7 /* FACoinPackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEC12EB1E19D00F4CAC7 /* FACoinPackViewController.swift */; };
|
||||||
|
031FDEC42EB1E45300F4CAC7 /* FACoinPackHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEC32EB1E45300F4CAC7 /* FACoinPackHeaderView.swift */; };
|
||||||
|
031FDEC62EB1E4E600F4CAC7 /* FACoinPackTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEC52EB1E4E600F4CAC7 /* FACoinPackTitleView.swift */; };
|
||||||
|
031FDEC82EB1F89F00F4CAC7 /* FACoinsPackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEC72EB1F89F00F4CAC7 /* FACoinsPackModel.swift */; };
|
||||||
|
031FDECA2EB1F8F200F4CAC7 /* FACoinsPackReceiveModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEC92EB1F8F200F4CAC7 /* FACoinsPackReceiveModel.swift */; };
|
||||||
|
031FDECC2EB1FDF500F4CAC7 /* FACoinsPackClaimListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDECB2EB1FDF500F4CAC7 /* FACoinsPackClaimListView.swift */; };
|
||||||
|
031FDECE2EB2006000F4CAC7 /* FACoinsPackClaimListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDECD2EB2006000F4CAC7 /* FACoinsPackClaimListCell.swift */; };
|
||||||
|
031FDED02EB2167200F4CAC7 /* FACoinsPackBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDECF2EB2167200F4CAC7 /* FACoinsPackBuyView.swift */; };
|
||||||
|
031FDED22EB2F69200F4CAC7 /* FALoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDED12EB2F69200F4CAC7 /* FALoginView.swift */; };
|
||||||
|
031FDED42EB2FF4000F4CAC7 /* FALogin+Apple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDED32EB2FF3A00F4CAC7 /* FALogin+Apple.swift */; };
|
||||||
|
031FDED62EB300F400F4CAC7 /* FAThirdSignModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDED52EB300F400F4CAC7 /* FAThirdSignModel.swift */; };
|
||||||
|
031FDED92EB30D6E00F4CAC7 /* FASettingCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 031FDED82EB30D6E00F4CAC7 /* FASettingCell.xib */; };
|
||||||
|
031FDEDA2EB30D6E00F4CAC7 /* FASettingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDED72EB30D6E00F4CAC7 /* FASettingCell.swift */; };
|
||||||
|
031FDEDC2EB3141E00F4CAC7 /* FASettingFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEDB2EB3141E00F4CAC7 /* FASettingFooterView.swift */; };
|
||||||
|
031FDEDF2EB3423000F4CAC7 /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 031FDEDE2EB3423000F4CAC7 /* FacebookLogin */; };
|
||||||
|
031FDEE12EB344AB00F4CAC7 /* FALogin+Facebook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEE02EB344A200F4CAC7 /* FALogin+Facebook.swift */; };
|
||||||
|
031FDEE42EB348AA00F4CAC7 /* FABaseAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEE32EB348AA00F4CAC7 /* FABaseAlert.swift */; };
|
||||||
|
031FDEE62EB34FBC00F4CAC7 /* FARemoveCollectAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEE52EB34FBC00F4CAC7 /* FARemoveCollectAlert.swift */; };
|
||||||
|
031FDEE82EB358AE00F4CAC7 /* FAHomeCoinsPackButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEE72EB358AE00F4CAC7 /* FAHomeCoinsPackButton.swift */; };
|
||||||
|
031FDEEA2EB35D2600F4CAC7 /* FACoinPackCanReceiveModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEE92EB35D2600F4CAC7 /* FACoinPackCanReceiveModel.swift */; };
|
||||||
|
031FDEEC2EB35DF600F4CAC7 /* FACoinsPackAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEEB2EB35DF600F4CAC7 /* FACoinsPackAlert.swift */; };
|
||||||
|
031FDEEE2EB3682000F4CAC7 /* FAVipRetainAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 031FDEED2EB3682000F4CAC7 /* FAVipRetainAlert.swift */; };
|
||||||
039CE6042EAA2621007B5EED /* AppDelegate+FAAdjust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */; };
|
039CE6042EAA2621007B5EED /* AppDelegate+FAAdjust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */; };
|
||||||
039CE6092EAA2F71007B5EED /* FAAdjustStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE6082EAA2F62007B5EED /* FAAdjustStateManager.swift */; };
|
039CE6092EAA2F71007B5EED /* FAAdjustStateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE6082EAA2F62007B5EED /* FAAdjustStateManager.swift */; };
|
||||||
039CE60B2EAA31CB007B5EED /* FAStatAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE60A2EAA31CB007B5EED /* FAStatAPI.swift */; };
|
039CE60B2EAA31CB007B5EED /* FAStatAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039CE60A2EAA31CB007B5EED /* FAStatAPI.swift */; };
|
||||||
@ -189,6 +212,11 @@
|
|||||||
03E23AB72EAA1A7F004A8CEC /* FALocalized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23A9C2EAA1A7F004A8CEC /* FALocalized.swift */; };
|
03E23AB72EAA1A7F004A8CEC /* FALocalized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23A9C2EAA1A7F004A8CEC /* FALocalized.swift */; };
|
||||||
03E23AB82EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AAA2EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift */; };
|
03E23AB82EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AAA2EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift */; };
|
||||||
03E23ABA2EAA1D85004A8CEC /* MNNItemController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AB92EAA1D85004A8CEC /* MNNItemController.swift */; };
|
03E23ABA2EAA1D85004A8CEC /* MNNItemController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AB92EAA1D85004A8CEC /* MNNItemController.swift */; };
|
||||||
|
03E9A7362EB44F26000D1067 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 03E9A7352EB44F26000D1067 /* FirebaseMessaging */; };
|
||||||
|
03E9A7382EB44F26000D1067 /* FirebasePerformance in Frameworks */ = {isa = PBXBuildFile; productRef = 03E9A7372EB44F26000D1067 /* FirebasePerformance */; };
|
||||||
|
03E9A73A2EB45154000D1067 /* AppDelegate+FAApns.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7392EB45149000D1067 /* AppDelegate+FAApns.swift */; };
|
||||||
|
03E9A73C2EB45507000D1067 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 03E9A73B2EB45507000D1067 /* GoogleService-Info.plist */; };
|
||||||
|
03E9A73E2EB460F2000D1067 /* FAApnsAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A73D2EB460F2000D1067 /* FAApnsAlert.swift */; };
|
||||||
B86XD3O90WO2R4725L084287 /* Pods_Fableon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */; };
|
B86XD3O90WO2R4725L084287 /* Pods_Fableon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */; };
|
||||||
F3019606DA7P36H41G408X13 /* ZStreamCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F38E33739F391364D0151P7Z /* ZStreamCell.swift */; };
|
F3019606DA7P36H41G408X13 /* ZStreamCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F38E33739F391364D0151P7Z /* ZStreamCell.swift */; };
|
||||||
F30470W590T8274E1642349G /* CControlCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32MR5F8X6Q3HSZ560BD0159 /* CControlCell.swift */; };
|
F30470W590T8274E1642349G /* CControlCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32MR5F8X6Q3HSZ560BD0159 /* CControlCell.swift */; };
|
||||||
@ -306,6 +334,28 @@
|
|||||||
031FDEB92EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinPackConfirmItem2View.swift; sourceTree = "<group>"; };
|
031FDEB92EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinPackConfirmItem2View.swift; sourceTree = "<group>"; };
|
||||||
031FDEBB2EB0C97A00F4CAC7 /* FAOldVideoRechargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAOldVideoRechargeView.swift; sourceTree = "<group>"; };
|
031FDEBB2EB0C97A00F4CAC7 /* FAOldVideoRechargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAOldVideoRechargeView.swift; sourceTree = "<group>"; };
|
||||||
031FDEBD2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FANewVideoRechargeView.swift; sourceTree = "<group>"; };
|
031FDEBD2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FANewVideoRechargeView.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEBF2EB1C08900F4CAC7 /* FAMeCoinsPackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAMeCoinsPackButton.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEC12EB1E19D00F4CAC7 /* FACoinPackViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinPackViewController.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEC32EB1E45300F4CAC7 /* FACoinPackHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinPackHeaderView.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEC52EB1E4E600F4CAC7 /* FACoinPackTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinPackTitleView.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEC72EB1F89F00F4CAC7 /* FACoinsPackModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinsPackModel.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEC92EB1F8F200F4CAC7 /* FACoinsPackReceiveModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinsPackReceiveModel.swift; sourceTree = "<group>"; };
|
||||||
|
031FDECB2EB1FDF500F4CAC7 /* FACoinsPackClaimListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinsPackClaimListView.swift; sourceTree = "<group>"; };
|
||||||
|
031FDECD2EB2006000F4CAC7 /* FACoinsPackClaimListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinsPackClaimListCell.swift; sourceTree = "<group>"; };
|
||||||
|
031FDECF2EB2167200F4CAC7 /* FACoinsPackBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinsPackBuyView.swift; sourceTree = "<group>"; };
|
||||||
|
031FDED12EB2F69200F4CAC7 /* FALoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALoginView.swift; sourceTree = "<group>"; };
|
||||||
|
031FDED32EB2FF3A00F4CAC7 /* FALogin+Apple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FALogin+Apple.swift"; sourceTree = "<group>"; };
|
||||||
|
031FDED52EB300F400F4CAC7 /* FAThirdSignModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAThirdSignModel.swift; sourceTree = "<group>"; };
|
||||||
|
031FDED72EB30D6E00F4CAC7 /* FASettingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FASettingCell.swift; sourceTree = "<group>"; };
|
||||||
|
031FDED82EB30D6E00F4CAC7 /* FASettingCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FASettingCell.xib; sourceTree = "<group>"; };
|
||||||
|
031FDEDB2EB3141E00F4CAC7 /* FASettingFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FASettingFooterView.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEE02EB344A200F4CAC7 /* FALogin+Facebook.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FALogin+Facebook.swift"; sourceTree = "<group>"; };
|
||||||
|
031FDEE32EB348AA00F4CAC7 /* FABaseAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FABaseAlert.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEE52EB34FBC00F4CAC7 /* FARemoveCollectAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FARemoveCollectAlert.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEE72EB358AE00F4CAC7 /* FAHomeCoinsPackButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAHomeCoinsPackButton.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEE92EB35D2600F4CAC7 /* FACoinPackCanReceiveModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinPackCanReceiveModel.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEEB2EB35DF600F4CAC7 /* FACoinsPackAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACoinsPackAlert.swift; sourceTree = "<group>"; };
|
||||||
|
031FDEED2EB3682000F4CAC7 /* FAVipRetainAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAVipRetainAlert.swift; sourceTree = "<group>"; };
|
||||||
039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+FAAdjust.swift"; sourceTree = "<group>"; };
|
039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+FAAdjust.swift"; sourceTree = "<group>"; };
|
||||||
039CE6082EAA2F62007B5EED /* FAAdjustStateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAAdjustStateManager.swift; sourceTree = "<group>"; };
|
039CE6082EAA2F62007B5EED /* FAAdjustStateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAAdjustStateManager.swift; sourceTree = "<group>"; };
|
||||||
039CE60A2EAA31CB007B5EED /* FAStatAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAStatAPI.swift; sourceTree = "<group>"; };
|
039CE60A2EAA31CB007B5EED /* FAStatAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAStatAPI.swift; sourceTree = "<group>"; };
|
||||||
@ -479,6 +529,9 @@
|
|||||||
03E23AA82EAA1A7F004A8CEC /* FAToast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAToast.swift; sourceTree = "<group>"; };
|
03E23AA82EAA1A7F004A8CEC /* FAToast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAToast.swift; sourceTree = "<group>"; };
|
||||||
03E23AAA2EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAWaterfallFlowLayout.swift; sourceTree = "<group>"; };
|
03E23AAA2EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAWaterfallFlowLayout.swift; sourceTree = "<group>"; };
|
||||||
03E23AB92EAA1D85004A8CEC /* MNNItemController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MNNItemController.swift; sourceTree = "<group>"; };
|
03E23AB92EAA1D85004A8CEC /* MNNItemController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MNNItemController.swift; sourceTree = "<group>"; };
|
||||||
|
03E9A7392EB45149000D1067 /* AppDelegate+FAApns.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+FAApns.swift"; sourceTree = "<group>"; };
|
||||||
|
03E9A73B2EB45507000D1067 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
|
03E9A73D2EB460F2000D1067 /* FAApnsAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAApnsAlert.swift; sourceTree = "<group>"; };
|
||||||
19196I43BR665O55RD205171 /* Pods-Fableon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fableon.debug.xcconfig"; path = "Target Support Files/Pods-Fableon/Pods-Fableon.debug.xcconfig"; sourceTree = "<group>"; };
|
19196I43BR665O55RD205171 /* Pods-Fableon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fableon.debug.xcconfig"; path = "Target Support Files/Pods-Fableon/Pods-Fableon.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fableon.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fableon.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
DCD59738B6J31K33W4Z524S0 /* Pods-Fableon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fableon.release.xcconfig"; path = "Target Support Files/Pods-Fableon/Pods-Fableon.release.xcconfig"; sourceTree = "<group>"; };
|
DCD59738B6J31K33W4Z524S0 /* Pods-Fableon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fableon.release.xcconfig"; path = "Target Support Files/Pods-Fableon/Pods-Fableon.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
@ -594,6 +647,9 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
03E9A7362EB44F26000D1067 /* FirebaseMessaging in Frameworks */,
|
||||||
|
031FDEDF2EB3423000F4CAC7 /* FacebookLogin in Frameworks */,
|
||||||
|
03E9A7382EB44F26000D1067 /* FirebasePerformance in Frameworks */,
|
||||||
B86XD3O90WO2R4725L084287 /* Pods_Fableon.framework in Frameworks */,
|
B86XD3O90WO2R4725L084287 /* Pods_Fableon.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -601,6 +657,18 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
031FDEE22EB3487700F4CAC7 /* Alert */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
031FDEE32EB348AA00F4CAC7 /* FABaseAlert.swift */,
|
||||||
|
031FDEE52EB34FBC00F4CAC7 /* FARemoveCollectAlert.swift */,
|
||||||
|
031FDEEB2EB35DF600F4CAC7 /* FACoinsPackAlert.swift */,
|
||||||
|
031FDEED2EB3682000F4CAC7 /* FAVipRetainAlert.swift */,
|
||||||
|
03E9A73D2EB460F2000D1067 /* FAApnsAlert.swift */,
|
||||||
|
);
|
||||||
|
path = Alert;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
039CE6072EAA2F37007B5EED /* AdjustStateManager */ = {
|
039CE6072EAA2F37007B5EED /* AdjustStateManager */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -645,6 +713,9 @@
|
|||||||
031FDEAD2EB093B100F4CAC7 /* FABuyRecordsModel.swift */,
|
031FDEAD2EB093B100F4CAC7 /* FABuyRecordsModel.swift */,
|
||||||
031FDEAF2EB09AB300F4CAC7 /* FARechargeRecordModel.swift */,
|
031FDEAF2EB09AB300F4CAC7 /* FARechargeRecordModel.swift */,
|
||||||
031FDEB12EB0A5AF00F4CAC7 /* FASendCoinRecordModel.swift */,
|
031FDEB12EB0A5AF00F4CAC7 /* FASendCoinRecordModel.swift */,
|
||||||
|
031FDEC72EB1F89F00F4CAC7 /* FACoinsPackModel.swift */,
|
||||||
|
031FDEC92EB1F8F200F4CAC7 /* FACoinsPackReceiveModel.swift */,
|
||||||
|
031FDEE92EB35D2600F4CAC7 /* FACoinPackCanReceiveModel.swift */,
|
||||||
);
|
);
|
||||||
path = M;
|
path = M;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -849,6 +920,7 @@
|
|||||||
03E239DF2EAA1A4E004A8CEC /* FASearchResultCell.swift */,
|
03E239DF2EAA1A4E004A8CEC /* FASearchResultCell.swift */,
|
||||||
03E239E02EAA1A4E004A8CEC /* FASearchResultCell.xib */,
|
03E239E02EAA1A4E004A8CEC /* FASearchResultCell.xib */,
|
||||||
03E239E12EAA1A4E004A8CEC /* FASearchResultView.swift */,
|
03E239E12EAA1A4E004A8CEC /* FASearchResultView.swift */,
|
||||||
|
031FDEE72EB358AE00F4CAC7 /* FAHomeCoinsPackButton.swift */,
|
||||||
);
|
);
|
||||||
path = V;
|
path = V;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -882,6 +954,7 @@
|
|||||||
03E239E92EAA1A4E004A8CEC /* FAMeListViewController.swift */,
|
03E239E92EAA1A4E004A8CEC /* FAMeListViewController.swift */,
|
||||||
03E239EA2EAA1A4E004A8CEC /* FAMeViewController.swift */,
|
03E239EA2EAA1A4E004A8CEC /* FAMeViewController.swift */,
|
||||||
03E239EB2EAA1A4E004A8CEC /* FASettingViewController.swift */,
|
03E239EB2EAA1A4E004A8CEC /* FASettingViewController.swift */,
|
||||||
|
031FDEC12EB1E19D00F4CAC7 /* FACoinPackViewController.swift */,
|
||||||
);
|
);
|
||||||
path = C;
|
path = C;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -905,6 +978,16 @@
|
|||||||
03E239F42EAA1A4E004A8CEC /* FAMeCoinsView.swift */,
|
03E239F42EAA1A4E004A8CEC /* FAMeCoinsView.swift */,
|
||||||
03E239F52EAA1A4E004A8CEC /* FAMeHeaderView.swift */,
|
03E239F52EAA1A4E004A8CEC /* FAMeHeaderView.swift */,
|
||||||
03E239F62EAA1A4E004A8CEC /* FAMeTableViewHeaderView.swift */,
|
03E239F62EAA1A4E004A8CEC /* FAMeTableViewHeaderView.swift */,
|
||||||
|
031FDEBF2EB1C08900F4CAC7 /* FAMeCoinsPackButton.swift */,
|
||||||
|
031FDEC52EB1E4E600F4CAC7 /* FACoinPackTitleView.swift */,
|
||||||
|
031FDEC32EB1E45300F4CAC7 /* FACoinPackHeaderView.swift */,
|
||||||
|
031FDECB2EB1FDF500F4CAC7 /* FACoinsPackClaimListView.swift */,
|
||||||
|
031FDECD2EB2006000F4CAC7 /* FACoinsPackClaimListCell.swift */,
|
||||||
|
031FDECF2EB2167200F4CAC7 /* FACoinsPackBuyView.swift */,
|
||||||
|
031FDED12EB2F69200F4CAC7 /* FALoginView.swift */,
|
||||||
|
031FDED72EB30D6E00F4CAC7 /* FASettingCell.swift */,
|
||||||
|
031FDED82EB30D6E00F4CAC7 /* FASettingCell.xib */,
|
||||||
|
031FDEDB2EB3141E00F4CAC7 /* FASettingFooterView.swift */,
|
||||||
);
|
);
|
||||||
path = V;
|
path = V;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1101,6 +1184,7 @@
|
|||||||
03E23A962EAA1A65004A8CEC /* Libs */ = {
|
03E23A962EAA1A65004A8CEC /* Libs */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
031FDEE22EB3487700F4CAC7 /* Alert */,
|
||||||
039CE6122EAB0DE1007B5EED /* FAIap */,
|
039CE6122EAB0DE1007B5EED /* FAIap */,
|
||||||
039CE60F2EAB0D2D007B5EED /* JXIAPManager */,
|
039CE60F2EAB0D2D007B5EED /* JXIAPManager */,
|
||||||
039CE6072EAA2F37007B5EED /* AdjustStateManager */,
|
039CE6072EAA2F37007B5EED /* AdjustStateManager */,
|
||||||
@ -1145,8 +1229,11 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
03E23A9E2EAA1A7F004A8CEC /* FALogin.swift */,
|
03E23A9E2EAA1A7F004A8CEC /* FALogin.swift */,
|
||||||
|
031FDED32EB2FF3A00F4CAC7 /* FALogin+Apple.swift */,
|
||||||
|
031FDEE02EB344A200F4CAC7 /* FALogin+Facebook.swift */,
|
||||||
03E23A9F2EAA1A7F004A8CEC /* FATokenModel.swift */,
|
03E23A9F2EAA1A7F004A8CEC /* FATokenModel.swift */,
|
||||||
03E23AA02EAA1A7F004A8CEC /* FAUserInfo.swift */,
|
03E23AA02EAA1A7F004A8CEC /* FAUserInfo.swift */,
|
||||||
|
031FDED52EB300F400F4CAC7 /* FAThirdSignModel.swift */,
|
||||||
);
|
);
|
||||||
path = FALogin;
|
path = FALogin;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1555,6 +1642,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
F32J2363K02108Z62849Y019 /* Assets.xcassets */,
|
F32J2363K02108Z62849Y019 /* Assets.xcassets */,
|
||||||
|
03E9A73B2EB45507000D1067 /* GoogleService-Info.plist */,
|
||||||
F3718184F516RJ76435E1IQ3 /* Info.plist */,
|
F3718184F516RJ76435E1IQ3 /* Info.plist */,
|
||||||
F3S22333V8I503E2Z4YYN165 /* LaunchScreen.storyboard */,
|
F3S22333V8I503E2Z4YYN165 /* LaunchScreen.storyboard */,
|
||||||
F3A0557617AU32W3L218F159 /* Localizable.strings */,
|
F3A0557617AU32W3L218F159 /* Localizable.strings */,
|
||||||
@ -1600,9 +1688,10 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
03E239602EAA1945004A8CEC /* AppDelegate.swift */,
|
03E239602EAA1945004A8CEC /* AppDelegate.swift */,
|
||||||
|
03E239622EAA1945004A8CEC /* SceneDelegate.swift */,
|
||||||
03E239612EAA1945004A8CEC /* AppDelegate+FAConfig.swift */,
|
03E239612EAA1945004A8CEC /* AppDelegate+FAConfig.swift */,
|
||||||
039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */,
|
039CE6032EAA2612007B5EED /* AppDelegate+FAAdjust.swift */,
|
||||||
03E239622EAA1945004A8CEC /* SceneDelegate.swift */,
|
03E9A7392EB45149000D1067 /* AppDelegate+FAApns.swift */,
|
||||||
);
|
);
|
||||||
path = App;
|
path = App;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1713,6 +1802,10 @@
|
|||||||
);
|
);
|
||||||
mainGroup = F31ABI705806054356280I22;
|
mainGroup = F31ABI705806054356280I22;
|
||||||
minimizedProjectReferenceProxies = 1;
|
minimizedProjectReferenceProxies = 1;
|
||||||
|
packageReferences = (
|
||||||
|
031FDEDD2EB3423000F4CAC7 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */,
|
||||||
|
03E9A7342EB44F26000D1067 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
|
||||||
|
);
|
||||||
preferredProjectObjectVersion = 77;
|
preferredProjectObjectVersion = 77;
|
||||||
productRefGroup = F3B536I6734E05L319J6654P /* Products */;
|
productRefGroup = F3B536I6734E05L319J6654P /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -1744,6 +1837,7 @@
|
|||||||
03E23A862EAA1A4E004A8CEC /* FAHistoryCell.xib in Resources */,
|
03E23A862EAA1A4E004A8CEC /* FAHistoryCell.xib in Resources */,
|
||||||
03E23A872EAA1A4E004A8CEC /* FAHomeRecommendedCell.xib in Resources */,
|
03E23A872EAA1A4E004A8CEC /* FAHomeRecommendedCell.xib in Resources */,
|
||||||
03E23A882EAA1A4E004A8CEC /* FAMeCell.xib in Resources */,
|
03E23A882EAA1A4E004A8CEC /* FAMeCell.xib in Resources */,
|
||||||
|
031FDED92EB30D6E00F4CAC7 /* FASettingCell.xib in Resources */,
|
||||||
03E23A892EAA1A4E004A8CEC /* FASearchResultCell.xib in Resources */,
|
03E23A892EAA1A4E004A8CEC /* FASearchResultCell.xib in Resources */,
|
||||||
03E23A8A2EAA1A4E004A8CEC /* FASearchRecommendCell.xib in Resources */,
|
03E23A8A2EAA1A4E004A8CEC /* FASearchRecommendCell.xib in Resources */,
|
||||||
03E23A8B2EAA1A4E004A8CEC /* FAHomeSectionTitleView.xib in Resources */,
|
03E23A8B2EAA1A4E004A8CEC /* FAHomeSectionTitleView.xib in Resources */,
|
||||||
@ -1756,6 +1850,7 @@
|
|||||||
03E23A922EAA1A4E004A8CEC /* FAConsumptionRecordsCell.xib in Resources */,
|
03E23A922EAA1A4E004A8CEC /* FAConsumptionRecordsCell.xib in Resources */,
|
||||||
03E23A932EAA1A4E004A8CEC /* FASearchRecordCell.xib in Resources */,
|
03E23A932EAA1A4E004A8CEC /* FASearchRecordCell.xib in Resources */,
|
||||||
03E23A942EAA1A4E004A8CEC /* FARankingListCell.xib in Resources */,
|
03E23A942EAA1A4E004A8CEC /* FARankingListCell.xib in Resources */,
|
||||||
|
03E9A73C2EB45507000D1067 /* GoogleService-Info.plist in Resources */,
|
||||||
03E23A952EAA1A4E004A8CEC /* FAAboutCell.xib in Resources */,
|
03E23A952EAA1A4E004A8CEC /* FAAboutCell.xib in Resources */,
|
||||||
F3R81ZR0ZIP4Q85CX4Z5J3I4 /* LaunchScreen.storyboard in Resources */,
|
F3R81ZR0ZIP4Q85CX4Z5J3I4 /* LaunchScreen.storyboard in Resources */,
|
||||||
F362972840Y56X1RPFI92W64 /* XKRefreshCell.xib in Resources */,
|
F362972840Y56X1RPFI92W64 /* XKRefreshCell.xib in Resources */,
|
||||||
@ -1838,12 +1933,14 @@
|
|||||||
F336143N569M8JG811WM9549 /* XHEedbackDetailView.swift in Sources */,
|
F336143N569M8JG811WM9549 /* XHEedbackDetailView.swift in Sources */,
|
||||||
F3F0952W592747Y1H6263E06 /* UCVBbfdebaffdFlowCell.swift in Sources */,
|
F3F0952W592747Y1H6263E06 /* UCVBbfdebaffdFlowCell.swift in Sources */,
|
||||||
F3SUP8DL68BIIEF1B8Z6U863 /* CFQConfigView.swift in Sources */,
|
F3SUP8DL68BIIEF1B8Z6U863 /* CFQConfigView.swift in Sources */,
|
||||||
|
031FDEE12EB344AB00F4CAC7 /* FALogin+Facebook.swift in Sources */,
|
||||||
F30E153206675C3SJ3974VL1 /* OJQUnechoSectionView.swift in Sources */,
|
F30E153206675C3SJ3974VL1 /* OJQUnechoSectionView.swift in Sources */,
|
||||||
F381909BQ5JWXYI119A49469 /* DREychainCell.swift in Sources */,
|
F381909BQ5JWXYI119A49469 /* DREychainCell.swift in Sources */,
|
||||||
F39R66F983517825QO331145 /* QCenterEfineView.swift in Sources */,
|
F39R66F983517825QO331145 /* QCenterEfineView.swift in Sources */,
|
||||||
F3II3AF834346F516W51V693 /* GAMainRecommendedView.swift in Sources */,
|
F3II3AF834346F516W51V693 /* GAMainRecommendedView.swift in Sources */,
|
||||||
031FDEAE2EB093B100F4CAC7 /* FABuyRecordsModel.swift in Sources */,
|
031FDEAE2EB093B100F4CAC7 /* FABuyRecordsModel.swift in Sources */,
|
||||||
F377Y22Z3J44H22J23963544 /* CDNewsController.swift in Sources */,
|
F377Y22Z3J44H22J23963544 /* CDNewsController.swift in Sources */,
|
||||||
|
031FDEC22EB1E19D00F4CAC7 /* FACoinPackViewController.swift in Sources */,
|
||||||
F358686093028548K00WQIO1 /* NGleeVionView.swift in Sources */,
|
F358686093028548K00WQIO1 /* NGleeVionView.swift in Sources */,
|
||||||
F3019606DA7P36H41G408X13 /* ZStreamCell.swift in Sources */,
|
F3019606DA7P36H41G408X13 /* ZStreamCell.swift in Sources */,
|
||||||
F392T441X031FH7N0HA03SZ7 /* WPSectionView.swift in Sources */,
|
F392T441X031FH7N0HA03SZ7 /* WPSectionView.swift in Sources */,
|
||||||
@ -1865,6 +1962,7 @@
|
|||||||
F3P4D170962A2JAF14W0520R /* ADCheckMageView.swift in Sources */,
|
F3P4D170962A2JAF14W0520R /* ADCheckMageView.swift in Sources */,
|
||||||
031FDEBA2EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift in Sources */,
|
031FDEBA2EB0B82600F4CAC7 /* FACoinPackConfirmItem2View.swift in Sources */,
|
||||||
F3206101P0DVK224N85S1W62 /* XIPathEviceController.swift in Sources */,
|
F3206101P0DVK224N85S1W62 /* XIPathEviceController.swift in Sources */,
|
||||||
|
031FDEC82EB1F89F00F4CAC7 /* FACoinsPackModel.swift in Sources */,
|
||||||
F31N0S2575E3YC5AOG80WE90 /* TYElyon.swift in Sources */,
|
F31N0S2575E3YC5AOG80WE90 /* TYElyon.swift in Sources */,
|
||||||
F3JX29E3JQ40V23245TS8Z36 /* YRegisterController.swift in Sources */,
|
F3JX29E3JQ40V23245TS8Z36 /* YRegisterController.swift in Sources */,
|
||||||
F381171472542RD403O12925 /* QZOast.swift in Sources */,
|
F381171472542RD403O12925 /* QZOast.swift in Sources */,
|
||||||
@ -1882,6 +1980,7 @@
|
|||||||
03E23AAC2EAA1A7F004A8CEC /* FALogin.swift in Sources */,
|
03E23AAC2EAA1A7F004A8CEC /* FALogin.swift in Sources */,
|
||||||
03E23AAD2EAA1A7F004A8CEC /* FAKeychainHelper.swift in Sources */,
|
03E23AAD2EAA1A7F004A8CEC /* FAKeychainHelper.swift in Sources */,
|
||||||
03E23AAE2EAA1A7F004A8CEC /* FATool.swift in Sources */,
|
03E23AAE2EAA1A7F004A8CEC /* FATool.swift in Sources */,
|
||||||
|
031FDECC2EB1FDF500F4CAC7 /* FACoinsPackClaimListView.swift in Sources */,
|
||||||
039CE6262EAB2A72007B5EED /* FAPayAlertModel.swift in Sources */,
|
039CE6262EAB2A72007B5EED /* FAPayAlertModel.swift in Sources */,
|
||||||
03E23AAF2EAA1A7F004A8CEC /* FSPagerSwiftUIView.swift in Sources */,
|
03E23AAF2EAA1A7F004A8CEC /* FSPagerSwiftUIView.swift in Sources */,
|
||||||
03E23AB02EAA1A7F004A8CEC /* FADeviceIDManager.swift in Sources */,
|
03E23AB02EAA1A7F004A8CEC /* FADeviceIDManager.swift in Sources */,
|
||||||
@ -1896,6 +1995,7 @@
|
|||||||
03E23AB72EAA1A7F004A8CEC /* FALocalized.swift in Sources */,
|
03E23AB72EAA1A7F004A8CEC /* FALocalized.swift in Sources */,
|
||||||
039CE6222EAB1340007B5EED /* FAUserDefaultsKey.swift in Sources */,
|
039CE6222EAB1340007B5EED /* FAUserDefaultsKey.swift in Sources */,
|
||||||
03E23AB82EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift in Sources */,
|
03E23AB82EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift in Sources */,
|
||||||
|
031FDEC62EB1E4E600F4CAC7 /* FACoinPackTitleView.swift in Sources */,
|
||||||
F3K238643L913I6RK4G7S006 /* CSceneRegister.swift in Sources */,
|
F3K238643L913I6RK4G7S006 /* CSceneRegister.swift in Sources */,
|
||||||
F3ZT3I4VAGB5405FWL36UW12 /* ZFGEtworkCell.swift in Sources */,
|
F3ZT3I4VAGB5405FWL36UW12 /* ZFGEtworkCell.swift in Sources */,
|
||||||
F35O71332554S53191121042 /* UOModalCell.swift in Sources */,
|
F35O71332554S53191121042 /* UOModalCell.swift in Sources */,
|
||||||
@ -1908,6 +2008,7 @@
|
|||||||
03E23A352EAA1A4E004A8CEC /* FARecommendPlayerControlView.swift in Sources */,
|
03E23A352EAA1A4E004A8CEC /* FARecommendPlayerControlView.swift in Sources */,
|
||||||
03E23A362EAA1A4E004A8CEC /* FAHomeMustSeeView.swift in Sources */,
|
03E23A362EAA1A4E004A8CEC /* FAHomeMustSeeView.swift in Sources */,
|
||||||
03E23A372EAA1A4E004A8CEC /* FAHomeItem.swift in Sources */,
|
03E23A372EAA1A4E004A8CEC /* FAHomeItem.swift in Sources */,
|
||||||
|
03E9A73E2EB460F2000D1067 /* FAApnsAlert.swift in Sources */,
|
||||||
03E23A382EAA1A4E004A8CEC /* FACategoryModel.swift in Sources */,
|
03E23A382EAA1A4E004A8CEC /* FACategoryModel.swift in Sources */,
|
||||||
03E23A392EAA1A4E004A8CEC /* FANewListViewController.swift in Sources */,
|
03E23A392EAA1A4E004A8CEC /* FANewListViewController.swift in Sources */,
|
||||||
03E23A3A2EAA1A4E004A8CEC /* FAHomeRecommendedCell.swift in Sources */,
|
03E23A3A2EAA1A4E004A8CEC /* FAHomeRecommendedCell.swift in Sources */,
|
||||||
@ -1928,12 +2029,14 @@
|
|||||||
03E23A492EAA1A4E004A8CEC /* FAVideoInfoModel.swift in Sources */,
|
03E23A492EAA1A4E004A8CEC /* FAVideoInfoModel.swift in Sources */,
|
||||||
039CE6202EAB114B007B5EED /* FAPayDateModel.swift in Sources */,
|
039CE6202EAB114B007B5EED /* FAPayDateModel.swift in Sources */,
|
||||||
03E23A4A2EAA1A4E004A8CEC /* FAConsumptionRecordsViewController.swift in Sources */,
|
03E23A4A2EAA1A4E004A8CEC /* FAConsumptionRecordsViewController.swift in Sources */,
|
||||||
|
031FDED02EB2167200F4CAC7 /* FACoinsPackBuyView.swift in Sources */,
|
||||||
03E23A4B2EAA1A4E004A8CEC /* FAMeCoinsView.swift in Sources */,
|
03E23A4B2EAA1A4E004A8CEC /* FAMeCoinsView.swift in Sources */,
|
||||||
03E23A4C2EAA1A4E004A8CEC /* FAHomeViewModel.swift in Sources */,
|
03E23A4C2EAA1A4E004A8CEC /* FAHomeViewModel.swift in Sources */,
|
||||||
03E23A4D2EAA1A4E004A8CEC /* FAGenresViewController.swift in Sources */,
|
03E23A4D2EAA1A4E004A8CEC /* FAGenresViewController.swift in Sources */,
|
||||||
03E23A4E2EAA1A4E004A8CEC /* FAHomeBannerContentCell.swift in Sources */,
|
03E23A4E2EAA1A4E004A8CEC /* FAHomeBannerContentCell.swift in Sources */,
|
||||||
03E23A4F2EAA1A4E004A8CEC /* FAEpSelectorView.swift in Sources */,
|
03E23A4F2EAA1A4E004A8CEC /* FAEpSelectorView.swift in Sources */,
|
||||||
03E23A502EAA1A4E004A8CEC /* FAMeHeaderView.swift in Sources */,
|
03E23A502EAA1A4E004A8CEC /* FAMeHeaderView.swift in Sources */,
|
||||||
|
031FDEC02EB1C08900F4CAC7 /* FAMeCoinsPackButton.swift in Sources */,
|
||||||
03E23A512EAA1A4E004A8CEC /* FAConsumptionRecordsCell.swift in Sources */,
|
03E23A512EAA1A4E004A8CEC /* FAConsumptionRecordsCell.swift in Sources */,
|
||||||
03E23A522EAA1A4E004A8CEC /* FARankingListHeaderView.swift in Sources */,
|
03E23A522EAA1A4E004A8CEC /* FARankingListHeaderView.swift in Sources */,
|
||||||
03E23A532EAA1A4E004A8CEC /* FAVideoLockView.swift in Sources */,
|
03E23A532EAA1A4E004A8CEC /* FAVideoLockView.swift in Sources */,
|
||||||
@ -1941,20 +2044,25 @@
|
|||||||
03E23A552EAA1A4E004A8CEC /* FAPopularListViewController.swift in Sources */,
|
03E23A552EAA1A4E004A8CEC /* FAPopularListViewController.swift in Sources */,
|
||||||
039CE6042EAA2621007B5EED /* AppDelegate+FAAdjust.swift in Sources */,
|
039CE6042EAA2621007B5EED /* AppDelegate+FAAdjust.swift in Sources */,
|
||||||
03E23A562EAA1A4E004A8CEC /* FAPlayerEpUIButton.swift in Sources */,
|
03E23A562EAA1A4E004A8CEC /* FAPlayerEpUIButton.swift in Sources */,
|
||||||
|
031FDEE42EB348AA00F4CAC7 /* FABaseAlert.swift in Sources */,
|
||||||
03E23A572EAA1A4E004A8CEC /* FAHistoryCell.swift in Sources */,
|
03E23A572EAA1A4E004A8CEC /* FAHistoryCell.swift in Sources */,
|
||||||
03E23A582EAA1A4E004A8CEC /* FASearchViewController.swift in Sources */,
|
03E23A582EAA1A4E004A8CEC /* FASearchViewController.swift in Sources */,
|
||||||
03E23A592EAA1A4E004A8CEC /* FAWalletCell.swift in Sources */,
|
03E23A592EAA1A4E004A8CEC /* FAWalletCell.swift in Sources */,
|
||||||
03E23A5A2EAA1A4E004A8CEC /* FASearchInputView.swift in Sources */,
|
03E23A5A2EAA1A4E004A8CEC /* FASearchInputView.swift in Sources */,
|
||||||
|
031FDEE82EB358AE00F4CAC7 /* FAHomeCoinsPackButton.swift in Sources */,
|
||||||
03E23A5B2EAA1A4E004A8CEC /* FAAboutCell.swift in Sources */,
|
03E23A5B2EAA1A4E004A8CEC /* FAAboutCell.swift in Sources */,
|
||||||
03E23A5C2EAA1A4E004A8CEC /* FAGenresListViewController.swift in Sources */,
|
03E23A5C2EAA1A4E004A8CEC /* FAGenresListViewController.swift in Sources */,
|
||||||
03E23A5D2EAA1A4E004A8CEC /* FARecommendViewModel.swift in Sources */,
|
03E23A5D2EAA1A4E004A8CEC /* FARecommendViewModel.swift in Sources */,
|
||||||
03E23A5E2EAA1A4E004A8CEC /* FAHomeMustSeeContentView.swift in Sources */,
|
03E23A5E2EAA1A4E004A8CEC /* FAHomeMustSeeContentView.swift in Sources */,
|
||||||
03E23A5F2EAA1A4E004A8CEC /* FAEpSelectorCell.swift in Sources */,
|
03E23A5F2EAA1A4E004A8CEC /* FAEpSelectorCell.swift in Sources */,
|
||||||
|
031FDEEC2EB35DF600F4CAC7 /* FACoinsPackAlert.swift in Sources */,
|
||||||
03E23A602EAA1A4E004A8CEC /* FASearchResultView.swift in Sources */,
|
03E23A602EAA1A4E004A8CEC /* FASearchResultView.swift in Sources */,
|
||||||
03E23A612EAA1A4E004A8CEC /* FAHomeMustSeeContentCell.swift in Sources */,
|
03E23A612EAA1A4E004A8CEC /* FAHomeMustSeeContentCell.swift in Sources */,
|
||||||
03E23A622EAA1A4E004A8CEC /* FAShortDetailModel.swift in Sources */,
|
03E23A622EAA1A4E004A8CEC /* FAShortDetailModel.swift in Sources */,
|
||||||
03E23A632EAA1A4E004A8CEC /* FASearchResultCell.swift in Sources */,
|
03E23A632EAA1A4E004A8CEC /* FASearchResultCell.swift in Sources */,
|
||||||
03E23A642EAA1A4E004A8CEC /* FAMeTableViewHeaderView.swift in Sources */,
|
03E23A642EAA1A4E004A8CEC /* FAMeTableViewHeaderView.swift in Sources */,
|
||||||
|
031FDEE62EB34FBC00F4CAC7 /* FARemoveCollectAlert.swift in Sources */,
|
||||||
|
031FDECE2EB2006000F4CAC7 /* FACoinsPackClaimListCell.swift in Sources */,
|
||||||
03E23A652EAA1A4E004A8CEC /* FARewardCoinsViewController.swift in Sources */,
|
03E23A652EAA1A4E004A8CEC /* FARewardCoinsViewController.swift in Sources */,
|
||||||
03E23A662EAA1A4E004A8CEC /* FAStoreViewController.swift in Sources */,
|
03E23A662EAA1A4E004A8CEC /* FAStoreViewController.swift in Sources */,
|
||||||
03E23A672EAA1A4E004A8CEC /* FAMeListViewController.swift in Sources */,
|
03E23A672EAA1A4E004A8CEC /* FAMeListViewController.swift in Sources */,
|
||||||
@ -1964,7 +2072,9 @@
|
|||||||
03E23A6B2EAA1A4E004A8CEC /* FARecommendPlayerCell.swift in Sources */,
|
03E23A6B2EAA1A4E004A8CEC /* FARecommendPlayerCell.swift in Sources */,
|
||||||
03E23A6C2EAA1A4E004A8CEC /* FAHomeNewView.swift in Sources */,
|
03E23A6C2EAA1A4E004A8CEC /* FAHomeNewView.swift in Sources */,
|
||||||
03E23A6D2EAA1A4E004A8CEC /* FARankingListViewController.swift in Sources */,
|
03E23A6D2EAA1A4E004A8CEC /* FARankingListViewController.swift in Sources */,
|
||||||
|
031FDEEA2EB35D2600F4CAC7 /* FACoinPackCanReceiveModel.swift in Sources */,
|
||||||
03E23A6E2EAA1A4E004A8CEC /* FARankingListCell.swift in Sources */,
|
03E23A6E2EAA1A4E004A8CEC /* FARankingListCell.swift in Sources */,
|
||||||
|
031FDED22EB2F69200F4CAC7 /* FALoginView.swift in Sources */,
|
||||||
03E23A6F2EAA1A4E004A8CEC /* FAHomeBannerCell.swift in Sources */,
|
03E23A6F2EAA1A4E004A8CEC /* FAHomeBannerCell.swift in Sources */,
|
||||||
03E23A702EAA1A4E004A8CEC /* FAGenresCell.swift in Sources */,
|
03E23A702EAA1A4E004A8CEC /* FAGenresCell.swift in Sources */,
|
||||||
03E23A712EAA1A4E004A8CEC /* FAHomeSectionTitleView.swift in Sources */,
|
03E23A712EAA1A4E004A8CEC /* FAHomeSectionTitleView.swift in Sources */,
|
||||||
@ -1981,12 +2091,14 @@
|
|||||||
03E23A7A2EAA1A4E004A8CEC /* FASearchRecordView.swift in Sources */,
|
03E23A7A2EAA1A4E004A8CEC /* FASearchRecordView.swift in Sources */,
|
||||||
03E23A7B2EAA1A4E004A8CEC /* FACollectViewController.swift in Sources */,
|
03E23A7B2EAA1A4E004A8CEC /* FACollectViewController.swift in Sources */,
|
||||||
03E23A7C2EAA1A4E004A8CEC /* FAMeCell.swift in Sources */,
|
03E23A7C2EAA1A4E004A8CEC /* FAMeCell.swift in Sources */,
|
||||||
|
03E9A73A2EB45154000D1067 /* AppDelegate+FAApns.swift in Sources */,
|
||||||
03E23A7D2EAA1A4E004A8CEC /* FAWalletHeaderView.swift in Sources */,
|
03E23A7D2EAA1A4E004A8CEC /* FAWalletHeaderView.swift in Sources */,
|
||||||
03E23A7E2EAA1A4E004A8CEC /* FAPlayerProgressView.swift in Sources */,
|
03E23A7E2EAA1A4E004A8CEC /* FAPlayerProgressView.swift in Sources */,
|
||||||
031FDEB82EB0B80400F4CAC7 /* FACoinPackConfirmItem1View.swift in Sources */,
|
031FDEB82EB0B80400F4CAC7 /* FACoinPackConfirmItem1View.swift in Sources */,
|
||||||
03E23A7F2EAA1A4E004A8CEC /* FAMeItemModel.swift in Sources */,
|
03E23A7F2EAA1A4E004A8CEC /* FAMeItemModel.swift in Sources */,
|
||||||
03E23A802EAA1A4E004A8CEC /* FAGenresListCell.swift in Sources */,
|
03E23A802EAA1A4E004A8CEC /* FAGenresListCell.swift in Sources */,
|
||||||
03E23A812EAA1A4E004A8CEC /* FACollectCell.swift in Sources */,
|
03E23A812EAA1A4E004A8CEC /* FACollectCell.swift in Sources */,
|
||||||
|
031FDED62EB300F400F4CAC7 /* FAThirdSignModel.swift in Sources */,
|
||||||
03E23A822EAA1A4E004A8CEC /* FASearchRecommendView.swift in Sources */,
|
03E23A822EAA1A4E004A8CEC /* FASearchRecommendView.swift in Sources */,
|
||||||
03E23A832EAA1A4E004A8CEC /* FAHomeMustSeeShortView.swift in Sources */,
|
03E23A832EAA1A4E004A8CEC /* FAHomeMustSeeShortView.swift in Sources */,
|
||||||
039CE60B2EAA31CB007B5EED /* FAStatAPI.swift in Sources */,
|
039CE60B2EAA31CB007B5EED /* FAStatAPI.swift in Sources */,
|
||||||
@ -2014,11 +2126,14 @@
|
|||||||
F3M8439X72Q55JY9G8U502D9 /* DXYFire.swift in Sources */,
|
F3M8439X72Q55JY9G8U502D9 /* DXYFire.swift in Sources */,
|
||||||
03E239912EAA1A29004A8CEC /* Dictionary+FAAdd.swift in Sources */,
|
03E239912EAA1A29004A8CEC /* Dictionary+FAAdd.swift in Sources */,
|
||||||
03E239922EAA1A29004A8CEC /* FAImageView.swift in Sources */,
|
03E239922EAA1A29004A8CEC /* FAImageView.swift in Sources */,
|
||||||
|
031FDEDC2EB3141E00F4CAC7 /* FASettingFooterView.swift in Sources */,
|
||||||
031FDEBE2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift in Sources */,
|
031FDEBE2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift in Sources */,
|
||||||
03E239932EAA1A29004A8CEC /* Date+FAAdd.swift in Sources */,
|
03E239932EAA1A29004A8CEC /* Date+FAAdd.swift in Sources */,
|
||||||
|
031FDEDA2EB30D6E00F4CAC7 /* FASettingCell.swift in Sources */,
|
||||||
03E239942EAA1A29004A8CEC /* UserDefaults+FAAdd.swift in Sources */,
|
03E239942EAA1A29004A8CEC /* UserDefaults+FAAdd.swift in Sources */,
|
||||||
039CE6322EAB796F007B5EED /* FALabel.swift in Sources */,
|
039CE6322EAB796F007B5EED /* FALabel.swift in Sources */,
|
||||||
03E239952EAA1A29004A8CEC /* Font+FAAdd.swift in Sources */,
|
03E239952EAA1A29004A8CEC /* Font+FAAdd.swift in Sources */,
|
||||||
|
031FDEEE2EB3682000F4CAC7 /* FAVipRetainAlert.swift in Sources */,
|
||||||
03E239962EAA1A29004A8CEC /* FACryptorService.swift in Sources */,
|
03E239962EAA1A29004A8CEC /* FACryptorService.swift in Sources */,
|
||||||
03E239972EAA1A29004A8CEC /* FANetworkManager.swift in Sources */,
|
03E239972EAA1A29004A8CEC /* FANetworkManager.swift in Sources */,
|
||||||
03E239982EAA1A29004A8CEC /* UIScrollView+FARefresh.swift in Sources */,
|
03E239982EAA1A29004A8CEC /* UIScrollView+FARefresh.swift in Sources */,
|
||||||
@ -2035,6 +2150,7 @@
|
|||||||
03E239A22EAA1A29004A8CEC /* FATabBarController.swift in Sources */,
|
03E239A22EAA1A29004A8CEC /* FATabBarController.swift in Sources */,
|
||||||
03E239A32EAA1A29004A8CEC /* UIStackView+FAAdd.swift in Sources */,
|
03E239A32EAA1A29004A8CEC /* UIStackView+FAAdd.swift in Sources */,
|
||||||
03E239A42EAA1A29004A8CEC /* UIScreen+FAAdd.swift in Sources */,
|
03E239A42EAA1A29004A8CEC /* UIScreen+FAAdd.swift in Sources */,
|
||||||
|
031FDED42EB2FF4000F4CAC7 /* FALogin+Apple.swift in Sources */,
|
||||||
039CE6182EAB0E7E007B5EED /* FAStoreAPI.swift in Sources */,
|
039CE6182EAB0E7E007B5EED /* FAStoreAPI.swift in Sources */,
|
||||||
03E239A52EAA1A29004A8CEC /* FACollectionView.swift in Sources */,
|
03E239A52EAA1A29004A8CEC /* FACollectionView.swift in Sources */,
|
||||||
03E239A62EAA1A29004A8CEC /* UIView+FAAdd.swift in Sources */,
|
03E239A62EAA1A29004A8CEC /* UIView+FAAdd.swift in Sources */,
|
||||||
@ -2046,9 +2162,11 @@
|
|||||||
03E239AB2EAA1A29004A8CEC /* FATableViewCell.swift in Sources */,
|
03E239AB2EAA1A29004A8CEC /* FATableViewCell.swift in Sources */,
|
||||||
03E239AC2EAA1A29004A8CEC /* FABaseWebViewController+Script.swift in Sources */,
|
03E239AC2EAA1A29004A8CEC /* FABaseWebViewController+Script.swift in Sources */,
|
||||||
03E239AD2EAA1A29004A8CEC /* FAAppWebViewController.swift in Sources */,
|
03E239AD2EAA1A29004A8CEC /* FAAppWebViewController.swift in Sources */,
|
||||||
|
031FDEC42EB1E45300F4CAC7 /* FACoinPackHeaderView.swift in Sources */,
|
||||||
03E239AE2EAA1A29004A8CEC /* SwiftUIExtension.swift in Sources */,
|
03E239AE2EAA1A29004A8CEC /* SwiftUIExtension.swift in Sources */,
|
||||||
039CE60E2EAA32A8007B5EED /* FAOpenAppModel.swift in Sources */,
|
039CE60E2EAA32A8007B5EED /* FAOpenAppModel.swift in Sources */,
|
||||||
03E239AF2EAA1A29004A8CEC /* FAAPI.swift in Sources */,
|
03E239AF2EAA1A29004A8CEC /* FAAPI.swift in Sources */,
|
||||||
|
031FDECA2EB1F8F200F4CAC7 /* FACoinsPackReceiveModel.swift in Sources */,
|
||||||
03E239B02EAA1A29004A8CEC /* FAWebView.swift in Sources */,
|
03E239B02EAA1A29004A8CEC /* FAWebView.swift in Sources */,
|
||||||
039CE61C2EAB0F29007B5EED /* FAIapOrderModel.swift in Sources */,
|
039CE61C2EAB0F29007B5EED /* FAIapOrderModel.swift in Sources */,
|
||||||
03E239B12EAA1A29004A8CEC /* FANetworkMonitor.swift in Sources */,
|
03E239B12EAA1A29004A8CEC /* FANetworkMonitor.swift in Sources */,
|
||||||
@ -2233,6 +2351,7 @@
|
|||||||
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
||||||
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
||||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
||||||
|
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience.";
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
||||||
@ -2273,6 +2392,7 @@
|
|||||||
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
||||||
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
||||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
|
||||||
|
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience.";
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
||||||
@ -2317,6 +2437,43 @@
|
|||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
031FDEDD2EB3423000F4CAC7 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/facebook/facebook-ios-sdk";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 14.1.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
03E9A7342EB44F26000D1067 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 12.5.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
031FDEDE2EB3423000F4CAC7 /* FacebookLogin */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 031FDEDD2EB3423000F4CAC7 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */;
|
||||||
|
productName = FacebookLogin;
|
||||||
|
};
|
||||||
|
03E9A7352EB44F26000D1067 /* FirebaseMessaging */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 03E9A7342EB44F26000D1067 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
|
||||||
|
productName = FirebaseMessaging;
|
||||||
|
};
|
||||||
|
03E9A7372EB44F26000D1067 /* FirebasePerformance */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 03E9A7342EB44F26000D1067 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
|
||||||
|
productName = FirebasePerformance;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = F3LK276P33H73Y39H9X6VTDI /* Project object */;
|
rootObject = F3LK276P33H73Y39H9X6VTDI /* Project object */;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,7 +133,7 @@ extension SceneDelegate {
|
|||||||
var result = false
|
var result = false
|
||||||
|
|
||||||
#if canImport(FacebookCore)
|
#if canImport(FacebookCore)
|
||||||
let result = ApplicationDelegate.shared.application(UIApplication.shared, continue: userActivity)
|
result = ApplicationDelegate.shared.application(UIApplication.shared, continue: userActivity)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if !result {
|
if !result {
|
||||||
|
|||||||
123
Fableon/App/AppDelegate+FAApns.swift
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
//
|
||||||
|
// AppDelegate+FAApns.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/31.
|
||||||
|
//
|
||||||
|
import UIKit
|
||||||
|
import FirebaseMessaging
|
||||||
|
import SmartCodable
|
||||||
|
import FirebaseCore
|
||||||
|
|
||||||
|
extension SceneDelegate {
|
||||||
|
|
||||||
|
func requestFirebase() {
|
||||||
|
FirebaseApp.configure()
|
||||||
|
Messaging.messaging().delegate = self
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestApns() {
|
||||||
|
let center = UNUserNotificationCenter.current()
|
||||||
|
center.delegate = self
|
||||||
|
|
||||||
|
center.requestAuthorization(options: [.badge, .sound, .alert]) { grant, error in
|
||||||
|
if !grant {
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
self.showApnsAlert()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FAAdjustStateManager.manager.apnsAuthorizationFinish = true
|
||||||
|
|
||||||
|
FATool.sceneDelegate?.retryHandleOpenAppMessage()
|
||||||
|
|
||||||
|
|
||||||
|
FATool.requestIDFAAuthorization(nil)
|
||||||
|
FAStatAPI.uploadApnsAuthorizationStatus()
|
||||||
|
}
|
||||||
|
UIApplication.shared.registerForRemoteNotifications()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func setBadgeCount(_ count: Int) {
|
||||||
|
if #available(iOS 16.0, *) {
|
||||||
|
UNUserNotificationCenter.current().setBadgeCount(count)
|
||||||
|
} else {
|
||||||
|
UIApplication.shared.applicationIconBadgeNumber = count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func showApnsAlert() {
|
||||||
|
guard let date = UserDefaults.standard.object(forKey: kFAApnsAlertDefaultsKey) as? Date else {
|
||||||
|
UserDefaults.standard.set(Date(), forKey: kFAApnsAlertDefaultsKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#if !DEBUG
|
||||||
|
if date.fa_isToday { return }
|
||||||
|
UserDefaults.standard.set(Date(), forKey: kFAApnsAlertDefaultsKey)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
let view = FAApnsAlert()
|
||||||
|
view.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AppDelegate {
|
||||||
|
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||||
|
Messaging.messaging().apnsToken = deviceToken
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: any Error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: -------------- UNUserNotificationCenterDelegate --------------
|
||||||
|
extension SceneDelegate: UNUserNotificationCenterDelegate {
|
||||||
|
|
||||||
|
|
||||||
|
///APP处于前台是接收通知消息
|
||||||
|
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
|
||||||
|
completionHandler([.badge, .banner])
|
||||||
|
}
|
||||||
|
|
||||||
|
///点击通知消息进入app
|
||||||
|
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
|
||||||
|
setBadgeCount(0)
|
||||||
|
|
||||||
|
guard let userInfo: [String : Any] = response.notification.request.content.userInfo as? [String : Any] else {
|
||||||
|
completionHandler()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let model = FAOpenAppModel.deserialize(from: userInfo) else {
|
||||||
|
completionHandler()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
FAStatAPI.requestStatApnsClick(id: model.message_id ?? "", title: response.notification.request.content.title)
|
||||||
|
|
||||||
|
if model.path == .videoDetail, let shortPlayId = model.short_play_id {
|
||||||
|
let vc = FAPlayerDetailViewController()
|
||||||
|
vc.shortPlayId = shortPlayId
|
||||||
|
FATool.topViewController?.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
|
||||||
|
} else if model.path == .feedback {
|
||||||
|
let vc = FAAppWebViewController()
|
||||||
|
vc.webUrl = kFAFeedBackListWebUrl
|
||||||
|
FATool.topViewController?.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
completionHandler()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: MessagingDelegate
|
||||||
|
extension SceneDelegate: MessagingDelegate {
|
||||||
|
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
|
||||||
|
if let token = fcmToken {
|
||||||
|
FAStatAPI.requestUploadApnsDeviceToken(token: token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ import UIKit
|
|||||||
import MJRefresh
|
import MJRefresh
|
||||||
import IQKeyboardManagerSwift
|
import IQKeyboardManagerSwift
|
||||||
import IQKeyboardToolbarManager
|
import IQKeyboardToolbarManager
|
||||||
|
import FacebookCore
|
||||||
|
|
||||||
|
|
||||||
extension AppDelegate {
|
extension AppDelegate {
|
||||||
@ -30,6 +31,11 @@ extension AppDelegate {
|
|||||||
UINavigationBar.appearance().standardAppearance = appearance
|
UINavigationBar.appearance().standardAppearance = appearance
|
||||||
|
|
||||||
registerAdjust()
|
registerAdjust()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func fa_registThirdparty(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
|
||||||
|
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import FacebookCore
|
||||||
|
|
||||||
@main
|
@main
|
||||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
@ -14,6 +15,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
FANetworkMonitor.manager.startMonitoring()
|
FANetworkMonitor.manager.startMonitoring()
|
||||||
|
fa_registThirdparty(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
|
|
||||||
self.fa_config()
|
self.fa_config()
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: FANetworkMonitor.networkStatusDidChangeNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: FANetworkMonitor.networkStatusDidChangeNotification, object: nil)
|
||||||
|
|||||||
@ -6,40 +6,54 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import YYText
|
||||||
|
|
||||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
|
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
|
private var onLineTimer: Timer?
|
||||||
|
|
||||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||||
guard let windowScene = (scene as? UIWindowScene) else { return }
|
guard let windowScene = (scene as? UIWindowScene) else { return }
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: FANetworkMonitor.networkStatusDidChangeNotification, object: nil)
|
||||||
|
FATool.sceneDelegate = self
|
||||||
FATool.windowScene = windowScene
|
FATool.windowScene = windowScene
|
||||||
|
|
||||||
window = UIWindow(windowScene: windowScene)
|
window = UIWindow(windowScene: windowScene)
|
||||||
window?.rootViewController = FATabBarController()
|
window?.rootViewController = FATabBarController()
|
||||||
window?.makeKeyAndVisible()
|
window?.makeKeyAndVisible()
|
||||||
FAAdjustStateManager.manager.isOpenApp = true
|
FAAdjustStateManager.manager.isOpenApp = true
|
||||||
|
|
||||||
|
onLineTimer = Timer.scheduledTimer(timeInterval: 60 * 10, target: YYTextWeakProxy(target: self), selector: #selector(handleOnLine), userInfo: nil, repeats: true)
|
||||||
|
|
||||||
|
|
||||||
|
if let webpageURL = connectionOptions.userActivities.first?.webpageURL {
|
||||||
|
self.handleOpenAppMessage(webpageURL: webpageURL)
|
||||||
|
} else if let url = connectionOptions.urlContexts.first?.url {
|
||||||
|
self.handleOpenAppMessage(webpageURL: url)
|
||||||
|
}
|
||||||
|
|
||||||
|
requestFirebase()
|
||||||
|
requestApns()
|
||||||
}
|
}
|
||||||
|
|
||||||
func sceneDidDisconnect(_ scene: UIScene) {
|
func sceneDidDisconnect(_ scene: UIScene) {
|
||||||
// Called as the scene is being released by the system.
|
|
||||||
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
|
||||||
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
|
||||||
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||||
// Called when the scene has moved from an inactive state to an active state.
|
self.handleOnLine()
|
||||||
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
FAStatAPI.requestEnterApp()
|
||||||
|
self.setBadgeCount(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sceneWillResignActive(_ scene: UIScene) {
|
func sceneWillResignActive(_ scene: UIScene) {
|
||||||
// Called when the scene will move from an active state to an inactive state.
|
FAStatAPI.requestLeaveApp()
|
||||||
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||||
|
FAStatAPI.uploadApnsAuthorizationStatus()
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
self.handleOpenAppMessage(webpageURL: nil)
|
self.handleOpenAppMessage(webpageURL: nil)
|
||||||
}
|
}
|
||||||
@ -52,3 +66,14 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SceneDelegate {
|
||||||
|
|
||||||
|
@objc private func handleOnLine() {
|
||||||
|
FAStatAPI.requestStatOnLine()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func networkStatusDidChangeNotification() {
|
||||||
|
FATool.requestIDFAAuthorization(nil)
|
||||||
|
self.retryHandleOpenAppMessage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,10 +2,16 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>com.apple.developer.applesignin</key>
|
||||||
|
<array>
|
||||||
|
<string>Default</string>
|
||||||
|
</array>
|
||||||
<key>com.apple.developer.associated-domains</key>
|
<key>com.apple.developer.associated-domains</key>
|
||||||
<array>
|
<array>
|
||||||
<string>applinks:fableon.go.link</string>
|
<string>applinks:fableon.go.link</string>
|
||||||
<string>applinks:kuzt.adj.st</string>
|
<string>applinks:kuzt.adj.st</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>keychain-access-groups</key>
|
||||||
|
<array/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -7,3 +7,5 @@
|
|||||||
|
|
||||||
|
|
||||||
let kFAWaitRestoreIAPDefaultsKey = "kFAWaitRestoreIAPDefaultsKey"
|
let kFAWaitRestoreIAPDefaultsKey = "kFAWaitRestoreIAPDefaultsKey"
|
||||||
|
|
||||||
|
let kFAApnsAlertDefaultsKey = "kFAApnsAlertDefaultsKey"
|
||||||
|
|||||||
@ -22,7 +22,7 @@ extension Date {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///是否是今天
|
///是否是今天
|
||||||
var br_isToday: Bool {
|
var fa_isToday: Bool {
|
||||||
get {
|
get {
|
||||||
return Calendar.current.isDateInToday(self)
|
return Calendar.current.isDateInToday(self)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
extension FAAPI {
|
extension FAAPI {
|
||||||
///更新短剧关注状态 [ "state" : isCollect, "id" : shortPlayId,]
|
///更新短剧关注状态 [ "state" : isCollect, "id" : shortPlayId,]
|
||||||
@ -249,6 +250,34 @@ struct FAAPI {
|
|||||||
completer?(response.data)
|
completer?(response.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: 用户登录
|
||||||
|
extension FAAPI {
|
||||||
|
///第三方用户登录
|
||||||
|
static func requestSignThirdLogin(model: FAThirdSignModel, completer: ((_ token: FATokenModel?) -> Void)?) {
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/customer/login",
|
||||||
|
method: .post,
|
||||||
|
parameters: model.toDictionary(),
|
||||||
|
isLoding: false,
|
||||||
|
isToast: true) { (response: FANetworkManager.Response<FATokenModel>) in
|
||||||
|
completer?(response.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func requestLogout(completer: ((_ token: FATokenModel?) -> Void)?) {
|
||||||
|
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/customer/signout",
|
||||||
|
method: .post,
|
||||||
|
parameters: nil,
|
||||||
|
isLoding: true,
|
||||||
|
isToast: true) { (response: FANetworkManager.Response<FATokenModel>) in
|
||||||
|
completer?(response.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -84,4 +84,97 @@ class FAStatAPI: NSObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///进入APP
|
||||||
|
static func requestEnterApp() {
|
||||||
|
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/customer/enterTheApp",
|
||||||
|
method: .post,
|
||||||
|
parameters: nil,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: false,
|
||||||
|
) { (response: FANetworkManager.Response<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///离开APP
|
||||||
|
static func requestLeaveApp() {
|
||||||
|
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/customer/leaveApp",
|
||||||
|
method: .post,
|
||||||
|
parameters: nil,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: false,
|
||||||
|
) { (response: FANetworkManager.Response<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func requestStatOnLine() {
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/customer/onLine",
|
||||||
|
method: .post,
|
||||||
|
parameters: nil,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: false,
|
||||||
|
) { (response: FANetworkManager.Response<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func requestUploadApnsAuthorizationStatus(_ status: Bool) {
|
||||||
|
let parameters = [
|
||||||
|
"is_open_notice" : status ? 1 : 0
|
||||||
|
]
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/customer/uploadNoticeStatus",
|
||||||
|
method: .post,
|
||||||
|
parameters: parameters,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: false,
|
||||||
|
) { (response: FANetworkManager.Response<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func requestStatApnsClick(id: String, title: String) {
|
||||||
|
let parameters = [
|
||||||
|
"message_id" : id,
|
||||||
|
"title" : title
|
||||||
|
]
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/message/sendReport",
|
||||||
|
method: .post,
|
||||||
|
parameters: parameters,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: false,
|
||||||
|
) { (response: FANetworkManager.Response<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func requestUploadApnsDeviceToken(token: String) {
|
||||||
|
let parameters = [
|
||||||
|
"fcm_token": token
|
||||||
|
]
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/customer/firebaseToken",
|
||||||
|
method: .post,
|
||||||
|
parameters: parameters,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: false,
|
||||||
|
) { (response: FANetworkManager.Response<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FAStatAPI {
|
||||||
|
///更新通知状态
|
||||||
|
static func uploadApnsAuthorizationStatus() {
|
||||||
|
UNUserNotificationCenter.current().getNotificationSettings { settings in
|
||||||
|
if settings.authorizationStatus == .authorized {
|
||||||
|
requestUploadApnsAuthorizationStatus(true)
|
||||||
|
} else if settings.authorizationStatus == .denied {
|
||||||
|
requestUploadApnsAuthorizationStatus(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,4 +131,70 @@ class FAStoreAPI: NSObject {
|
|||||||
completer?(response.data)
|
completer?(response.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///金币包数据
|
||||||
|
static func requestCoinsPackData(completer: ((_ model: FACoinsPackModel?) -> Void)?) {
|
||||||
|
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/getReceiveDayCoinInfo",
|
||||||
|
method: .get,
|
||||||
|
parameters: nil,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: true,
|
||||||
|
) { (response: FANetworkManager.Response<FACoinsPackModel>) in
|
||||||
|
completer?(response.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///领取金币包金币
|
||||||
|
static func requestReceiveCoinsPackCoins(id: String?, completer: ((_ finish: Bool) -> Void)?) {
|
||||||
|
|
||||||
|
var parameters: [String : Any]? = nil
|
||||||
|
if let id = id {
|
||||||
|
parameters = [
|
||||||
|
"id" : id
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/receiveDayCoin",
|
||||||
|
method: .post,
|
||||||
|
parameters: parameters,
|
||||||
|
isLoding: true,
|
||||||
|
isToast: true,
|
||||||
|
) { (response: FANetworkManager.Response<FACoinsPackModel>) in
|
||||||
|
if response.isSuccess {
|
||||||
|
completer?(true)
|
||||||
|
} else {
|
||||||
|
completer?(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///获取金币包可领取信息
|
||||||
|
static func requestCoinBagCanReceiveInfo(completer: ((_ model: FACoinPackCanReceiveModel?) -> Void)?) {
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/getReceiveDayCoin",
|
||||||
|
method: .get,
|
||||||
|
parameters: nil,
|
||||||
|
isLoding: false,
|
||||||
|
isToast: true,
|
||||||
|
) { (response: FANetworkManager.Response<FACoinPackCanReceiveModel>) in
|
||||||
|
completer?(response.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///挽留支付项
|
||||||
|
static func requestVipRetainPayInfo(completer: ((_ model: FAPayAlertModel?) -> Void)?) {
|
||||||
|
|
||||||
|
FANetworkManager.manager.request(FABaseURL + "/getRetainVipPaySetting",
|
||||||
|
method: .get,
|
||||||
|
parameters: nil,
|
||||||
|
isLoding: true,
|
||||||
|
isToast: true,
|
||||||
|
) { (response: FANetworkManager.Response<FAPayAlertModel>) in
|
||||||
|
if let _ = response.data?.info {
|
||||||
|
completer?(response.data)
|
||||||
|
} else {
|
||||||
|
completer?(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,3 +16,6 @@ let kFAFeedBackHomeWebUrl = FACampaignWebURL + "/pages/leave/index"
|
|||||||
let kFAFeedBackListWebUrl = FACampaignWebURL + "/pages/leave/list"
|
let kFAFeedBackListWebUrl = FACampaignWebURL + "/pages/leave/list"
|
||||||
///反馈详情
|
///反馈详情
|
||||||
let kFAFeedBackDetailWebUrl = FACampaignWebURL + "/pages/leave/detail"
|
let kFAFeedBackDetailWebUrl = FACampaignWebURL + "/pages/leave/detail"
|
||||||
|
|
||||||
|
///注销账号
|
||||||
|
let kFALogoutWebUrl = FACampaignWebURL + "/pages/setting/logout"
|
||||||
|
|||||||
@ -186,7 +186,8 @@ extension FANetworkManager {
|
|||||||
"model" : UIDevice.current.machineModelName ?? "",
|
"model" : UIDevice.current.machineModelName ?? "",
|
||||||
"idfa" : ASIdentifierManager.shared().advertisingIdentifier.uuidString,
|
"idfa" : ASIdentifierManager.shared().advertisingIdentifier.uuidString,
|
||||||
"device-id" : FADeviceIDManager.shared.id, //设备id
|
"device-id" : FADeviceIDManager.shared.id, //设备id
|
||||||
"device-gaid" : UIDevice.current.identifierForVendor?.uuidString ?? ""
|
"device-gaid" : UIDevice.current.identifierForVendor?.uuidString ?? "",
|
||||||
|
"product-prefix" : FAIapManager.IAPPrefix
|
||||||
]
|
]
|
||||||
return HTTPHeaders(dic)
|
return HTTPHeaders(dic)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class FAAppWebViewController: FABaseWebViewController {
|
|||||||
|
|
||||||
private var receiveDataCount = 0
|
private var receiveDataCount = 0
|
||||||
|
|
||||||
var theme: String? = "theme_1"
|
var theme: String? = "theme_3"
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
@ -26,6 +26,8 @@ class FAAppWebViewController: FABaseWebViewController {
|
|||||||
self.title = "Feedback".localized
|
self.title = "Feedback".localized
|
||||||
} else if webUrl == kFAFeedBackDetailWebUrl {
|
} else if webUrl == kFAFeedBackDetailWebUrl {
|
||||||
self.title = "Feedback Details".localized
|
self.title = "Feedback Details".localized
|
||||||
|
} else if webUrl == kFALogoutWebUrl {
|
||||||
|
self.title = "Account Deletion".localized
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -51,6 +53,7 @@ extension FAAppWebViewController {
|
|||||||
"time_zone" : String.timeZone(),
|
"time_zone" : String.timeZone(),
|
||||||
"lang" : FALocalized.manager.currentLocalizedKey,
|
"lang" : FALocalized.manager.currentLocalizedKey,
|
||||||
"type" : "ios",
|
"type" : "ios",
|
||||||
|
"device-id" : FADeviceIDManager.shared.id
|
||||||
]
|
]
|
||||||
|
|
||||||
if let theme = theme {
|
if let theme = theme {
|
||||||
|
|||||||
@ -18,6 +18,8 @@ let kFAWebMessageOpenFeedbackList = "openFeedbackList"
|
|||||||
let kFAWebMessageOpenFeedbackDetail = "openFeedbackDetail"
|
let kFAWebMessageOpenFeedbackDetail = "openFeedbackDetail"
|
||||||
///打开相册
|
///打开相册
|
||||||
let kFAWebMessageOpenPhotoPicker = "openPhotoPicker"
|
let kFAWebMessageOpenPhotoPicker = "openPhotoPicker"
|
||||||
|
///删除账号成功
|
||||||
|
let kFAWebMessageAccountDeletionFinish = "accountLogout"
|
||||||
|
|
||||||
extension FABaseWebViewController {
|
extension FABaseWebViewController {
|
||||||
|
|
||||||
@ -50,7 +52,8 @@ extension FABaseWebViewController {
|
|||||||
let data = model.data
|
let data = model.data
|
||||||
|
|
||||||
if type == "login" {
|
if type == "login" {
|
||||||
// VPLoginManager.manager.openLogin()
|
let view = FALoginView()
|
||||||
|
view.present(in: nil)
|
||||||
|
|
||||||
} else if type == "open_notify" {
|
} else if type == "open_notify" {
|
||||||
// openNotify()
|
// openNotify()
|
||||||
@ -69,6 +72,9 @@ extension FABaseWebViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kFAWebMessageAccountDeletionFinish:
|
||||||
|
self.navigationController?.popToRootViewController(animated: true)
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|||||||
@ -38,6 +38,7 @@ class FAWebView: WKWebView {
|
|||||||
kFAWebMessageOpenFeedbackList,
|
kFAWebMessageOpenFeedbackList,
|
||||||
kFAWebMessageOpenFeedbackDetail,
|
kFAWebMessageOpenFeedbackDetail,
|
||||||
kFAWebMessageOpenPhotoPicker,
|
kFAWebMessageOpenPhotoPicker,
|
||||||
|
kFAWebMessageAccountDeletionFinish,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,17 @@ class FAHomeViewController: FAViewController {
|
|||||||
return view
|
return view
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private lazy var coinPackButton: FAHomeCoinsPackButton = {
|
||||||
|
let view = FAHomeCoinsPackButton()
|
||||||
|
view.addAction(UIAction(handler: { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
let vc = FACoinPackViewController()
|
||||||
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
|
||||||
|
}), for: .touchUpInside)
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
NotificationCenter.default.removeObserver(self)
|
NotificationCenter.default.removeObserver(self)
|
||||||
}
|
}
|
||||||
@ -72,6 +83,8 @@ class FAHomeViewController: FAViewController {
|
|||||||
fa_setupLayout()
|
fa_setupLayout()
|
||||||
|
|
||||||
requestAllData(completer: nil)
|
requestAllData(completer: nil)
|
||||||
|
|
||||||
|
requestCoinBagCanReceiveInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
@ -104,6 +117,7 @@ extension FAHomeViewController {
|
|||||||
view.addSubview(searchButton)
|
view.addSubview(searchButton)
|
||||||
view.addSubview(collectionView)
|
view.addSubview(collectionView)
|
||||||
view.addSubview(playHistoryView)
|
view.addSubview(playHistoryView)
|
||||||
|
view.addSubview(coinPackButton)
|
||||||
|
|
||||||
titleView.snp.makeConstraints { make in
|
titleView.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(16)
|
make.left.equalToSuperview().offset(16)
|
||||||
@ -125,6 +139,11 @@ extension FAHomeViewController {
|
|||||||
make.centerX.equalToSuperview()
|
make.centerX.equalToSuperview()
|
||||||
make.bottom.equalToSuperview().offset(-10)
|
make.bottom.equalToSuperview().offset(-10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinPackButton.snp.makeConstraints { make in
|
||||||
|
make.right.equalToSuperview().offset(-21)
|
||||||
|
make.bottom.equalTo(playHistoryView.snp.top).offset(5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -280,4 +299,22 @@ extension FAHomeViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func requestCoinBagCanReceiveInfo() {
|
||||||
|
|
||||||
|
FAStoreAPI.requestCoinBagCanReceiveInfo { [weak self] model in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let model = model else { return }
|
||||||
|
let coins = model.coins ?? 0
|
||||||
|
if coins > 0 {
|
||||||
|
let view = FACoinsPackAlert()
|
||||||
|
view.coinsCount = coins
|
||||||
|
view.show(in: self.view)
|
||||||
|
view.clickHighlightButton = { [weak self] in
|
||||||
|
let vc = FACoinPackViewController()
|
||||||
|
self?.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
50
Fableon/Object/Class/Home/V/FAHomeCoinsPackButton.swift
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// FAHomeCoinsPackButton.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SnapKit
|
||||||
|
|
||||||
|
class FAHomeCoinsPackButton: UIControl {
|
||||||
|
|
||||||
|
private lazy var bgImageView = UIImageView(image: UIImage(named: "Group 2072750470"))
|
||||||
|
private lazy var textBgImageView = UIImageView(image: UIImage(named: "按钮"))
|
||||||
|
|
||||||
|
private lazy var textLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 10, weight: .init(900)).withBoldItalic()
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.text = "Daily Coins".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
addSubview(bgImageView)
|
||||||
|
addSubview(textBgImageView)
|
||||||
|
textBgImageView.addSubview(textLabel)
|
||||||
|
|
||||||
|
bgImageView.snp.makeConstraints { make in
|
||||||
|
make.left.right.top.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
textBgImageView.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(50)
|
||||||
|
}
|
||||||
|
|
||||||
|
textLabel.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
216
Fableon/Object/Class/Me/C/FACoinPackViewController.swift
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
//
|
||||||
|
// FACoinPackViewController.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import YYText
|
||||||
|
|
||||||
|
class FACoinPackViewController: FAViewController {
|
||||||
|
|
||||||
|
private var model: FACoinsPackModel? {
|
||||||
|
didSet {
|
||||||
|
headerView.model = model
|
||||||
|
claimView.dataArr = model?.receive_list ?? []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var payDataModel : FAPayDateModel? {
|
||||||
|
didSet {
|
||||||
|
var arr: [FAPayItem] = []
|
||||||
|
|
||||||
|
payDataModel?.list_coins?.forEach {
|
||||||
|
if $0.buy_type == .subCoins {
|
||||||
|
arr.append($0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.buyView.dataArr = arr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var payDataRequest: FAPayDataRequest?
|
||||||
|
|
||||||
|
private lazy var bgIconImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "查看图片 25"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var scrollView: FAScrollView = {
|
||||||
|
let scrollView = FAScrollView()
|
||||||
|
return scrollView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var headerView: FACoinPackHeaderView = {
|
||||||
|
let view = FACoinPackHeaderView()
|
||||||
|
view.clickClaimButton = { [weak self] in
|
||||||
|
self?.requestReceiveCoins(nil)
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var stackView: UIStackView = {
|
||||||
|
let stackView = UIStackView()
|
||||||
|
stackView.axis = .vertical
|
||||||
|
stackView.spacing = 19
|
||||||
|
return stackView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var claimView: FACoinsPackClaimListView = {
|
||||||
|
let view = FACoinsPackClaimListView()
|
||||||
|
view.clickClaimButton = { [weak self] id in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.requestReceiveCoins(id)
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var buyView: FACoinsPackBuyView = {
|
||||||
|
let view = FACoinsPackBuyView()
|
||||||
|
view.buyFinishHandle = { [weak self] in
|
||||||
|
self?.requestCoinsPackData()
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var tipView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.addSubview(tipTitleLabel)
|
||||||
|
view.addSubview(tipTextLabel)
|
||||||
|
|
||||||
|
tipTitleLabel.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
tipTextLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-16)
|
||||||
|
make.top.equalTo(tipTitleLabel.snp.bottom).offset(4)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var tipTitleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .medium)
|
||||||
|
label.textColor = .FFFFFF.withAlphaComponent(0.5)
|
||||||
|
label.text = "coins_pack_tips_title".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var tipTextLabel: UILabel = {
|
||||||
|
let att = NSMutableAttributedString(string: "coins_pack_tips".localized)
|
||||||
|
att.yy_lineSpacing = 3
|
||||||
|
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 10, weight: .regular)
|
||||||
|
label.textColor = .FFFFFF.withAlphaComponent(0.5)
|
||||||
|
label.attributedText = att
|
||||||
|
label.numberOfLines = 0
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
self.title = "My Refills".localized
|
||||||
|
payDataModel = FAIapManager.manager.payDateModel
|
||||||
|
|
||||||
|
fa_setupLayout()
|
||||||
|
|
||||||
|
requestCoinsPackData()
|
||||||
|
|
||||||
|
updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
||||||
|
self.fa_setNavigationStyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateLayout() {
|
||||||
|
stackView.fa_removeAllArrangedSubview()
|
||||||
|
|
||||||
|
if self.claimView.dataArr.count > 0 {
|
||||||
|
stackView.addArrangedSubview(self.claimView)
|
||||||
|
} else if self.buyView.dataArr.count > 0 {
|
||||||
|
stackView.addArrangedSubview(self.buyView)
|
||||||
|
}
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(tipView)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinPackViewController {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
view.addSubview(bgIconImageView)
|
||||||
|
view.addSubview(scrollView)
|
||||||
|
scrollView.addSubview(headerView)
|
||||||
|
scrollView.addSubview(stackView)
|
||||||
|
|
||||||
|
bgIconImageView.snp.makeConstraints { make in
|
||||||
|
make.right.equalToSuperview()
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollView.snp.makeConstraints { make in
|
||||||
|
make.left.right.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(UIScreen.navBarHeight)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
headerView.snp.makeConstraints { make in
|
||||||
|
make.left.centerX.equalToSuperview()
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
stackView.snp.makeConstraints { make in
|
||||||
|
make.left.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(headerView.snp.bottom).offset(16)
|
||||||
|
make.bottom.equalToSuperview().offset(-(UIScreen.safeBottom + 10))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinPackViewController {
|
||||||
|
|
||||||
|
private func requestCoinsPackData() {
|
||||||
|
FAStoreAPI.requestCoinsPackData { [weak self] model in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let model = model else { return }
|
||||||
|
self.model = model
|
||||||
|
|
||||||
|
if (model.receive_list?.count ?? 0) == 0 {
|
||||||
|
self.requestPayData()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.updateLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private func requestPayData() {
|
||||||
|
self.payDataRequest = FAPayDataRequest()
|
||||||
|
self.payDataRequest?.requestProducts { [weak self] model in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let model = model else { return }
|
||||||
|
self.payDataModel = model
|
||||||
|
|
||||||
|
self.updateLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func requestReceiveCoins(_ id: String?) {
|
||||||
|
FAStoreAPI.requestReceiveCoinsPackCoins(id: id) { [weak self] finish in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.requestCoinsPackData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -16,11 +16,12 @@ class FAMeListViewController: FAViewController, JXPagingViewListViewDelegate {
|
|||||||
let arr = [
|
let arr = [
|
||||||
FAMeItemModel(type: .feedback, name: "Feedback".localized, icon: UIImage(named: "icon_feedback")),
|
FAMeItemModel(type: .feedback, name: "Feedback".localized, icon: UIImage(named: "icon_feedback")),
|
||||||
FAMeItemModel(type: .about, name: "About".localized, icon: UIImage(named: "icon_about")),
|
FAMeItemModel(type: .about, name: "About".localized, icon: UIImage(named: "icon_about")),
|
||||||
// FAMeItemModel(type: .setting, name: "Setting".localized, icon: UIImage(named: "icon_setting"))
|
|
||||||
|
|
||||||
FAMeItemModel(type: .privacyPolicy, name: "Privacy Policy".localized, icon: UIImage(named: "icon_privacy")),
|
FAMeItemModel(type: .privacyPolicy, name: "Privacy Policy".localized, icon: UIImage(named: "icon_privacy")),
|
||||||
FAMeItemModel(type: .userAgreement, name: "User Agreement".localized, icon: UIImage(named: "icon_user")),
|
FAMeItemModel(type: .userAgreement, name: "User Agreement".localized, icon: UIImage(named: "icon_user")),
|
||||||
FAMeItemModel(type: .visitWebsite, name: "Visit Website".localized, icon: UIImage(named: "icon_visit")),
|
FAMeItemModel(type: .visitWebsite, name: "Visit Website".localized, icon: UIImage(named: "icon_visit")),
|
||||||
|
|
||||||
|
FAMeItemModel(type: .setting, name: "Setting".localized, icon: UIImage(named: "icon_setting"))
|
||||||
]
|
]
|
||||||
return arr
|
return arr
|
||||||
}()
|
}()
|
||||||
|
|||||||
@ -9,10 +9,34 @@ import UIKit
|
|||||||
|
|
||||||
class FASettingViewController: FAViewController {
|
class FASettingViewController: FAViewController {
|
||||||
|
|
||||||
|
private lazy var dataArr: [FAMeItemModel] = [
|
||||||
|
FAMeItemModel(type: .deleteAccount, name: "Account Deletion".localized, icon: nil)
|
||||||
|
]
|
||||||
|
|
||||||
|
private lazy var tableView: FATableView = {
|
||||||
|
let tableView = FATableView(frame: .zero, style: .plain)
|
||||||
|
tableView.delegate = self
|
||||||
|
tableView.dataSource = self
|
||||||
|
tableView.rowHeight = 48
|
||||||
|
tableView.contentInset = .init(top: 25, left: 0, bottom: 0, right: 0)
|
||||||
|
tableView.separatorStyle = .none
|
||||||
|
tableView.register(UINib(nibName: "FASettingCell", bundle: nil), forCellReuseIdentifier: "cell")
|
||||||
|
return tableView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var footerView: FASettingFooterView = {
|
||||||
|
let view = FASettingFooterView(frame: .init(x: 0, y: 0, width: UIScreen.width, height: 60))
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
self.title = "Settings".localized
|
self.title = "Settings".localized
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(userInfoUpdateNotification), name: FALogin.userInfoUpdateNotification, object: nil)
|
||||||
|
|
||||||
|
|
||||||
|
userInfoUpdateNotification()
|
||||||
|
fa_setupLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
@ -21,6 +45,51 @@ class FASettingViewController: FAViewController {
|
|||||||
self.fa_setNavigationStyle()
|
self.fa_setNavigationStyle()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func userInfoUpdateNotification() {
|
||||||
|
if FALogin.manager.isLogin {
|
||||||
|
tableView.tableFooterView = footerView
|
||||||
|
} else {
|
||||||
|
tableView.tableFooterView = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension FASettingViewController {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
|
||||||
|
|
||||||
|
view.addSubview(tableView)
|
||||||
|
|
||||||
|
tableView.snp.makeConstraints { make in
|
||||||
|
make.left.right.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(UIScreen.navBarHeight)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: UITableViewDelegate UITableViewDataSource
|
||||||
|
extension FASettingViewController: UITableViewDelegate, UITableViewDataSource {
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
let item = dataArr[indexPath.row]
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FASettingCell
|
||||||
|
cell.titleLabel.text = item.name
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return self.dataArr.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
let vc = FAAppWebViewController()
|
||||||
|
vc.webUrl = kFALogoutWebUrl
|
||||||
|
vc.theme = "theme_4"
|
||||||
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ struct FAMeItemModel {
|
|||||||
case purchaseRecords
|
case purchaseRecords
|
||||||
///金币奖励
|
///金币奖励
|
||||||
case rewardCoins
|
case rewardCoins
|
||||||
|
case deleteAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
266
Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
//
|
||||||
|
// FACoinPackHeaderView.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FACoinPackHeaderView: UIView {
|
||||||
|
|
||||||
|
var clickClaimButton: (() -> Void)?
|
||||||
|
|
||||||
|
var model: FACoinsPackModel? {
|
||||||
|
didSet {
|
||||||
|
coinsView1.coins = model?.week_max_total
|
||||||
|
coinsView2.coins = model?.week_total
|
||||||
|
|
||||||
|
activeCountLabel.text = "\(model?.receive_count ?? 0)"
|
||||||
|
|
||||||
|
if let coin = model?.receive_coins, coin > 0 {
|
||||||
|
claimButton.isEnabled = true
|
||||||
|
} else {
|
||||||
|
claimButton.isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
claimButton.setNeedsUpdateConfiguration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var titleView: FACoinPackTitleView = {
|
||||||
|
let view = FACoinPackTitleView()
|
||||||
|
view.dotColor = .C_5_DDF_5
|
||||||
|
view.font = .font(ofSize: 14, weight: .regular)
|
||||||
|
view.textColors = [UIColor.C_5_DDF_5.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
view.text = "REWARDS OVERVIEW".localized
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var coinsView1: CoinsView = {
|
||||||
|
let view = CoinsView()
|
||||||
|
view.title = "Weekly Total".localized
|
||||||
|
view.coins = 0
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var coinsView2: CoinsView = {
|
||||||
|
let view = CoinsView()
|
||||||
|
view.title = "Claimable Coins".localized
|
||||||
|
view.coins = 0
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var lineView1: UIView = {
|
||||||
|
let view = UIImageView(image: UIImage(named: "间隔线"))
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var lineView2: UIView = {
|
||||||
|
let view = UIImageView(image: UIImage(named: "横间隔虚线"))
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var activeCountTitleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .regular)
|
||||||
|
label.textColor = .FFFFFF.withAlphaComponent(0.5)
|
||||||
|
label.text = "Active Refills".localized + ": "
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var activeCountLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .medium)
|
||||||
|
label.textColor = ._53_A_2_F_1
|
||||||
|
label.text = "0"
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var claimButton: UIButton = {
|
||||||
|
let config = UIButton.Configuration.plain()
|
||||||
|
let button = FAGradientButton(configuration: config, primaryAction: UIAction(handler: { [weak self] _ in
|
||||||
|
self?.clickClaimButton?()
|
||||||
|
}))
|
||||||
|
button.isEnabled = false
|
||||||
|
button.layer.cornerRadius = 24
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.fa_locations = [0, 1]
|
||||||
|
button.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
button.fa_endPoint = .init(x: 1, y: 0.5)
|
||||||
|
button.configurationUpdateHandler = { [weak self] button in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let button = button as? FAGradientButton else { return }
|
||||||
|
if button.isEnabled {
|
||||||
|
button.fa_colors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
|
||||||
|
let coinImage = UIImage(named: "coins_icon_03")!
|
||||||
|
let coinText = NSTextAttachment(image: coinImage)
|
||||||
|
coinText.bounds = .init(x: 0, y: -2.5, width: coinImage.size.width, height: coinImage.size.height)
|
||||||
|
let coinAtt = AttributedString(NSAttributedString(attachment: coinText))
|
||||||
|
|
||||||
|
let textAtt = AttributedString("Claim All".localized + " ", attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||||
|
.foregroundColor : UIColor.FFFFFF
|
||||||
|
]))
|
||||||
|
|
||||||
|
let countAtt = AttributedString(" \(0)".localized, attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||||
|
.foregroundColor : UIColor.FFFFFF
|
||||||
|
]))
|
||||||
|
|
||||||
|
button.configuration?.attributedTitle = textAtt + coinAtt + countAtt
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
button.fa_colors = [UIColor._6_D_6_D_6_D.cgColor, UIColor._6_D_6_D_6_D.cgColor]
|
||||||
|
button.configuration?.attributedTitle = AttributedString("Get a Refill to Claim".localized, attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||||
|
.foregroundColor : UIColor.FFFFFF.withAlphaComponent(0.5)
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinPackHeaderView {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
addSubview(titleView)
|
||||||
|
addSubview(coinsView1)
|
||||||
|
addSubview(coinsView2)
|
||||||
|
addSubview(lineView1)
|
||||||
|
addSubview(activeCountTitleLabel)
|
||||||
|
addSubview(activeCountLabel)
|
||||||
|
addSubview(claimButton)
|
||||||
|
addSubview(lineView2)
|
||||||
|
|
||||||
|
titleView.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.top.equalToSuperview().offset(20)
|
||||||
|
}
|
||||||
|
|
||||||
|
coinsView1.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(28)
|
||||||
|
make.top.equalTo(titleView.snp.bottom).offset(23)
|
||||||
|
}
|
||||||
|
|
||||||
|
lineView1.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(coinsView1)
|
||||||
|
make.left.equalTo(coinsView1.snp.right).offset(18)
|
||||||
|
}
|
||||||
|
|
||||||
|
coinsView2.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(lineView1)
|
||||||
|
make.left.equalTo(lineView1.snp.right).offset(18)
|
||||||
|
}
|
||||||
|
|
||||||
|
activeCountTitleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(coinsView1)
|
||||||
|
make.top.equalTo(coinsView1.snp.bottom).offset(23)
|
||||||
|
}
|
||||||
|
|
||||||
|
activeCountLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(activeCountTitleLabel.snp.right)
|
||||||
|
make.centerY.equalTo(activeCountTitleLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
claimButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(23)
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(activeCountTitleLabel.snp.bottom).offset(12)
|
||||||
|
make.height.equalTo(48)
|
||||||
|
make.bottom.equalToSuperview().offset(-16)
|
||||||
|
}
|
||||||
|
|
||||||
|
lineView2.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(claimButton)
|
||||||
|
make.right.equalTo(claimButton)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension FACoinPackHeaderView {
|
||||||
|
|
||||||
|
class CoinsView: UIView {
|
||||||
|
var title: String? {
|
||||||
|
didSet {
|
||||||
|
titleLabel.text = title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var coins: Int? {
|
||||||
|
didSet {
|
||||||
|
coinsLabel.text = "\(coins ?? 0)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .bold)
|
||||||
|
label.textColor = .FFFFFF.withAlphaComponent(0.5)
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var iconImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "coins_icon_09"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var coinsLabel: UILabel = {
|
||||||
|
let label = FALabel()
|
||||||
|
label.font = .font(ofSize: 18, weight: .bold)
|
||||||
|
label.textColors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
label.textStartPoint = .init(x: 0, y: 0.5)
|
||||||
|
label.textEndPoint = .init(x: 1, y: 0.5)
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
addSubview(titleLabel)
|
||||||
|
addSubview(iconImageView)
|
||||||
|
addSubview(coinsLabel)
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
iconImageView.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.top.equalTo(titleLabel.snp.bottom).offset(4)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
coinsLabel.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(iconImageView)
|
||||||
|
make.left.equalTo(iconImageView.snp.right).offset(4)
|
||||||
|
make.right.lessThanOrEqualToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
91
Fableon/Object/Class/Me/V/FACoinPackTitleView.swift
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// FACoinPackTitleView.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FACoinPackTitleView: UIView {
|
||||||
|
|
||||||
|
var text: String? {
|
||||||
|
didSet {
|
||||||
|
label.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var font: UIFont? {
|
||||||
|
didSet {
|
||||||
|
label.font = font
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var textColors: [CGColor]? {
|
||||||
|
didSet {
|
||||||
|
label.textColors = textColors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var dotColor: UIColor? {
|
||||||
|
didSet {
|
||||||
|
dotView1.backgroundColor = dotColor
|
||||||
|
dotView2.backgroundColor = dotColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var dotView1: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.layer.cornerRadius = 3
|
||||||
|
view.layer.masksToBounds = true
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var dotView2: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.layer.cornerRadius = 3
|
||||||
|
view.layer.masksToBounds = true
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var label: FALabel = {
|
||||||
|
let label = FALabel()
|
||||||
|
label.textStartPoint = .init(x: 0, y: 0.5)
|
||||||
|
label.textEndPoint = .init(x: 1, y: 0.5)
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
addSubview(dotView1)
|
||||||
|
addSubview(dotView2)
|
||||||
|
addSubview(label)
|
||||||
|
|
||||||
|
dotView1.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.width.height.equalTo(6)
|
||||||
|
make.bottom.lessThanOrEqualToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
label.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.bottom.lessThanOrEqualToSuperview()
|
||||||
|
make.left.equalTo(dotView1.snp.right).offset(6)
|
||||||
|
}
|
||||||
|
|
||||||
|
dotView2.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.bottom.lessThanOrEqualToSuperview()
|
||||||
|
make.right.equalToSuperview()
|
||||||
|
make.width.height.equalTo(dotView1)
|
||||||
|
make.left.equalTo(label.snp.right).offset(6)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
112
Fableon/Object/Class/Me/V/FACoinsPackBuyView.swift
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
//
|
||||||
|
// FACoinsPackBuyView.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FACoinsPackBuyView: UIView {
|
||||||
|
|
||||||
|
var buyFinishHandle: (() -> Void)?
|
||||||
|
|
||||||
|
var dataArr: [FAPayItem] = []
|
||||||
|
|
||||||
|
private lazy var titleView: FACoinPackTitleView = {
|
||||||
|
let view = FACoinPackTitleView()
|
||||||
|
view.dotColor = .C_5_DDF_5
|
||||||
|
view.textColors = [UIColor.C_5_DDF_5.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
view.font = .font(ofSize: 14, weight: .regular)
|
||||||
|
view.text = "Weekly Refill".localized.uppercased()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
||||||
|
let layout = UICollectionViewFlowLayout()
|
||||||
|
layout.itemSize = .init(width: UIScreen.width - 32, height: 84)
|
||||||
|
layout.minimumLineSpacing = 12
|
||||||
|
return layout
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var collectionView: FACollectionView = {
|
||||||
|
let collectionView = FACollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||||
|
collectionView.delegate = self
|
||||||
|
collectionView.dataSource = self
|
||||||
|
collectionView.addObserver(self, forKeyPath: "contentSize", context: nil)
|
||||||
|
collectionView.register(FAStoreCoinsPackCell.self, forCellWithReuseIdentifier: "cell")
|
||||||
|
return collectionView
|
||||||
|
}()
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
collectionView.removeObserver(self, forKeyPath: "contentSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||||
|
if keyPath == "contentSize" {
|
||||||
|
let height = self.collectionView.contentSize.height + 1
|
||||||
|
collectionView.snp.updateConstraints { make in
|
||||||
|
make.height.equalTo(height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinsPackBuyView {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
addSubview(titleView)
|
||||||
|
addSubview(collectionView)
|
||||||
|
|
||||||
|
titleView.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionView.snp.makeConstraints { make in
|
||||||
|
make.left.right.bottom.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(30)
|
||||||
|
make.height.equalTo(1)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: UICollectionViewDelegate UICollectionViewDataSource
|
||||||
|
extension FACoinsPackBuyView: UICollectionViewDelegate, UICollectionViewDataSource {
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! FAStoreCoinsPackCell
|
||||||
|
cell.model = self.dataArr[indexPath.row]
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return dataArr.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
let model = self.dataArr[indexPath.row]
|
||||||
|
|
||||||
|
let view = FACoinPackConfirmView()
|
||||||
|
view.model = model
|
||||||
|
view.buyFinishHandle = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
FALogin.manager.requestUserInfo(completer: nil)
|
||||||
|
self.buyFinishHandle?()
|
||||||
|
}
|
||||||
|
view.present(in: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
280
Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
//
|
||||||
|
// FACoinsPackClaimListCell.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import YYText
|
||||||
|
|
||||||
|
class FACoinsPackClaimListCell: UICollectionViewCell {
|
||||||
|
|
||||||
|
var clickClaimButton: ((_ id: String?) -> Void)?
|
||||||
|
|
||||||
|
var model: FACoinsPackReceiveModel? {
|
||||||
|
didSet {
|
||||||
|
coinsView1.coins = model?.week_max_total
|
||||||
|
coinsView2.coins = model?.week_remaining_total
|
||||||
|
|
||||||
|
claimButton.isEnabled = (model?.receive_coins ?? 0) > 0
|
||||||
|
claimButton.setNeedsUpdateConfiguration()
|
||||||
|
|
||||||
|
let titleAtt = NSMutableAttributedString(string: "\(model?.title ?? "")")
|
||||||
|
titleAtt.yy_color = .FFFFFF
|
||||||
|
titleAtt.yy_font = .font(ofSize: 14, weight: .bold)
|
||||||
|
|
||||||
|
let dayAtt = NSMutableAttributedString(string: " (Day \(model?.day_text ?? ""))")
|
||||||
|
dayAtt.yy_color = ._20_A_1_FF
|
||||||
|
dayAtt.yy_font = .font(ofSize: 14, weight: .regular)
|
||||||
|
titleAtt.append(dayAtt)
|
||||||
|
|
||||||
|
titleLabel.attributedText = titleAtt
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var bgView: FAGradientView = {
|
||||||
|
let view = FAGradientView()
|
||||||
|
view.fa_colors = [UIColor._524_B_8_E.cgColor, UIColor._303265.cgColor]
|
||||||
|
view.fa_locations = [0, 1]
|
||||||
|
view.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
view.fa_endPoint = .init(x: 1, y: 0.5)
|
||||||
|
view.layer.cornerRadius = 12
|
||||||
|
view.layer.masksToBounds = true
|
||||||
|
view.layer.borderWidth = 1
|
||||||
|
view.layer.borderColor = UIColor.E_5_E_5_E_5.cgColor
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var bgIconImageView1 = UIImageView(image: UIImage(named: "coin_attachment_01"))
|
||||||
|
private lazy var bgIconImageView2 = UIImageView(image: UIImage(named: "coin_attachment_03"))
|
||||||
|
private lazy var bgIconImageView4 = UIImageView(image: UIImage(named: "coin_attachment_04"))
|
||||||
|
private lazy var bgIconImageView5 = UIImageView(image: UIImage(named: "coin_attachment_05"))
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.numberOfLines = 0
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var lineView1 = UIImageView(image: UIImage(named: "横间隔虚线"))
|
||||||
|
private lazy var lineView2 = UIImageView(image: UIImage(named: "间隔线"))
|
||||||
|
|
||||||
|
private lazy var coinsView1: CoinsView = {
|
||||||
|
let view = CoinsView()
|
||||||
|
view.title = "Total Reward".localized
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var coinsView2: CoinsView = {
|
||||||
|
let view = CoinsView()
|
||||||
|
view.title = "Remaining".localized
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var claimButton: UIButton = {
|
||||||
|
var config = UIButton.Configuration.plain()
|
||||||
|
config.titleAlignment = .center
|
||||||
|
|
||||||
|
let button = FAGradientButton(configuration: config, primaryAction: UIAction(handler: { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.clickClaimButton?(self.model?.id)
|
||||||
|
}))
|
||||||
|
button.layer.cornerRadius = 24
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.fa_locations = [0, 1]
|
||||||
|
button.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
button.fa_endPoint = .init(x: 1, y: 0.5)
|
||||||
|
button.configurationUpdateHandler = { [weak self] button in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let button = button as? FAGradientButton else { return }
|
||||||
|
|
||||||
|
if button.isEnabled {
|
||||||
|
button.fa_colors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
|
||||||
|
let coinImage = UIImage(named: "coins_icon_03")!
|
||||||
|
let coinText = NSTextAttachment(image: coinImage)
|
||||||
|
coinText.bounds = .init(x: 0, y: -2.5, width: coinImage.size.width, height: coinImage.size.height)
|
||||||
|
let coinAtt = AttributedString(NSAttributedString(attachment: coinText))
|
||||||
|
let countAtt = AttributedString(" \(self.model?.receive_coins ?? 0)", attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 12, weight: .bold),
|
||||||
|
.foregroundColor : UIColor._000000.withAlphaComponent(0.5)
|
||||||
|
]))
|
||||||
|
|
||||||
|
|
||||||
|
button.configuration?.attributedTitle = AttributedString("Claim".localized, attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||||
|
.foregroundColor : UIColor._114_CEE
|
||||||
|
]))
|
||||||
|
|
||||||
|
button.configuration?.attributedSubtitle = coinAtt + countAtt
|
||||||
|
|
||||||
|
} else {
|
||||||
|
button.fa_colors = [UIColor.BCBCBC.cgColor, UIColor.BCBCBC.cgColor]
|
||||||
|
button.configuration?.attributedTitle = AttributedString("Claim".localized, attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||||
|
.foregroundColor : UIColor.FFFFFF_0_8
|
||||||
|
]))
|
||||||
|
|
||||||
|
button.configuration?.attributedSubtitle = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinsPackClaimListCell {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
contentView.addSubview(bgView)
|
||||||
|
bgView.addSubview(bgIconImageView5)
|
||||||
|
bgView.addSubview(bgIconImageView4)
|
||||||
|
bgView.addSubview(bgIconImageView1)
|
||||||
|
bgView.addSubview(bgIconImageView2)
|
||||||
|
bgView.addSubview(titleLabel)
|
||||||
|
bgView.addSubview(lineView1)
|
||||||
|
bgView.addSubview(lineView2)
|
||||||
|
bgView.addSubview(coinsView1)
|
||||||
|
bgView.addSubview(coinsView2)
|
||||||
|
bgView.addSubview(claimButton)
|
||||||
|
|
||||||
|
bgView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView1.snp.makeConstraints { make in
|
||||||
|
make.left.top.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView2.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.right.equalToSuperview().offset(-8)
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView4.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.centerX.equalTo(bgIconImageView2)
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView5.snp.makeConstraints { make in
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
make.left.equalToSuperview().offset(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(12)
|
||||||
|
make.centerY.equalTo(self.bgView.snp.top).offset(25)
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-12)
|
||||||
|
}
|
||||||
|
|
||||||
|
lineView1.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(12)
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(48)
|
||||||
|
}
|
||||||
|
|
||||||
|
coinsView1.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(12)
|
||||||
|
make.bottom.equalToSuperview().offset(-18)
|
||||||
|
}
|
||||||
|
|
||||||
|
lineView2.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(coinsView1)
|
||||||
|
make.left.equalTo(coinsView1.snp.right).offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
coinsView2.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(coinsView1)
|
||||||
|
make.left.equalTo(lineView2.snp.right).offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
claimButton.snp.makeConstraints { make in
|
||||||
|
make.right.equalToSuperview().offset(-12)
|
||||||
|
make.centerY.equalTo(coinsView1)
|
||||||
|
make.height.equalTo(48)
|
||||||
|
make.width.equalTo(120)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinsPackClaimListCell {
|
||||||
|
|
||||||
|
class CoinsView: UIView {
|
||||||
|
|
||||||
|
var title: String? {
|
||||||
|
didSet {
|
||||||
|
titleLabel.text = title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var coins: Int? {
|
||||||
|
didSet {
|
||||||
|
coinsLabel.text = "\(coins ?? 0)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .bold)
|
||||||
|
label.textColor = .DFEFFF
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var iconImageView = UIImageView(image: UIImage(named: "coins_icon_03"))
|
||||||
|
|
||||||
|
private lazy var coinsLabel: UILabel = {
|
||||||
|
let label = FALabel()
|
||||||
|
label.font = .font(ofSize: 14, weight: .bold)
|
||||||
|
label.textColors = [UIColor.FFCE_63.cgColor, UIColor.FFE_1_AA.cgColor]
|
||||||
|
label.textStartPoint = .init(x: 0, y: 0.5)
|
||||||
|
label.textEndPoint = .init(x: 1, y: 0.5)
|
||||||
|
label.text = "0"
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
addSubview(titleLabel)
|
||||||
|
addSubview(iconImageView)
|
||||||
|
addSubview(coinsLabel)
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
iconImageView.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
make.top.equalTo(titleLabel.snp.bottom).offset(8)
|
||||||
|
}
|
||||||
|
|
||||||
|
coinsLabel.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(iconImageView)
|
||||||
|
make.left.equalTo(iconImageView.snp.right).offset(4)
|
||||||
|
make.right.lessThanOrEqualToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
106
Fableon/Object/Class/Me/V/FACoinsPackClaimListView.swift
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
//
|
||||||
|
// FACoinsPackClaimListView.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FACoinsPackClaimListView: UIView {
|
||||||
|
|
||||||
|
var clickClaimButton: ((_ id: String?) -> Void)?
|
||||||
|
|
||||||
|
var dataArr: [FACoinsPackReceiveModel] = [] {
|
||||||
|
didSet {
|
||||||
|
collectionView.reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var titleView: FACoinPackTitleView = {
|
||||||
|
let view = FACoinPackTitleView()
|
||||||
|
view.dotColor = .C_5_DDF_5
|
||||||
|
view.textColors = [UIColor.C_5_DDF_5.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
view.font = .font(ofSize: 14, weight: .regular)
|
||||||
|
view.text = "Active Refills".localized.uppercased()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
||||||
|
let layout = UICollectionViewFlowLayout()
|
||||||
|
layout.itemSize = .init(width: UIScreen.width - 32, height: 122)
|
||||||
|
layout.minimumLineSpacing = 12
|
||||||
|
return layout
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var collectionView: FACollectionView = {
|
||||||
|
let collectionView = FACollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||||
|
collectionView.delegate = self
|
||||||
|
collectionView.dataSource = self
|
||||||
|
collectionView.addObserver(self, forKeyPath: "contentSize", context: nil)
|
||||||
|
collectionView.register(FACoinsPackClaimListCell.self, forCellWithReuseIdentifier: "cell")
|
||||||
|
return collectionView
|
||||||
|
}()
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
collectionView.removeObserver(self, forKeyPath: "contentSize")
|
||||||
|
}
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||||
|
if keyPath == "contentSize" {
|
||||||
|
let height = self.collectionView.contentSize.height + 1
|
||||||
|
collectionView.snp.updateConstraints { make in
|
||||||
|
make.height.equalTo(height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinsPackClaimListView {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
addSubview(titleView)
|
||||||
|
addSubview(collectionView)
|
||||||
|
|
||||||
|
titleView.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionView.snp.makeConstraints { make in
|
||||||
|
make.left.right.bottom.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(30)
|
||||||
|
make.height.equalTo(1)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: UICollectionViewDelegate UICollectionViewDataSource
|
||||||
|
extension FACoinsPackClaimListView: UICollectionViewDelegate, UICollectionViewDataSource {
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! FACoinsPackClaimListCell
|
||||||
|
cell.model = self.dataArr[indexPath.row]
|
||||||
|
cell.clickClaimButton = { [weak self] id in
|
||||||
|
self?.clickClaimButton?(id)
|
||||||
|
}
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return dataArr.count
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
121
Fableon/Object/Class/Me/V/FALoginView.swift
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
//
|
||||||
|
// FALoginView.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FALoginView: FAPanModalContentView {
|
||||||
|
|
||||||
|
|
||||||
|
private lazy var bgView = UIImageView(image: UIImage(named: "弹窗背景色"))
|
||||||
|
private lazy var bgIconImageView = UIImageView(image: UIImage(named: "Ellipse 873"))
|
||||||
|
private lazy var logoImageView = UIImageView(image: UIImage(named: "logo_image_02"))
|
||||||
|
|
||||||
|
private lazy var stackView: UIStackView = {
|
||||||
|
let view = UIStackView(arrangedSubviews: [appleButton, facebookButton])
|
||||||
|
view.axis = .vertical
|
||||||
|
view.spacing = 18
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var appleButton: UIButton = {
|
||||||
|
let button = self.createButton(image: UIImage(named: "apple_logo_icon_01"), title: "Login with Apple".localized)
|
||||||
|
button.addAction(UIAction(handler: { [weak self] _ in
|
||||||
|
self?.login(type: .apple)
|
||||||
|
}), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var facebookButton: UIButton = {
|
||||||
|
let button = self.createButton(image: UIImage(named: "facebook_logo_icon_01"), title: "Login with Facebook".localized)
|
||||||
|
button.addAction(UIAction(handler: { [weak self] _ in
|
||||||
|
self?.login(type: .faceBook)
|
||||||
|
}), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
backgroundColor = .clear
|
||||||
|
contentHeight = 300
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func cornerRadius() -> CGFloat {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private func createButton(image: UIImage?, title: String) -> UIButton {
|
||||||
|
var config = UIButton.Configuration.plain()
|
||||||
|
config.image = image
|
||||||
|
config.imagePadding = 12
|
||||||
|
config.attributedTitle = AttributedString(title, attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||||
|
.foregroundColor : UIColor._333333
|
||||||
|
]))
|
||||||
|
config.background.backgroundColor = .FFFFFF
|
||||||
|
|
||||||
|
let button = UIButton(configuration: config)
|
||||||
|
button.layer.cornerRadius = 24
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
|
||||||
|
button.snp.makeConstraints { make in
|
||||||
|
make.height.equalTo(48)
|
||||||
|
}
|
||||||
|
|
||||||
|
return button
|
||||||
|
}
|
||||||
|
|
||||||
|
private func login(type: FALogin.LoginType) {
|
||||||
|
FAHUD.show()
|
||||||
|
FALogin.manager.thirdLogin(type: type, presentingViewController: nil) { [weak self] isFinish in
|
||||||
|
FAHUD.dismiss()
|
||||||
|
guard let self = self else { return }
|
||||||
|
if isFinish {
|
||||||
|
Task {
|
||||||
|
await self.dismiss(animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FALoginView {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
addSubview(bgView)
|
||||||
|
bgView.addSubview(bgIconImageView)
|
||||||
|
bgView.addSubview(logoImageView)
|
||||||
|
addSubview(stackView)
|
||||||
|
|
||||||
|
bgView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView.snp.makeConstraints { make in
|
||||||
|
make.top.centerX.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
logoImageView.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(20)
|
||||||
|
}
|
||||||
|
|
||||||
|
stackView.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview().offset(112)
|
||||||
|
make.left.equalToSuperview().offset(37)
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
95
Fableon/Object/Class/Me/V/FAMeCoinsPackButton.swift
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// FAMeCoinsPackButton.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FAMeCoinsPackButton: UIControl {
|
||||||
|
|
||||||
|
private lazy var bgView: FAGradientView = {
|
||||||
|
let view = FAGradientView()
|
||||||
|
view.isUserInteractionEnabled = false
|
||||||
|
view.fa_colors = [UIColor._114_CEE.cgColor, UIColor._000000.cgColor]
|
||||||
|
view.fa_locations = [0, 1]
|
||||||
|
view.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
view.fa_endPoint = .init(x: 1, y: 0.5)
|
||||||
|
view.layer.cornerRadius = 12
|
||||||
|
view.layer.masksToBounds = true
|
||||||
|
view.layer.borderWidth = 1
|
||||||
|
view.layer.borderColor = UIColor._629_DFA.cgColor
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var iconImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "礼物11"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var titleLabel: FALabel = {
|
||||||
|
let label = FALabel()
|
||||||
|
label.font = .font(ofSize: 14, weight: .init(900)).withBoldItalic()
|
||||||
|
label.textColors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
label.textStartPoint = .init(x: 0, y: 0.5)
|
||||||
|
label.textEndPoint = .init(x: 0.7, y: 0.5)
|
||||||
|
label.text = "Daily reward ready!".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var subtitleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .medium).withBoldItalic()
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.text = "Claim your rewards now.".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var indicatorImageView = UIImageView(image: UIImage(named: "arrow"))
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FAMeCoinsPackButton {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
addSubview(bgView)
|
||||||
|
bgView.addSubview(iconImageView)
|
||||||
|
bgView.addSubview(titleLabel)
|
||||||
|
bgView.addSubview(subtitleLabel)
|
||||||
|
bgView.addSubview(indicatorImageView)
|
||||||
|
|
||||||
|
bgView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
iconImageView.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.left.equalToSuperview().offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview().offset(13)
|
||||||
|
make.left.equalTo(iconImageView.snp.right).offset(8)
|
||||||
|
}
|
||||||
|
|
||||||
|
subtitleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(titleLabel)
|
||||||
|
make.bottom.equalToSuperview().offset(-13)
|
||||||
|
}
|
||||||
|
|
||||||
|
indicatorImageView.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.right.equalToSuperview().offset(-12)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -9,7 +9,7 @@ import UIKit
|
|||||||
|
|
||||||
class FAMeHeaderView: UIView {
|
class FAMeHeaderView: UIView {
|
||||||
|
|
||||||
var contentHeight: CGFloat = 40 + 66 + 40 + 28 + 24
|
var contentHeight: CGFloat = 40 + 66 + 40 + 28 + 16 + 60 + 16
|
||||||
|
|
||||||
var userInfo: FAUserInfo? {
|
var userInfo: FAUserInfo? {
|
||||||
didSet {
|
didSet {
|
||||||
@ -22,6 +22,8 @@ class FAMeHeaderView: UIView {
|
|||||||
coinsView.count = userInfo?.coin_left_total ?? 0
|
coinsView.count = userInfo?.coin_left_total ?? 0
|
||||||
|
|
||||||
bonusCoinsView.count = userInfo?.send_coin_left_total ?? 0
|
bonusCoinsView.count = userInfo?.send_coin_left_total ?? 0
|
||||||
|
|
||||||
|
loginButton.isHidden = FALogin.manager.isLogin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +71,32 @@ class FAMeHeaderView: UIView {
|
|||||||
return view
|
return view
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private lazy var coinPackButton: FAMeCoinsPackButton = {
|
||||||
|
let button = FAMeCoinsPackButton()
|
||||||
|
button.addAction(UIAction(handler: { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
let vc = FACoinPackViewController()
|
||||||
|
self.viewController?.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var loginButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
let view = FALoginView()
|
||||||
|
view.present(in: nil)
|
||||||
|
}))
|
||||||
|
button.layer.cornerRadius = 14
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.layer.borderWidth = 1
|
||||||
|
button.layer.borderColor = UIColor.FFFEE_9.cgColor
|
||||||
|
button.setTitle("Log in".localized, for: .normal)
|
||||||
|
button.setTitleColor(.FFFFFF, for: .normal)
|
||||||
|
button.titleLabel?.font = .font(ofSize: 14, weight: .medium)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
@ -88,6 +116,8 @@ extension FAMeHeaderView {
|
|||||||
addSubview(idLabel)
|
addSubview(idLabel)
|
||||||
addSubview(coinsView)
|
addSubview(coinsView)
|
||||||
addSubview(bonusCoinsView)
|
addSubview(bonusCoinsView)
|
||||||
|
addSubview(coinPackButton)
|
||||||
|
addSubview(loginButton)
|
||||||
|
|
||||||
avatarImageView.snp.makeConstraints { make in
|
avatarImageView.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(16)
|
make.left.equalToSuperview().offset(16)
|
||||||
@ -115,6 +145,20 @@ extension FAMeHeaderView {
|
|||||||
make.top.equalTo(coinsView)
|
make.top.equalTo(coinsView)
|
||||||
make.left.equalTo(coinsView.snp.right).offset(40)
|
make.left.equalTo(coinsView.snp.right).offset(40)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coinPackButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(coinsView.snp.bottom).offset(16)
|
||||||
|
make.height.equalTo(60)
|
||||||
|
}
|
||||||
|
|
||||||
|
loginButton.snp.makeConstraints { make in
|
||||||
|
make.right.equalToSuperview().offset(-16)
|
||||||
|
make.centerY.equalTo(avatarImageView)
|
||||||
|
make.width.equalTo(76)
|
||||||
|
make.height.equalTo(28)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
26
Fableon/Object/Class/Me/V/FASettingCell.swift
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// FASettingCell.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FASettingCell: FATableViewCell {
|
||||||
|
|
||||||
|
|
||||||
|
@IBOutlet weak var titleLabel: UILabel!
|
||||||
|
|
||||||
|
override func awakeFromNib() {
|
||||||
|
super.awakeFromNib()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||||
|
super.setSelected(selected, animated: animated)
|
||||||
|
|
||||||
|
// Configure the view for the selected state
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
72
Fableon/Object/Class/Me/V/FASettingCell.xib
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="24128" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||||
|
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24063"/>
|
||||||
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||||
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="91" id="KGk-i7-Jjw" customClass="FASettingCell" customModule="Fableon" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="362" height="91"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="362" height="91"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eS3-W5-VR6">
|
||||||
|
<rect key="frame" x="16" y="0.0" width="330" height="91"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A4A-hn-CZz">
|
||||||
|
<rect key="frame" x="16" y="37" width="36" height="17"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
|
||||||
|
<color key="textColor" name="#FFFFFF"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" image="Frame 3015" translatesAutoresizingMaskIntoConstraints="NO" id="f2b-1S-BSh">
|
||||||
|
<rect key="frame" x="304" y="40.666666666666664" width="10" height="10"/>
|
||||||
|
</imageView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" name="#5CA8FF_0.2"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="A4A-hn-CZz" firstAttribute="leading" secondItem="eS3-W5-VR6" secondAttribute="leading" constant="16" id="OqO-BA-gyr"/>
|
||||||
|
<constraint firstItem="A4A-hn-CZz" firstAttribute="centerY" secondItem="eS3-W5-VR6" secondAttribute="centerY" id="WQz-Lc-m7d"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="f2b-1S-BSh" secondAttribute="trailing" constant="16" id="ppx-bH-uVc"/>
|
||||||
|
<constraint firstItem="f2b-1S-BSh" firstAttribute="centerY" secondItem="eS3-W5-VR6" secondAttribute="centerY" id="sJc-Wi-mjw"/>
|
||||||
|
</constraints>
|
||||||
|
<userDefinedRuntimeAttributes>
|
||||||
|
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
|
||||||
|
<integer key="value" value="12"/>
|
||||||
|
</userDefinedRuntimeAttribute>
|
||||||
|
<userDefinedRuntimeAttribute type="boolean" keyPath="masksToBounds" value="YES"/>
|
||||||
|
</userDefinedRuntimeAttributes>
|
||||||
|
</view>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="eS3-W5-VR6" secondAttribute="bottom" id="7pH-iM-ihT"/>
|
||||||
|
<constraint firstItem="eS3-W5-VR6" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="MKW-Dz-3xN"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="eS3-W5-VR6" secondAttribute="trailing" constant="16" id="bZG-Qv-nXN"/>
|
||||||
|
<constraint firstItem="eS3-W5-VR6" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="fSl-zo-SIR"/>
|
||||||
|
</constraints>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="titleLabel" destination="A4A-hn-CZz" id="yn4-Ke-t3P"/>
|
||||||
|
</connections>
|
||||||
|
<point key="canvasLocation" x="117.55725190839694" y="119.36619718309859"/>
|
||||||
|
</tableViewCell>
|
||||||
|
</objects>
|
||||||
|
<resources>
|
||||||
|
<image name="Frame 3015" width="10" height="10"/>
|
||||||
|
<namedColor name="#5CA8FF_0.2">
|
||||||
|
<color red="0.36078431372549019" green="0.6588235294117647" blue="1" alpha="0.20000000298023224" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</namedColor>
|
||||||
|
<namedColor name="#FFFFFF">
|
||||||
|
<color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</namedColor>
|
||||||
|
</resources>
|
||||||
|
</document>
|
||||||
48
Fableon/Object/Class/Me/V/FASettingFooterView.swift
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// FASettingFooterView.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FASettingFooterView: UIView {
|
||||||
|
|
||||||
|
|
||||||
|
private lazy var logoutButton: UIButton = {
|
||||||
|
let button = FAGradientButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
FALogin.manager.logout(completer: nil)
|
||||||
|
}))
|
||||||
|
button.layer.cornerRadius = 24
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.fa_colors = [UIColor.BEDFFF.cgColor, UIColor._52_A_2_F_1.cgColor]
|
||||||
|
button.fa_locations = [0, 1]
|
||||||
|
button.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
button.fa_endPoint = .init(x: 1, y: 0.5)
|
||||||
|
button.setTitle("Log out".localized, for: .normal)
|
||||||
|
button.setTitleColor(._000000, for: .normal)
|
||||||
|
button.titleLabel?.font = .font(ofSize: 18, weight: .semibold)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
addSubview(logoutButton)
|
||||||
|
|
||||||
|
logoutButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
make.height.equalTo(48)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,6 +122,22 @@ class FACollectViewController: FAViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func removeCollect(_ indexPath: IndexPath) {
|
||||||
|
|
||||||
|
let alert = FARemoveCollectAlert()
|
||||||
|
alert.show()
|
||||||
|
alert.clickHighlightButton = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
let model = self.dataArr[indexPath.row]
|
||||||
|
guard let shortPlayId = model.short_play_id else { return }
|
||||||
|
FAAPI.requestShortCollect(isCollect: false, shortPlayId: shortPlayId, videoId: model.short_play_video_id) { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.dataArr.remove(at: indexPath.row)
|
||||||
|
self.collectionView.deleteItems(at: [indexPath])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FACollectViewController {
|
extension FACollectViewController {
|
||||||
@ -147,13 +163,10 @@ extension FACollectViewController: UICollectionViewDataSource, UICollectionViewD
|
|||||||
cell.clickDeleteButton = { [weak self] cell in
|
cell.clickDeleteButton = { [weak self] cell in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
guard let indexPath = self.collectionView.indexPath(for: cell) else { return }
|
guard let indexPath = self.collectionView.indexPath(for: cell) else { return }
|
||||||
guard let shortPlayId = cell.model?.short_play_id else { return }
|
|
||||||
|
|
||||||
FAAPI.requestShortCollect(isCollect: false, shortPlayId: shortPlayId, videoId: cell.model?.short_play_video_id) { [weak self] in
|
self.removeCollect(indexPath)
|
||||||
guard let self = self else { return }
|
|
||||||
self.dataArr.remove(at: indexPath.row)
|
|
||||||
self.collectionView.deleteItems(at: [indexPath])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|||||||
@ -173,12 +173,24 @@ extension FAEpSelectorView: UICollectionViewDelegate, UICollectionViewDataSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
model?.episodeList?.count ?? 0
|
return model?.episodeList?.count ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
guard let epList = self.model?.episodeList else { return }
|
||||||
if self.selectedIndex == indexPath.row { return }
|
if self.selectedIndex == indexPath.row { return }
|
||||||
self.selectedIndex = indexPath.row
|
|
||||||
|
let lastIndex = indexPath.row - 1
|
||||||
|
var lastIsLock = false
|
||||||
|
if lastIndex > 0 && lastIndex < epList.count {
|
||||||
|
let lastModel = epList[lastIndex]
|
||||||
|
lastIsLock = lastModel.is_lock ?? false
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastIsLock {
|
||||||
|
FAToast.show(text: "buy_fail_toast_02".localized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
self.didSelected?(indexPath.row)
|
self.didSelected?(indexPath.row)
|
||||||
self.dismiss(animated: true) {
|
self.dismiss(animated: true) {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import HWPanModal
|
|||||||
class FAOldVideoRechargeView: FAPanModalContentView {
|
class FAOldVideoRechargeView: FAPanModalContentView {
|
||||||
|
|
||||||
var buyFinishHandle: (() -> Void)?
|
var buyFinishHandle: (() -> Void)?
|
||||||
|
var didDismissHandle: (() -> Void)?
|
||||||
|
|
||||||
var model: FAPayDateModel? {
|
var model: FAPayDateModel? {
|
||||||
didSet {
|
didSet {
|
||||||
@ -35,7 +36,7 @@ class FAOldVideoRechargeView: FAPanModalContentView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// self.stackView.addArrangedSubview(self.tipView)
|
self.stackView.addArrangedSubview(self.tipView)
|
||||||
|
|
||||||
self.setNeedsLayoutUpdate()
|
self.setNeedsLayoutUpdate()
|
||||||
}
|
}
|
||||||
@ -62,6 +63,7 @@ class FAOldVideoRechargeView: FAPanModalContentView {
|
|||||||
Task {
|
Task {
|
||||||
await self.dismiss(animated: true)
|
await self.dismiss(animated: true)
|
||||||
}
|
}
|
||||||
|
self.didDismissHandle?()
|
||||||
}))
|
}))
|
||||||
button.setImage(UIImage(named: "close_icon_02"), for: .normal)
|
button.setImage(UIImage(named: "close_icon_02"), for: .normal)
|
||||||
return button
|
return button
|
||||||
@ -123,6 +125,42 @@ class FAOldVideoRechargeView: FAPanModalContentView {
|
|||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private lazy var tipView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.addSubview(tipTitleLabel)
|
||||||
|
view.addSubview(tipTextLabel)
|
||||||
|
|
||||||
|
tipTitleLabel.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview().offset(7)
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
tipTextLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-16)
|
||||||
|
make.top.equalTo(tipTitleLabel.snp.bottom).offset(4)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var tipTitleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .medium)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.text = "store_tips_title".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var tipTextLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 10, weight: .regular)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.text = "store_tips".localized
|
||||||
|
label.numberOfLines = 0
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
NotificationCenter.default.removeObserver(self)
|
NotificationCenter.default.removeObserver(self)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,6 +171,10 @@ extension FAShortDetailViewModel {
|
|||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.requestDetailData(indexPath: self.currentIndexPath, completer: nil)
|
self.requestDetailData(indexPath: self.currentIndexPath, completer: nil)
|
||||||
}
|
}
|
||||||
|
view.didDismissHandle = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self._showVipRetainAlert(videoInfo)
|
||||||
|
}
|
||||||
view.present(in: nil)
|
view.present(in: nil)
|
||||||
self.popView = view
|
self.popView = view
|
||||||
}
|
}
|
||||||
@ -182,6 +186,25 @@ extension FAShortDetailViewModel {
|
|||||||
view.present(in: nil)
|
view.present(in: nil)
|
||||||
self.popView = view
|
self.popView = view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func _showVipRetainAlert(_ videoInfo: FAVideoInfoModel) {
|
||||||
|
|
||||||
|
|
||||||
|
payDataRequest = FAPayDataRequest()
|
||||||
|
|
||||||
|
payDataRequest?.requestVipRetainPayInfo { [weak self] model in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let model = model else { return }
|
||||||
|
let view = FAVipRetainAlert()
|
||||||
|
view.model = model
|
||||||
|
view.videoInfo = videoInfo
|
||||||
|
view.buyFinishHandle = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.requestDetailData(indexPath: self.currentIndexPath, completer: nil)
|
||||||
|
}
|
||||||
|
view.show(in: FATool.keyWindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FAShortDetailViewModel {
|
extension FAShortDetailViewModel {
|
||||||
|
|||||||
13
Fableon/Object/Class/Store/M/FACoinPackCanReceiveModel.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// FACoinPackCanReceiveModel.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
|
struct FACoinPackCanReceiveModel: SmartCodable {
|
||||||
|
var coins: Int?
|
||||||
|
}
|
||||||
25
Fableon/Object/Class/Store/M/FACoinsPackModel.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// FACoinsPackModel.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
|
struct FACoinsPackModel: SmartCodable {
|
||||||
|
|
||||||
|
//当前可领取订阅数
|
||||||
|
var receive_count: Int?
|
||||||
|
//已领取累计金币总数
|
||||||
|
var week_total: Int?
|
||||||
|
//剩余可领取金币数
|
||||||
|
var week_remaining_total: Int?
|
||||||
|
//订阅可领取累计金币总数
|
||||||
|
var week_max_total: Int?
|
||||||
|
//当前可领取金币总数
|
||||||
|
var receive_coins: Int?
|
||||||
|
|
||||||
|
var receive_list: [FACoinsPackReceiveModel]?
|
||||||
|
}
|
||||||
25
Fableon/Object/Class/Store/M/FACoinsPackReceiveModel.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// FACoinsPackReceiveModel.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
|
struct FACoinsPackReceiveModel: SmartCodable {
|
||||||
|
|
||||||
|
var id: String?
|
||||||
|
var title: String?
|
||||||
|
//剩余可领取金币数
|
||||||
|
var week_remaining_total: Int?
|
||||||
|
//当前可领取金币数
|
||||||
|
var receive_coins: Int?
|
||||||
|
//已领取累计金币总数
|
||||||
|
var week_total: Int?
|
||||||
|
//可领取累计金币总数
|
||||||
|
var week_max_total: Int?
|
||||||
|
//领取天数文本
|
||||||
|
var day_text: String?
|
||||||
|
}
|
||||||
@ -10,14 +10,15 @@ import UIKit
|
|||||||
class FAAdjustStateManager {
|
class FAAdjustStateManager {
|
||||||
static let manager = FAAdjustStateManager()
|
static let manager = FAAdjustStateManager()
|
||||||
|
|
||||||
|
var allowOpenMessage = true
|
||||||
|
|
||||||
var webpageURL: URL?
|
var webpageURL: URL?
|
||||||
///是否需要重试
|
///是否需要重试
|
||||||
var isNeedRetry = false
|
var isNeedRetry = false
|
||||||
|
|
||||||
var allowOpenMessage = true
|
|
||||||
|
|
||||||
var isOpenApp = false
|
var isOpenApp = false
|
||||||
|
|
||||||
var idfaAuthorizationFinish = false
|
var idfaAuthorizationFinish = false
|
||||||
|
|
||||||
|
var apnsAuthorizationFinish = false
|
||||||
}
|
}
|
||||||
|
|||||||
104
Fableon/Object/Libs/Alert/FAApnsAlert.swift
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
//
|
||||||
|
// FAApnsAlert.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FAApnsAlert: FABaseAlert {
|
||||||
|
|
||||||
|
private lazy var imageView = UIImageView(image: UIImage(named: "__magnifying"))
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.numberOfLines = 0
|
||||||
|
label.font = .font(ofSize: 18, weight: .semibold)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.text = "apns_alert_title".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var textLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.numberOfLines = 0
|
||||||
|
label.font = .font(ofSize: 12, weight: .regular)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.text = "apns_alert_text".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var laterButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.layer.cornerRadius = 18
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.layer.borderWidth = 1
|
||||||
|
button.layer.borderColor = UIColor.FFFFFF.cgColor
|
||||||
|
button.setTitle("Later".localized, for: .normal)
|
||||||
|
button.setTitleColor(.FFFFFF, for: .normal)
|
||||||
|
button.titleLabel?.font = .font(ofSize: 14, weight: .semibold)
|
||||||
|
button.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
highlightButton.setTitle("Open".localized, for: .normal)
|
||||||
|
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
override func handleHighlightButton() {
|
||||||
|
super.handleHighlightButton()
|
||||||
|
FATool.openApnsSetting()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FAApnsAlert {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
containerView.addSubview(imageView)
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
contentView.addSubview(textLabel)
|
||||||
|
contentView.addSubview(laterButton)
|
||||||
|
contentView.addSubview(highlightButton)
|
||||||
|
|
||||||
|
imageView.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(-62)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-10)
|
||||||
|
make.top.equalTo(imageView.snp.bottom).offset(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
textLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-20)
|
||||||
|
make.top.equalTo(titleLabel.snp.bottom).offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
laterButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(23)
|
||||||
|
make.top.equalTo(textLabel.snp.bottom).offset(21)
|
||||||
|
make.bottom.equalToSuperview().offset(-20)
|
||||||
|
make.height.equalTo(36)
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightButton.snp.makeConstraints { make in
|
||||||
|
make.width.height.top.equalTo(laterButton)
|
||||||
|
make.left.equalTo(laterButton.snp.right).offset(11)
|
||||||
|
make.right.equalToSuperview().offset(-23)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
169
Fableon/Object/Libs/Alert/FABaseAlert.swift
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
//
|
||||||
|
// FABaseAlert.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SnapKit
|
||||||
|
|
||||||
|
class FABaseAlert: UIView {
|
||||||
|
|
||||||
|
var clickHighlightButton: (() -> Void)?
|
||||||
|
|
||||||
|
var contentWidth: CGFloat = UIScreen.width - 70 {
|
||||||
|
didSet {
|
||||||
|
containerView.snp.updateConstraints { make in
|
||||||
|
make.width.equalTo(contentWidth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private(set) var containerView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private(set) var contentView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.backgroundColor = ._404040
|
||||||
|
view.layer.cornerRadius = 16
|
||||||
|
view.layer.masksToBounds = true
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private(set) lazy var closeButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.setImage(UIImage(named: "close_icon_03"), for: .normal)
|
||||||
|
button.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
lazy var highlightButton: FAGradientButton = {
|
||||||
|
let button = FAGradientButton(type: .custom)
|
||||||
|
button.fa_colors = [UIColor.BEDFFF.cgColor, UIColor._52_A_2_F_1.cgColor]
|
||||||
|
button.fa_locations = [0, 1]
|
||||||
|
button.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
button.fa_endPoint = .init(x: 1, y: 0.5)
|
||||||
|
button.layer.cornerRadius = 16
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.setTitleColor(._000000, for: .normal)
|
||||||
|
button.titleLabel?.font = .font(ofSize: 14, weight: .semibold)
|
||||||
|
button.addTarget(self, action: #selector(handleHighlightButton), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
backgroundColor = ._000000.withAlphaComponent(0.5)
|
||||||
|
|
||||||
|
addSubview(containerView)
|
||||||
|
containerView.addSubview(contentView)
|
||||||
|
containerView.addSubview(closeButton)
|
||||||
|
|
||||||
|
containerView.snp.makeConstraints { make in
|
||||||
|
make.center.equalToSuperview()
|
||||||
|
make.width.equalTo(contentWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentView.snp.makeConstraints { make in
|
||||||
|
make.left.right.top.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview().offset(-66)
|
||||||
|
}
|
||||||
|
|
||||||
|
closeButton.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
@objc func show(in view: UIView? = nil) -> Self {
|
||||||
|
guard self.superview == nil else { return self }
|
||||||
|
|
||||||
|
var inView: UIView
|
||||||
|
if let view = view {
|
||||||
|
inView = view
|
||||||
|
} else {
|
||||||
|
inView = FABaseAlert.Window.manager.createWindow()
|
||||||
|
}
|
||||||
|
|
||||||
|
inView.addSubview(self)
|
||||||
|
self.frame = inView.bounds
|
||||||
|
showAnimation()
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
@objc func dismiss() {
|
||||||
|
dismissAnimation()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func handleHighlightButton() {
|
||||||
|
self.dismissAnimation()
|
||||||
|
self.clickHighlightButton?()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FABaseAlert {
|
||||||
|
private func showAnimation() {
|
||||||
|
containerView.transform = CGAffineTransform(translationX: 0, y: 200)
|
||||||
|
|
||||||
|
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0) {
|
||||||
|
self.containerView.transform = CGAffineTransform.identity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func dismissAnimation() {
|
||||||
|
|
||||||
|
UIView.animate(withDuration: 0.3) {
|
||||||
|
self.alpha = 0
|
||||||
|
self.containerView.transform = CGAffineTransform(translationX: 0, y: 500)
|
||||||
|
} completion: { _ in
|
||||||
|
self.removeFromSuperview()
|
||||||
|
FABaseAlert.Window.manager.dismissWindow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FABaseAlert {
|
||||||
|
class Window {
|
||||||
|
static let manager = Window()
|
||||||
|
|
||||||
|
private(set) var window: UIWindow?
|
||||||
|
|
||||||
|
func createWindow() -> UIWindow {
|
||||||
|
guard let window = window else {
|
||||||
|
let window = UIWindow(windowScene: FATool.windowScene!)
|
||||||
|
window.backgroundColor = .clear
|
||||||
|
window.windowLevel = .alert
|
||||||
|
window.isHidden = false
|
||||||
|
self.window = window
|
||||||
|
return window
|
||||||
|
}
|
||||||
|
return window
|
||||||
|
}
|
||||||
|
|
||||||
|
func dismissWindow() {
|
||||||
|
guard let window = self.window else { return }
|
||||||
|
|
||||||
|
var isHidden = true
|
||||||
|
|
||||||
|
window.subviews.forEach {
|
||||||
|
if $0.isKind(of: FABaseAlert.self) {
|
||||||
|
isHidden = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isHidden {
|
||||||
|
window.isHidden = true
|
||||||
|
self.window = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
117
Fableon/Object/Libs/Alert/FACoinsPackAlert.swift
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
//
|
||||||
|
// FACoinsPackAlert.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FACoinsPackAlert: FABaseAlert {
|
||||||
|
|
||||||
|
var coinsCount: Int? {
|
||||||
|
didSet {
|
||||||
|
coinsView.setNeedsUpdateConfiguration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var imageView = UIImageView(image: UIImage(named: "签到"))
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 18, weight: .bold)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.numberOfLines = 0
|
||||||
|
label.text = "coins_pack_alert_title".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var coinsView: UIButton = {
|
||||||
|
var config = UIButton.Configuration.plain()
|
||||||
|
config.image = UIImage(named: "coins_icon_10")
|
||||||
|
config.imagePadding = 8
|
||||||
|
config.contentInsets = .zero
|
||||||
|
let button = UIButton(configuration: config)
|
||||||
|
button.isUserInteractionEnabled = false
|
||||||
|
button.configurationUpdateHandler = { [weak self] button in
|
||||||
|
guard let self = self else { return }
|
||||||
|
button.configuration?.attributedTitle = AttributedString("+\(self.coinsCount ?? 0)", attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 24, weight: .init(700)),
|
||||||
|
.foregroundColor : UIColor.F_6_CF_87
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var laterButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.layer.cornerRadius = 24
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.layer.borderColor = UIColor._777777.cgColor
|
||||||
|
button.layer.borderWidth = 1
|
||||||
|
button.setTitle("Later".localized, for: .normal)
|
||||||
|
button.setTitleColor(._777777, for: .normal)
|
||||||
|
button.titleLabel?.font = .font(ofSize: 14, weight: .bold)
|
||||||
|
button.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
self.highlightButton.setTitle("Claim Now".localized, for: .normal)
|
||||||
|
self.highlightButton.setTitleColor(.FFFFFF, for: .normal)
|
||||||
|
self.highlightButton.fa_colors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
self.highlightButton.layer.cornerRadius = 24
|
||||||
|
self.highlightButton.titleLabel?.font = .font(ofSize: 14, weight: .bold)
|
||||||
|
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FACoinsPackAlert {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
contentView.addSubview(imageView)
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
contentView.addSubview(coinsView)
|
||||||
|
contentView.addSubview(highlightButton)
|
||||||
|
contentView.addSubview(laterButton)
|
||||||
|
|
||||||
|
imageView.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(24)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-10)
|
||||||
|
make.top.equalTo(imageView.snp.bottom).offset(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
coinsView.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(titleLabel.snp.bottom).offset(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(18)
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(coinsView.snp.bottom).offset(16)
|
||||||
|
make.height.equalTo(48)
|
||||||
|
}
|
||||||
|
|
||||||
|
laterButton.snp.makeConstraints { make in
|
||||||
|
make.left.right.height.equalTo(highlightButton)
|
||||||
|
make.top.equalTo(highlightButton.snp.bottom).offset(12)
|
||||||
|
make.bottom.equalToSuperview().offset(-24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
93
Fableon/Object/Libs/Alert/FARemoveCollectAlert.swift
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
//
|
||||||
|
// FARemoveCollectAlert.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FARemoveCollectAlert: FABaseAlert {
|
||||||
|
|
||||||
|
|
||||||
|
private lazy var imageView = UIImageView(image: UIImage(named: "alert_image_01"))
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 18, weight: .semibold)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.text = "remove_collect_alert_title".localized
|
||||||
|
label.numberOfLines = 0
|
||||||
|
label.textAlignment = .center
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var textLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 12, weight: .regular)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
label.numberOfLines = 0
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.text = "remove_collect_alert_text".localized
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var cancelButton: UIButton = {
|
||||||
|
let button = UIButton(type: .custom)
|
||||||
|
button.layer.cornerRadius = 18
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.layer.borderWidth = 1
|
||||||
|
button.layer.borderColor = UIColor.FFFFFF.cgColor
|
||||||
|
button.setTitle("Cancel".localized, for: .normal)
|
||||||
|
button.setTitleColor(.FFFFFF, for: .normal)
|
||||||
|
button.titleLabel?.font = .font(ofSize: 14, weight: .medium)
|
||||||
|
button.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
highlightButton.setTitle("Remove".localized, for: .normal)
|
||||||
|
|
||||||
|
containerView.addSubview(imageView)
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
contentView.addSubview(textLabel)
|
||||||
|
contentView.addSubview(cancelButton)
|
||||||
|
contentView.addSubview(highlightButton)
|
||||||
|
|
||||||
|
imageView.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalToSuperview().offset(-62)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(imageView.snp.bottom).offset(10)
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-10)
|
||||||
|
}
|
||||||
|
|
||||||
|
textLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-20)
|
||||||
|
make.top.equalTo(titleLabel.snp.bottom).offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(24)
|
||||||
|
make.top.equalTo(textLabel.snp.bottom).offset(21)
|
||||||
|
make.bottom.equalTo(-20)
|
||||||
|
make.height.equalTo(36)
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(cancelButton.snp.right).offset(11)
|
||||||
|
make.right.equalToSuperview().offset(-24)
|
||||||
|
make.width.height.top.equalTo(cancelButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
307
Fableon/Object/Libs/Alert/FAVipRetainAlert.swift
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
//
|
||||||
|
// FAVipRetainAlert.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FAVipRetainAlert: FABaseAlert {
|
||||||
|
|
||||||
|
var buyFinishHandle: (() -> Void)?
|
||||||
|
|
||||||
|
var model: FAPayAlertModel? {
|
||||||
|
didSet {
|
||||||
|
let payItem = model?.info
|
||||||
|
titleView.text = payItem?.getVipTitle()
|
||||||
|
itemView.payItem = payItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var videoInfo: FAVideoInfoModel?
|
||||||
|
|
||||||
|
|
||||||
|
private lazy var titleView: FACoinPackTitleView = {
|
||||||
|
let view = FACoinPackTitleView()
|
||||||
|
view.dotColor = ._20_A_1_FF
|
||||||
|
view.textColors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
view.font = .font(ofSize: 24, weight: .init(900))
|
||||||
|
view.text = "Weekly Refill".localized.uppercased()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var itemView: ItemView = {
|
||||||
|
let view = ItemView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var textLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 18, weight: .bold).withBoldItalic()
|
||||||
|
label.textColor = .C_5_DDF_5
|
||||||
|
label.text = "vip_retain_alert_text".localized
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.numberOfLines = 0
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var buyButton: UIButton = {
|
||||||
|
let button = FAGradientButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let payItem = self.model?.info else { return }
|
||||||
|
FAIapManager.manager.start(model: payItem, shortPlayId: self.videoInfo?.short_play_id, videoId: self.videoInfo?.short_play_video_id) { [weak self] finish in
|
||||||
|
guard let self = self else { return }
|
||||||
|
if finish {
|
||||||
|
FALogin.manager.requestUserInfo(completer: nil)
|
||||||
|
self.dismiss()
|
||||||
|
self.buyFinishHandle?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}))
|
||||||
|
button.layer.cornerRadius = 24
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.fa_colors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
button.fa_locations = [0, 1]
|
||||||
|
button.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
button.fa_endPoint = .init(x: 0.7, y: 0.5)
|
||||||
|
button.setTitle("Buy Now".localized, for: .normal)
|
||||||
|
button.setTitleColor(.FFFFFF, for: .normal)
|
||||||
|
button.titleLabel?.font = .font(ofSize: 14, weight: .bold)
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
contentWidth = UIScreen.width - 55
|
||||||
|
contentView.backgroundColor = .clear
|
||||||
|
|
||||||
|
fa_setupLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FAVipRetainAlert {
|
||||||
|
|
||||||
|
private func fa_setupLayout() {
|
||||||
|
contentView.addSubview(titleView)
|
||||||
|
contentView.addSubview(itemView)
|
||||||
|
contentView.addSubview(textLabel)
|
||||||
|
contentView.addSubview(buyButton)
|
||||||
|
|
||||||
|
titleView.snp.makeConstraints { make in
|
||||||
|
make.top.equalToSuperview()
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
itemView.snp.makeConstraints { make in
|
||||||
|
make.left.right.equalToSuperview()
|
||||||
|
make.top.equalTo(titleView.snp.bottom).offset(12)
|
||||||
|
make.height.equalTo(84)
|
||||||
|
}
|
||||||
|
|
||||||
|
textLabel.snp.makeConstraints { make in
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-10)
|
||||||
|
make.top.equalTo(itemView.snp.bottom).offset(12)
|
||||||
|
}
|
||||||
|
|
||||||
|
buyButton.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(20)
|
||||||
|
make.centerX.equalToSuperview()
|
||||||
|
make.top.equalTo(textLabel.snp.bottom).offset(12)
|
||||||
|
make.height.equalTo(48)
|
||||||
|
make.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FAVipRetainAlert {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ItemView: UIView {
|
||||||
|
|
||||||
|
var payItem: FAPayItem? {
|
||||||
|
didSet {
|
||||||
|
nameLabel.text = payItem?.getVipTitle()
|
||||||
|
|
||||||
|
button.setNeedsUpdateConfiguration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var bgView: FAGradientView = {
|
||||||
|
let view = FAGradientView()
|
||||||
|
view.fa_colors = [UIColor._524_B_8_E.cgColor, UIColor._303265.cgColor]
|
||||||
|
view.fa_locations = [0, 1]
|
||||||
|
view.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
view.fa_endPoint = .init(x: 1, y: 0.5)
|
||||||
|
view.layer.cornerRadius = 12
|
||||||
|
view.layer.masksToBounds = true
|
||||||
|
view.layer.borderWidth = 1
|
||||||
|
view.layer.borderColor = UIColor.E_5_E_5_E_5.cgColor
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var bgIconImageView1: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "coin_attachment_01"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var bgIconImageView2: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "coin_attachment_02"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
private lazy var bgIconImageView3 = UIImageView(image: UIImage(named: "coin_attachment_04"))
|
||||||
|
private lazy var bgIconImageView4 = UIImageView(image: UIImage(named: "coin_attachment_05"))
|
||||||
|
|
||||||
|
private lazy var vipIconImageView = UIImageView(image: UIImage(named: "皇冠-金"))
|
||||||
|
|
||||||
|
private lazy var nameLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .font(ofSize: 18, weight: .bold)
|
||||||
|
label.textColor = .FFFFFF
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var textLabel: UILabel = {
|
||||||
|
let label = FALabel()
|
||||||
|
label.textColors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
label.textStartPoint = .init(x: 0, y: 0.5)
|
||||||
|
label.textEndPoint = .init(x: 0.7, y: 0.5)
|
||||||
|
label.font = .font(ofSize: 12, weight: .regular)
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var button: UIButton = {
|
||||||
|
var config = UIButton.Configuration.plain()
|
||||||
|
config.contentInsets = .init(top: 0, leading: 10, bottom: 0, trailing: 10)
|
||||||
|
config.titleAlignment = .center
|
||||||
|
|
||||||
|
let button = FAGradientButton(configuration: config)
|
||||||
|
button.isUserInteractionEnabled = false
|
||||||
|
button.fa_colors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor]
|
||||||
|
button.fa_locations = [0, 1]
|
||||||
|
button.fa_startPoint = .init(x: 0, y: 0.5)
|
||||||
|
button.fa_endPoint = .init(x: 0.5, y: 0.5)
|
||||||
|
button.layer.cornerRadius = 24
|
||||||
|
button.layer.masksToBounds = true
|
||||||
|
button.configurationUpdateHandler = { [weak self] button in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
let currency = self.payItem?.currency ?? ""
|
||||||
|
let timeString = self.payItem?.getTimeString() ?? ""
|
||||||
|
let oldPrice = self.payItem?.price ?? ""
|
||||||
|
var discountPrice: String? = nil
|
||||||
|
|
||||||
|
if self.payItem?.discount_type == 1, let introductoryPrice = self.payItem?.introductionaryOffer {
|
||||||
|
discountPrice = introductoryPrice.price.stringValue
|
||||||
|
} else if self.payItem?.discount_type == 2, let discount = self.payItem?.promotionalOffers?.first {
|
||||||
|
discountPrice = discount.price.stringValue
|
||||||
|
}
|
||||||
|
|
||||||
|
if let discountPrice = discountPrice {
|
||||||
|
button.configuration?.attributedTitle = AttributedString("\(currency)\(discountPrice)", attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 18, weight: .bold),
|
||||||
|
.foregroundColor : UIColor._114_CEE
|
||||||
|
]))
|
||||||
|
|
||||||
|
button.configuration?.attributedSubtitle = AttributedString("\(currency)\(oldPrice)", attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 12, weight: .regular),
|
||||||
|
.foregroundColor : UIColor._000000.withAlphaComponent(0.5),
|
||||||
|
.strikethroughStyle: NSUnderlineStyle.single.rawValue,
|
||||||
|
.strikethroughColor: UIColor._000000.withAlphaComponent(0.5)
|
||||||
|
]))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
button.configuration?.attributedTitle = AttributedString("\(currency)\(oldPrice)", attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 18, weight: .bold),
|
||||||
|
.foregroundColor : UIColor._114_CEE
|
||||||
|
]))
|
||||||
|
|
||||||
|
button.configuration?.attributedSubtitle = AttributedString("/\(timeString)", attributes: AttributeContainer([
|
||||||
|
.font : UIFont.font(ofSize: 12, weight: .regular),
|
||||||
|
.foregroundColor : UIColor._000000.withAlphaComponent(0.5)
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
nameLabel.text = "Weekly VIP"
|
||||||
|
textLabel.text = "Unlimited access to all series"
|
||||||
|
|
||||||
|
addSubview(bgView)
|
||||||
|
bgView.addSubview(bgIconImageView4)
|
||||||
|
bgView.addSubview(bgIconImageView3)
|
||||||
|
bgView.addSubview(bgIconImageView1)
|
||||||
|
bgView.addSubview(bgIconImageView2)
|
||||||
|
bgView.addSubview(vipIconImageView)
|
||||||
|
bgView.addSubview(nameLabel)
|
||||||
|
bgView.addSubview(textLabel)
|
||||||
|
bgView.addSubview(button)
|
||||||
|
|
||||||
|
bgView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView1.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(0)
|
||||||
|
make.top.equalToSuperview().offset(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView2.snp.makeConstraints { make in
|
||||||
|
make.right.equalToSuperview().offset(-26)
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView3.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.centerX.equalTo(bgIconImageView2)
|
||||||
|
}
|
||||||
|
|
||||||
|
bgIconImageView4.snp.makeConstraints { make in
|
||||||
|
make.left.bottom.equalToSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
vipIconImageView.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview().offset(16)
|
||||||
|
make.top.equalToSuperview().offset(18)
|
||||||
|
}
|
||||||
|
|
||||||
|
nameLabel.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalTo(vipIconImageView)
|
||||||
|
make.left.equalTo(vipIconImageView.snp.right).offset(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
textLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalTo(vipIconImageView)
|
||||||
|
make.bottom.equalToSuperview().offset(-18)
|
||||||
|
}
|
||||||
|
|
||||||
|
button.snp.makeConstraints { make in
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
make.right.equalToSuperview().offset(-12)
|
||||||
|
make.height.equalTo(48)
|
||||||
|
make.width.greaterThanOrEqualTo(88)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -83,25 +83,25 @@ class FAPayDataRequest: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///挽留信息
|
///挽留信息
|
||||||
func requestRetainVipPayInfo(completer: ((_ model: FAPayAlertModel?) -> Void)?) {
|
func requestVipRetainPayInfo(completer: ((_ model: FAPayAlertModel?) -> Void)?) {
|
||||||
self.completerBlock = nil
|
self.completerBlock = nil
|
||||||
self.payAlertBlock = completer
|
self.payAlertBlock = completer
|
||||||
|
|
||||||
// FAStoreAPI.requestRetainVipPayInfo { [weak self] model in
|
FAStoreAPI.requestVipRetainPayInfo { [weak self] model in
|
||||||
// guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
// guard let model = model else {
|
guard let model = model else {
|
||||||
// self.payAlertBlock?(nil)
|
self.payAlertBlock?(nil)
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
// self.payAlertModel = model
|
self.payAlertModel = model
|
||||||
//
|
|
||||||
// let productId = BRIAP.manager.getProductId(templateId: model.info?.ios_template_id) ?? ""
|
let productId = FAIapManager.manager.getProductId(templateId: model.info?.ios_template_id) ?? ""
|
||||||
//
|
|
||||||
// let set = Set([productId])
|
let set = Set([productId])
|
||||||
// let productsRequest = SKProductsRequest(productIdentifiers: set)
|
let productsRequest = SKProductsRequest(productIdentifiers: set)
|
||||||
// productsRequest.delegate = self
|
productsRequest.delegate = self
|
||||||
// productsRequest.start()
|
productsRequest.start()
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
115
Fableon/Object/Libs/FALogin/FALogin+Apple.swift
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// FALogin+Apple.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import AuthenticationServices
|
||||||
|
|
||||||
|
extension FALogin {
|
||||||
|
|
||||||
|
private struct AssociatedKeys {
|
||||||
|
static var appleLoginHandle: Int?
|
||||||
|
}
|
||||||
|
|
||||||
|
private var appleLoginHandle: ((_ model: FAThirdSignModel?) -> Void)? {
|
||||||
|
set {
|
||||||
|
objc_setAssociatedObject(self, &AssociatedKeys.appleLoginHandle, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
|
||||||
|
}
|
||||||
|
get {
|
||||||
|
return objc_getAssociatedObject(self, &AssociatedKeys.appleLoginHandle) as? ((_ model: FAThirdSignModel?) -> Void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appleLogin(completer: ((_ model: FAThirdSignModel?) -> Void)?) {
|
||||||
|
self.appleLoginHandle = completer
|
||||||
|
|
||||||
|
let appleIDProvider = ASAuthorizationAppleIDProvider()
|
||||||
|
let request = appleIDProvider.createRequest()
|
||||||
|
request.requestedScopes = [.fullName, .email]
|
||||||
|
|
||||||
|
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
|
||||||
|
authorizationController.delegate = self
|
||||||
|
authorizationController.presentationContextProvider = self
|
||||||
|
authorizationController.performRequests()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func jwtDecode(jwtStr: String) -> [String: Any]? {
|
||||||
|
let segments = jwtStr.components(separatedBy: ".")
|
||||||
|
guard segments.count > 1 else { return nil }
|
||||||
|
|
||||||
|
var base64String = segments[1]
|
||||||
|
|
||||||
|
// 处理 Base64 补齐
|
||||||
|
let requiredLength = 4 * Int(ceil(Double(base64String.count) / 4.0))
|
||||||
|
let paddingLength = requiredLength - base64String.count
|
||||||
|
if paddingLength > 0 {
|
||||||
|
base64String += String(repeating: "=", count: paddingLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 替换 URL 安全字符
|
||||||
|
base64String = base64String.replacingOccurrences(of: "-", with: "+")
|
||||||
|
base64String = base64String.replacingOccurrences(of: "_", with: "/")
|
||||||
|
|
||||||
|
// 解码 Base64 数据
|
||||||
|
guard let data = Data(base64Encoded: base64String),
|
||||||
|
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
|
||||||
|
let payload = jsonObject as? [String: Any] else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: ASAuthorizationControllerDelegate
|
||||||
|
extension FALogin: ASAuthorizationControllerDelegate {
|
||||||
|
|
||||||
|
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
||||||
|
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
|
||||||
|
|
||||||
|
let userIdentifier = appleIDCredential.user
|
||||||
|
let fullName = appleIDCredential.fullName
|
||||||
|
let email = appleIDCredential.email
|
||||||
|
|
||||||
|
let identityToken = appleIDCredential.identityToken.flatMap { String(data: $0, encoding: .utf8) }
|
||||||
|
let identityTokenParams = self.jwtDecode(jwtStr: identityToken ?? "")
|
||||||
|
|
||||||
|
|
||||||
|
var model = FAThirdSignModel()
|
||||||
|
model.platform = .apple
|
||||||
|
model.third_id = userIdentifier
|
||||||
|
model.giving_name = fullName?.givenName
|
||||||
|
model.family_name = fullName?.familyName
|
||||||
|
model.avator = identityTokenParams?["picture"] as? String
|
||||||
|
model.email = identityTokenParams?["email"] as? String
|
||||||
|
|
||||||
|
|
||||||
|
debugLog(userIdentifier)
|
||||||
|
debugLog(fullName)
|
||||||
|
debugLog(email)
|
||||||
|
|
||||||
|
appleLoginHandle?(model)
|
||||||
|
appleLoginHandle = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
|
||||||
|
appleLoginHandle?(nil)
|
||||||
|
appleLoginHandle = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: ASAuthorizationControllerPresentationContextProviding
|
||||||
|
extension FALogin: ASAuthorizationControllerPresentationContextProviding {
|
||||||
|
|
||||||
|
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
||||||
|
return FATool.keyWindow!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
58
Fableon/Object/Libs/FALogin/FALogin+Facebook.swift
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// FALogin+Facebook.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
import UIKit
|
||||||
|
import FacebookLogin
|
||||||
|
|
||||||
|
extension FALogin {
|
||||||
|
|
||||||
|
func facebookLogin(presentingViewController: UIViewController?, completer: ((_ model: FAThirdSignModel?) -> Void)?) {
|
||||||
|
|
||||||
|
let loginManager = LoginManager()
|
||||||
|
loginManager.logOut()
|
||||||
|
loginManager.defaultAudience = .everyone
|
||||||
|
|
||||||
|
loginManager.logIn(permissions: ["public_profile", "email"], from: presentingViewController) { result, error in
|
||||||
|
guard error == nil, let result = result else {
|
||||||
|
completer?(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if result.isCancelled {
|
||||||
|
completer?(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let request = GraphRequest(graphPath: "me", parameters: ["fields" : "id,name,email,picture"], httpMethod: .get)
|
||||||
|
request.start { connection, result, error in
|
||||||
|
guard let result = result as? [String : Any] else {
|
||||||
|
completer?(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var model = FAThirdSignModel()
|
||||||
|
model.platform = .faceBook
|
||||||
|
model.third_id = result["id"] as? String
|
||||||
|
model.email = result["email"] as? String
|
||||||
|
|
||||||
|
if let picture = result["picture"] as? [String : Any],
|
||||||
|
let data = picture["data"] as? [String : Any],
|
||||||
|
let url = data["url"] as? String
|
||||||
|
{
|
||||||
|
model.avator = url
|
||||||
|
}
|
||||||
|
|
||||||
|
if let name = result["name"] as? String {
|
||||||
|
model.family_name = name
|
||||||
|
} else {
|
||||||
|
model.family_name = result["first_name"] as? String
|
||||||
|
model.giving_name = result["last_name"] as? String
|
||||||
|
}
|
||||||
|
completer?(model)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -6,16 +6,28 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
let kFAUserTokenDefaultsKey = "kFAUserTokenDefaultsKey"
|
let kFAUserTokenDefaultsKey = "kFAUserTokenDefaultsKey"
|
||||||
let kFAUserInfoDefaultsKey = "kFAUserInfoDefaultsKey"
|
let kFAUserInfoDefaultsKey = "kFAUserInfoDefaultsKey"
|
||||||
|
|
||||||
class FALogin: NSObject {
|
class FALogin: NSObject {
|
||||||
|
|
||||||
|
enum LoginType: String, SmartCaseDefaultable {
|
||||||
|
case apple = "Apple"
|
||||||
|
case faceBook = "Facebook"
|
||||||
|
case google = "Google"
|
||||||
|
case tiktok = "Tiktok"
|
||||||
|
}
|
||||||
|
|
||||||
static let manager = FALogin()
|
static let manager = FALogin()
|
||||||
|
|
||||||
private(set) var token = UserDefaults.fa_object(forKey: kFAUserTokenDefaultsKey, as: FATokenModel.self)
|
private(set) var token = UserDefaults.fa_object(forKey: kFAUserTokenDefaultsKey, as: FATokenModel.self)
|
||||||
private(set) var userInfo = UserDefaults.fa_object(forKey: kFAUserInfoDefaultsKey, as: FAUserInfo.self)
|
private(set) var userInfo = UserDefaults.fa_object(forKey: kFAUserInfoDefaultsKey, as: FAUserInfo.self)
|
||||||
|
|
||||||
|
var isLogin: Bool {
|
||||||
|
return !(userInfo?.is_tourist ?? true)
|
||||||
|
}
|
||||||
|
|
||||||
private func setToken(_ token: FATokenModel?) {
|
private func setToken(_ token: FATokenModel?) {
|
||||||
self.token = token
|
self.token = token
|
||||||
@ -27,6 +39,67 @@ class FALogin: NSObject {
|
|||||||
UserDefaults.fa_setObject(userInfo, forKey: kFAUserInfoDefaultsKey)
|
UserDefaults.fa_setObject(userInfo, forKey: kFAUserInfoDefaultsKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///第三方登录
|
||||||
|
func thirdLogin(type: LoginType, presentingViewController: UIViewController?, completer: ((_ isFinish: Bool) -> Void)?) {
|
||||||
|
switch type {
|
||||||
|
case .apple:
|
||||||
|
appleLogin { [weak self] model in
|
||||||
|
self?.requestSignThirdLogin(thirdSignModel: model, completer: completer)
|
||||||
|
}
|
||||||
|
|
||||||
|
case .faceBook:
|
||||||
|
facebookLogin(presentingViewController: presentingViewController) { [weak self] model in
|
||||||
|
self?.requestSignThirdLogin(thirdSignModel: model, completer: completer)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///后台验证三方登录
|
||||||
|
private func requestSignThirdLogin(thirdSignModel: FAThirdSignModel?, completer: ((_ isFinish: Bool) -> Void)?) {
|
||||||
|
guard let thirdSignModel = thirdSignModel else {
|
||||||
|
completer?(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
FAStatAPI.requestLeaveApp()
|
||||||
|
FAAPI.requestSignThirdLogin(model: thirdSignModel) { [weak self] token in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let token = token else {
|
||||||
|
completer?(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.setToken(token)
|
||||||
|
self.userInfo?.is_tourist = false
|
||||||
|
self.requestUserInfo(completer: nil)
|
||||||
|
FAStatAPI.requestEnterApp()
|
||||||
|
FAStatAPI.requestStatOnLine()
|
||||||
|
completer?(true)
|
||||||
|
NotificationCenter.default.post(name: FALogin.userInfoUpdateNotification, object: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logout(completer: ((_ isFinish: Bool) -> Void)?) {
|
||||||
|
FAStatAPI.requestLeaveApp()
|
||||||
|
|
||||||
|
FAAPI.requestLogout { [weak self] token in
|
||||||
|
guard let self = self else { return }
|
||||||
|
if let token = token {
|
||||||
|
self.setToken(token)
|
||||||
|
self.userInfo?.is_tourist = true
|
||||||
|
self.requestUserInfo(completer: nil)
|
||||||
|
FAStatAPI.requestEnterApp()
|
||||||
|
FAStatAPI.requestStatOnLine()
|
||||||
|
completer?(true)
|
||||||
|
NotificationCenter.default.post(name: FALogin.userInfoUpdateNotification, object: nil)
|
||||||
|
} else {
|
||||||
|
completer?(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FALogin {
|
extension FALogin {
|
||||||
|
|||||||
23
Fableon/Object/Libs/FALogin/FAThirdSignModel.swift
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// FAThirdSignModel.swift
|
||||||
|
// Fableon
|
||||||
|
//
|
||||||
|
// Created by 湖北秦九 on 2025/10/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
|
struct FAThirdSignModel: SmartCodable {
|
||||||
|
|
||||||
|
var third_id: String?
|
||||||
|
var email: String?
|
||||||
|
//姓
|
||||||
|
var family_name: String?
|
||||||
|
//名
|
||||||
|
var giving_name: String?
|
||||||
|
|
||||||
|
var avator: String?
|
||||||
|
|
||||||
|
var platform: FALogin.LoginType?
|
||||||
|
}
|
||||||
@ -6,6 +6,8 @@
|
|||||||
//
|
//
|
||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import AppTrackingTransparency
|
||||||
|
import AdSupport
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
func debugLog(_ msg: Any, file: String = #file, function: String = #function, line: Int = #line) {
|
func debugLog(_ msg: Any, file: String = #file, function: String = #function, line: Int = #line) {
|
||||||
@ -18,6 +20,8 @@ func debugLog(_ msg: Any) { }
|
|||||||
|
|
||||||
class FATool {
|
class FATool {
|
||||||
|
|
||||||
|
static var sceneDelegate: SceneDelegate?
|
||||||
|
|
||||||
static var windowScene: UIWindowScene?
|
static var windowScene: UIWindowScene?
|
||||||
|
|
||||||
static var keyWindow: UIWindow? {
|
static var keyWindow: UIWindow? {
|
||||||
@ -52,3 +56,38 @@ class FATool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension FATool {
|
||||||
|
|
||||||
|
static func requestIDFAAuthorization(_ completion: ((String?) -> Void)? = nil) {
|
||||||
|
if FAAdjustStateManager.manager.idfaAuthorizationFinish {
|
||||||
|
completion?(ASIdentifierManager.shared().advertisingIdentifier.uuidString)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard FANetworkMonitor.manager.isReachable == true, FAAdjustStateManager.manager.apnsAuthorizationFinish, FAAdjustStateManager.manager.isOpenApp else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
ATTrackingManager.requestTrackingAuthorization { status in
|
||||||
|
FAAdjustStateManager.manager.idfaAuthorizationFinish = true
|
||||||
|
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
|
||||||
|
FATool.sceneDelegate?.retryHandleOpenAppMessage()
|
||||||
|
completion?(idfa)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///打开消息通知设置页面
|
||||||
|
static func openApnsSetting() {
|
||||||
|
if #available(iOS 16.0, *) {
|
||||||
|
if let url = URL(string: UIApplication.openNotificationSettingsURLString) {
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let url = URL(string: UIApplication.openSettingsURLString) {
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0x40",
|
||||||
|
"green" : "0x40",
|
||||||
|
"red" : "0x40"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0xFA",
|
||||||
|
"green" : "0x9D",
|
||||||
|
"red" : "0x62"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0x6D",
|
||||||
|
"green" : "0x6D",
|
||||||
|
"red" : "0x6D"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0xBC",
|
||||||
|
"green" : "0xBC",
|
||||||
|
"red" : "0xBC"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0xFF",
|
||||||
|
"green" : "0xEF",
|
||||||
|
"red" : "0xDF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0x87",
|
||||||
|
"green" : "0xCF",
|
||||||
|
"red" : "0xF6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0xE9",
|
||||||
|
"green" : "0xFE",
|
||||||
|
"red" : "0xFF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Fableon/Source/Assets.xcassets/image/Group 2072750470.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "浮窗@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "浮窗@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/Group 2072750470.imageset/浮窗@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
Fableon/Source/Assets.xcassets/image/Group 2072750470.imageset/浮窗@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 61 KiB |
22
Fableon/Source/Assets.xcassets/image/__magnifying.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "__magnifying@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "__magnifying@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/__magnifying.imageset/__magnifying@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
Fableon/Source/Assets.xcassets/image/__magnifying.imageset/__magnifying@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 63 KiB |
22
Fableon/Source/Assets.xcassets/image/alert_image_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "__to remove 1@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "__to remove 1@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/alert_image_01.imageset/__to remove 1@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
Fableon/Source/Assets.xcassets/image/alert_image_01.imageset/__to remove 1@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 45 KiB |
22
Fableon/Source/Assets.xcassets/image/apple_logo_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Vector@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Vector@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/apple_logo_icon_01.imageset/Vector@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 696 B |
BIN
Fableon/Source/Assets.xcassets/image/apple_logo_icon_01.imageset/Vector@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 994 B |
22
Fableon/Source/Assets.xcassets/image/arrow.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "arrow@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "arrow@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/arrow.imageset/arrow@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 399 B |
BIN
Fableon/Source/Assets.xcassets/image/arrow.imageset/arrow@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 537 B |
22
Fableon/Source/Assets.xcassets/image/close_icon_03.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "关闭按钮@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "关闭按钮@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/close_icon_03.imageset/关闭按钮@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Fableon/Source/Assets.xcassets/image/close_icon_03.imageset/关闭按钮@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 88 KiB |
22
Fableon/Source/Assets.xcassets/image/coin_attachment_03.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "90ad09d41707261a78f7b0c4f06813390209096846c76-uqCzGu_fw240webp 1@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "90ad09d41707261a78f7b0c4f06813390209096846c76-uqCzGu_fw240webp 1@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Fableon/Source/Assets.xcassets/image/coin_attachment_04.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Ellipse 2325@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Ellipse 2325@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/coin_attachment_04.imageset/Ellipse 2325@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 166 KiB |
BIN
Fableon/Source/Assets.xcassets/image/coin_attachment_04.imageset/Ellipse 2325@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 344 KiB |
22
Fableon/Source/Assets.xcassets/image/coin_attachment_05.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Ellipse 2326@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Ellipse 2326@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/coin_attachment_05.imageset/Ellipse 2326@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
Fableon/Source/Assets.xcassets/image/coin_attachment_05.imageset/Ellipse 2326@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 263 KiB |
22
Fableon/Source/Assets.xcassets/image/coins_icon_09.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "金币@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "金币@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/coins_icon_09.imageset/金币@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
Fableon/Source/Assets.xcassets/image/coins_icon_09.imageset/金币@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
22
Fableon/Source/Assets.xcassets/image/coins_icon_10.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "金币@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "金币@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/coins_icon_10.imageset/金币@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
Fableon/Source/Assets.xcassets/image/coins_icon_10.imageset/金币@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
22
Fableon/Source/Assets.xcassets/image/facebook_logo_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Vector@2x 2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Vector@3x 2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/facebook_logo_icon_01.imageset/Vector@2x 2.png
vendored
Normal file
|
After Width: | Height: | Size: 804 B |
BIN
Fableon/Source/Assets.xcassets/image/facebook_logo_icon_01.imageset/Vector@3x 2.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
22
Fableon/Source/Assets.xcassets/image/logo_image_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group 2414@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group 2414@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Fableon/Source/Assets.xcassets/image/logo_image_02.imageset/Group 2414@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
Fableon/Source/Assets.xcassets/image/logo_image_02.imageset/Group 2414@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
22
Fableon/Source/Assets.xcassets/image/按钮.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "按钮@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "按钮@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||