From 008d5b55b8eb14ff376280b2b75430fe5ecb2f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B9=96=E5=8C=97=E7=A7=A6=E4=B9=9D?= Date: Fri, 21 Nov 2025 09:12:46 +0800 Subject: [PATCH] 1 --- .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 35 ++ FAWidget/Assets.xcassets/Contents.json | 6 + .../WidgetBackground.colorset/Contents.json | 11 + FAWidget/FAWidget.swift | 84 ++++ FAWidget/FAWidgetBundle.swift | 17 + FAWidget/FAWidgetLiveActivity.swift | 129 ++++++ FAWidget/Info.plist | 11 + FAWidgetExtension.entitlements | 10 + Fableon.xcodeproj/project.pbxproj | 370 +++++++++++++++++- Fableon/App/AppDelegate+FAAdjust.swift | 3 +- Fableon/App/AppDelegate+FAApns.swift | 10 +- Fableon/App/SceneDelegate.swift | 43 ++ Fableon/Fableon.entitlements | 5 + .../Controller/FANavigationController.swift | 4 + .../Base/Extension/NSNumber+FAAdd.swift | 25 ++ .../Object/Base/Extension/UIImage+FAAdd.swift | 68 ++++ .../Extension/UIScrollView+FARefresh.swift | 27 +- Fableon/Object/Base/Request/FAAPI/FAAPI.swift | 17 + .../Base/Request/FANetworkManager.swift | 13 +- .../FABaseWebViewController+Script.swift | 2 +- .../Home/C/FAGenresListViewController.swift | 3 +- .../Class/Home/C/FAGenresViewController.swift | 3 +- .../Class/Home/C/FAHomeViewController.swift | 30 +- .../Home/C/FAPopularListViewController.swift | 1 + .../Home/C/FARankingListViewController.swift | 3 +- .../Object/Class/Home/M/FACategoryModel.swift | 6 + .../Class/Home/M/FAHomeNewTransformer.swift | 17 + .../Class/Home/UI/FAHomeMustSeeView.swift | 2 +- .../Object/Class/Home/UI/FAHomeNewView.swift | 2 +- .../Object/Class/Home/V/FAGenresCell.swift | 12 +- .../Class/Home/V/FAHomeBannerCell.swift | 6 +- .../Home/V/FAHomeBannerContentCell.swift | 1 + .../Class/Home/V/FAHomeSectionTitleView.swift | 5 +- .../Class/Home/V/FAHomeSectionTitleView.xib | 9 +- .../Class/Home/V/FARankingListCell.swift | 9 +- .../Class/Home/V/FASearchRecommendCell.swift | 8 +- .../Class/Home/V/FASearchResultCell.swift | 2 +- .../Class/Home/VM/FAHomeViewModel.swift | 6 +- .../Class/Me/C/FACoinPackViewController.swift | 29 ++ .../Class/Me/C/FAFeedbackViewController.swift | 68 +++- .../Class/Me/C/FAMeListViewController.swift | 45 ++- .../Class/Me/M/FAFeedbackCountModel.swift | 15 + .../Class/Me/V/FACoinPackHeaderView.swift | 2 +- .../Class/Me/V/FACoinsPackClaimListCell.swift | 3 +- .../Object/Class/Me/V/FAMeHeaderView.swift | 26 ++ .../Class/Me/V/FAMeTableViewHeaderView.swift | 4 +- .../Class/Me/V/FASettingFooterView.swift | 5 +- .../MyShort/C/FACollectViewController.swift | 25 +- .../MyShort/C/FAHistoryViewController.swift | 2 +- .../Class/Player/M/FAShortPlayModel.swift | 1 + .../Player/V/FADetailRecommendCell.swift | 1 + .../Player/V/FADetailRecommendView.swift | 27 ++ .../Class/Player/V/FAEpSelectorView.swift | 5 +- .../Player/V/FAOldVideoRechargeView.swift | 4 +- .../Class/Player/V/FAPlayerDetailCell.swift | 2 + .../Player/V/FAPlayerDetailControlView.swift | 16 +- .../Class/Player/V/FAPlayerProgressView.swift | 8 +- .../VC/FAPlayerDetailViewController.swift | 23 +- .../Player/VM/FAShortDetailViewModel.swift | 26 ++ .../C/FARecommendViewController.swift | 62 ++- .../Recommend/V/FARecommendPlayerCell.swift | 1 + .../V/FARecommendPlayerControlView.swift | 65 +-- .../Recommend/VM/FARecommendViewModel.swift | 3 +- .../Store/C/FACoinRecordViewController.swift | 8 +- .../FAConsumptionRecordsViewController.swift | 2 +- .../Store/C/FARewardCoinsViewController.swift | 2 +- .../Class/Store/C/FAStoreViewController.swift | 52 +-- .../Store/C/FAVipRecordViewController.swift | 2 +- .../Store/V/FACoinPackConfirmItem2View.swift | 2 +- .../Class/Store/V/FAStoreCoinsPackCell.swift | 13 +- .../Class/Store/V/FAStoreCoinsView.swift | 6 +- .../Object/Class/Store/V/FAStoreVipCell.swift | 6 +- .../Object/Class/Store/V/FAStoreVipView.swift | 4 +- .../ActivityManager/FAActivityManager.swift | 62 +++ .../FAAdjustStateManager.swift | 11 +- Fableon/Object/Libs/Alert/FAApnsAlert.swift | 6 + .../Object/Libs/Alert/FAUpdatesAlert.swift | 8 +- .../Object/Libs/Alert/FAVipRetainAlert.swift | 9 +- Fableon/Object/Libs/Empty/FAEmpty.swift | 29 ++ Fableon/Object/Libs/FALogin/FALogin.swift | 4 + Fableon/Object/Libs/FATool/FATool.swift | 28 +- .../color/#FF313B.colorset/Contents.json | 20 + .../image/Thalire.imageset/Contents.json | 4 +- .../image/Thalire.imageset/Fableon@2x.png | Bin 0 -> 3759 bytes .../image/Thalire.imageset/Fableon@3x.png | Bin 0 -> 6558 bytes .../image/Thalire.imageset/Thalire@2x.png | Bin 2567 -> 0 bytes .../image/Thalire.imageset/Thalire@3x.png | Bin 4183 -> 0 bytes .../image/__startap.imageset/Contents.json | 22 ++ .../image/__startap.imageset/__startap@2x.png | Bin 0 -> 58177 bytes .../image/__startap.imageset/__startap@3x.png | Bin 0 -> 92552 bytes Fableon/Source/Info.plist | 7 + Fableon/Source/en.lproj/Localizable.strings | 10 +- .../grey/preservesYoga/FFCheck.swift | 2 +- .../grey/stationaritySumd/CSGleeView.swift | 2 +- .../grey/zpbiquads/TCFableonCell.swift | 8 +- NotificationService/Info.plist | 13 + NotificationService/NotificationService.swift | 69 ++++ Podfile | 2 +- Podfile.lock | 20 +- 账号信息/银行卡信息.txt | 4 + 101 files changed, 1743 insertions(+), 188 deletions(-) create mode 100644 FAWidget/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 FAWidget/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 FAWidget/Assets.xcassets/Contents.json create mode 100644 FAWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json create mode 100644 FAWidget/FAWidget.swift create mode 100644 FAWidget/FAWidgetBundle.swift create mode 100644 FAWidget/FAWidgetLiveActivity.swift create mode 100644 FAWidget/Info.plist create mode 100644 FAWidgetExtension.entitlements create mode 100644 Fableon/Object/Base/Extension/NSNumber+FAAdd.swift create mode 100644 Fableon/Object/Base/Extension/UIImage+FAAdd.swift create mode 100644 Fableon/Object/Class/Home/M/FAHomeNewTransformer.swift create mode 100644 Fableon/Object/Class/Me/M/FAFeedbackCountModel.swift create mode 100644 Fableon/Object/Libs/ActivityManager/FAActivityManager.swift create mode 100644 Fableon/Source/Assets.xcassets/color/#FF313B.colorset/Contents.json create mode 100644 Fableon/Source/Assets.xcassets/image/Thalire.imageset/Fableon@2x.png create mode 100644 Fableon/Source/Assets.xcassets/image/Thalire.imageset/Fableon@3x.png delete mode 100644 Fableon/Source/Assets.xcassets/image/Thalire.imageset/Thalire@2x.png delete mode 100644 Fableon/Source/Assets.xcassets/image/Thalire.imageset/Thalire@3x.png create mode 100644 Fableon/Source/Assets.xcassets/image/__startap.imageset/Contents.json create mode 100644 Fableon/Source/Assets.xcassets/image/__startap.imageset/__startap@2x.png create mode 100644 Fableon/Source/Assets.xcassets/image/__startap.imageset/__startap@3x.png create mode 100644 NotificationService/Info.plist create mode 100644 NotificationService/NotificationService.swift diff --git a/FAWidget/Assets.xcassets/AccentColor.colorset/Contents.json b/FAWidget/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/FAWidget/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FAWidget/Assets.xcassets/AppIcon.appiconset/Contents.json b/FAWidget/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/FAWidget/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FAWidget/Assets.xcassets/Contents.json b/FAWidget/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/FAWidget/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FAWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json b/FAWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/FAWidget/Assets.xcassets/WidgetBackground.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FAWidget/FAWidget.swift b/FAWidget/FAWidget.swift new file mode 100644 index 0000000..d7d230f --- /dev/null +++ b/FAWidget/FAWidget.swift @@ -0,0 +1,84 @@ +// +// FAWidget.swift +// FAWidget +// +// Created by 湖北秦九 on 2025/11/10. +// + +import WidgetKit +import SwiftUI + +struct Provider: TimelineProvider { + func placeholder(in context: Context) -> SimpleEntry { + SimpleEntry(date: Date(), emoji: "😀") + } + + func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { + let entry = SimpleEntry(date: Date(), emoji: "😀") + completion(entry) + } + + func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { + var entries: [SimpleEntry] = [] + + // Generate a timeline consisting of five entries an hour apart, starting from the current date. + let currentDate = Date() + for hourOffset in 0 ..< 5 { + let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! + let entry = SimpleEntry(date: entryDate, emoji: "😀") + entries.append(entry) + } + + let timeline = Timeline(entries: entries, policy: .atEnd) + completion(timeline) + } + +// func relevances() async -> WidgetRelevances { +// // Generate a list containing the contexts this widget is relevant in. +// } +} + +struct SimpleEntry: TimelineEntry { + let date: Date + let emoji: String +} + +struct FAWidgetEntryView : View { + var entry: Provider.Entry + + var body: some View { + VStack { + Text("Time:") + Text(entry.date, style: .time) + + Text("Emoji:") + Text(entry.emoji) + } + } +} + +struct FAWidget: Widget { + let kind: String = "FAWidget" + + var body: some WidgetConfiguration { + StaticConfiguration(kind: kind, provider: Provider()) { entry in + if #available(iOS 17.0, *) { + FAWidgetEntryView(entry: entry) + .containerBackground(.fill.tertiary, for: .widget) + } else { + FAWidgetEntryView(entry: entry) + .padding() + .background() + } + } + .configurationDisplayName("My Widget") + .description("This is an example widget.") + } +} + +//#Preview(as: .systemSmall) { +// FAWidget() +//} timeline: { +// SimpleEntry(date: .now, emoji: "😀") +// SimpleEntry(date: .now, emoji: "🤩") +//} diff --git a/FAWidget/FAWidgetBundle.swift b/FAWidget/FAWidgetBundle.swift new file mode 100644 index 0000000..aef11d9 --- /dev/null +++ b/FAWidget/FAWidgetBundle.swift @@ -0,0 +1,17 @@ +// +// FAWidgetBundle.swift +// FAWidget +// +// Created by 湖北秦九 on 2025/11/10. +// + +import WidgetKit +import SwiftUI + +@main +struct FAWidgetBundle: WidgetBundle { + var body: some Widget { +// FAWidget() + FAWidgetLiveActivity() + } +} diff --git a/FAWidget/FAWidgetLiveActivity.swift b/FAWidget/FAWidgetLiveActivity.swift new file mode 100644 index 0000000..6febf22 --- /dev/null +++ b/FAWidget/FAWidgetLiveActivity.swift @@ -0,0 +1,129 @@ +// +// FAWidgetLiveActivity.swift +// FAWidget +// +// Created by 湖北秦九 on 2025/11/10. +// + +import ActivityKit +import WidgetKit +import SwiftUI + + +struct FAWidgetLiveActivity: Widget { + var body: some WidgetConfiguration { + ActivityConfiguration(for: ActivityManagerAttributes.self) { context in + // 🔹 Live Activity UI(锁屏 & Banner) + HStack(spacing: 16) { + // 🔹 网络图片 + if let imageData = try? Data(contentsOf: URL(string: context.state.videoCoverPath)!), + let uiImage = UIImage(data: imageData) { + Image(uiImage: uiImage) + .resizable() + .frame(width: 108, height: 146) + .cornerRadius(8) + .clipped() + + + } else { + Image("logo100") + .frame(width: 100, height: 100) + .cornerRadius(8) + .clipped() + + } + + // 🔹 文本内容 + VStack(alignment: .leading, spacing: 4) { + VStack(alignment: .leading, spacing: 4) { + HStack { + Text("Playing") + .font(.caption) + .foregroundColor(.gray) + Spacer() + Image("logo40") + } + + Text(context.state.videoTitle) + .font(.headline) + .foregroundColor(.black) + + Text("Ep.\(context.state.videoEpisode)") + .font(.subheadline) + .foregroundColor(.gray) + } + + Spacer() + + // 🔹 按钮 + Button(action: { print("Watch Now") }) { + HStack { + Spacer() + Image(systemName: "play.fill") + Text("Watch Now") + Spacer() + } + .padding(.horizontal, 14) + .padding(.vertical, 8) + .background( + LinearGradient(colors: [Color.red, Color.orange], startPoint: .leading, endPoint: .trailing) + ) + .foregroundColor(.white) + .cornerRadius(20) + } + } + } + .padding() + .background(RoundedRectangle(cornerRadius: 8).fill(Color.white)) + .activityBackgroundTint(Color.white) + .activitySystemActionForegroundColor(.primary) + .widgetURL(URL(string: "fableonapp://liveActivity?short_play_id=\(context.state.videoId)")) + + } dynamicIsland: { context in + DynamicIsland { + // 🔹 Expanded UI + DynamicIslandExpandedRegion(.leading) { + VStack (alignment: .center) { + Spacer() + Image("logo40") + .resizable() + .frame(width: 40, height: 40) + .cornerRadius(5) + Spacer() + } + } + + DynamicIslandExpandedRegion(.center) { + VStack (alignment: .center) { + Spacer() + Text(context.state.videoTitle) + .font(.headline) + .foregroundColor(.primary) + Spacer() + + } + } + + DynamicIslandExpandedRegion(.trailing) { + VStack (alignment: .center) { + Spacer() + Text("Ep.\(context.state.videoEpisode)") + .font(.subheadline) + .foregroundColor(.secondary) + Spacer() + } + } + } compactLeading: { + Image("logo40") + } compactTrailing: { + Text("Ep.\(context.state.videoEpisode)") + .font(.caption2) + } minimal: { + Image("logo40") + } + .widgetURL(URL(string: "fableonapp://liveActivity?short_play_id=\(context.state.videoId)")) + .keylineTint(Color.red) + } + } +} + diff --git a/FAWidget/Info.plist b/FAWidget/Info.plist new file mode 100644 index 0000000..0f118fb --- /dev/null +++ b/FAWidget/Info.plist @@ -0,0 +1,11 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.widgetkit-extension + + + diff --git a/FAWidgetExtension.entitlements b/FAWidgetExtension.entitlements new file mode 100644 index 0000000..06a809b --- /dev/null +++ b/FAWidgetExtension.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.com.hn.qinjiu.fableon + + + diff --git a/Fableon.xcodeproj/project.pbxproj b/Fableon.xcodeproj/project.pbxproj index 4a14494..02cc1c1 100644 --- a/Fableon.xcodeproj/project.pbxproj +++ b/Fableon.xcodeproj/project.pbxproj @@ -227,6 +227,21 @@ 03E9A74E2EB5E0F7000D1067 /* FALanguageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A74D2EB5E0F7000D1067 /* FALanguageModel.swift */; }; 03E9A7502EB5EAC0000D1067 /* FALanguageDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A74F2EB5EAC0000D1067 /* FALanguageDataModel.swift */; }; 03E9A7522EB83A58000D1067 /* FAAppStartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7512EB83A58000D1067 /* FAAppStartViewController.swift */; }; + 03E9A75E2EC19101000D1067 /* NotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 03E9A7572EC19101000D1067 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 03E9A7682EC19110000D1067 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7652EC19110000D1067 /* NotificationService.swift */; }; + 03E9A76F2EC1950F000D1067 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03E9A76E2EC1950F000D1067 /* WidgetKit.framework */; }; + 03E9A7712EC1950F000D1067 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03E9A7702EC1950F000D1067 /* SwiftUI.framework */; }; + 03E9A77E2EC19510000D1067 /* FAWidgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 03E9A76D2EC1950F000D1067 /* FAWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 03E9A7892EC19516000D1067 /* FAWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7842EC19516000D1067 /* FAWidget.swift */; }; + 03E9A78A2EC19516000D1067 /* FAWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7852EC19516000D1067 /* FAWidgetBundle.swift */; }; + 03E9A78B2EC19516000D1067 /* FAWidgetLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7862EC19516000D1067 /* FAWidgetLiveActivity.swift */; }; + 03E9A78C2EC19516000D1067 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 03E9A7832EC19516000D1067 /* Assets.xcassets */; }; + 03E9A7902EC1B007000D1067 /* FAActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A78F2EC1B007000D1067 /* FAActivityManager.swift */; }; + 03E9A7912EC1B007000D1067 /* FAActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A78F2EC1B007000D1067 /* FAActivityManager.swift */; }; + 03E9A7942EC1B24E000D1067 /* UIImage+FAAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7932EC1B24E000D1067 /* UIImage+FAAdd.swift */; }; + 03E9A7972EC2C7DF000D1067 /* FAHomeNewTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7962EC2C7DF000D1067 /* FAHomeNewTransformer.swift */; }; + 03E9A79A2EC2C8FD000D1067 /* NSNumber+FAAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7992EC2C8F3000D1067 /* NSNumber+FAAdd.swift */; }; + 03E9A79C2EC31AD0000D1067 /* FAFeedbackCountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A79B2EC31AD0000D1067 /* FAFeedbackCountModel.swift */; }; B86XD3O90WO2R4725L084287 /* Pods_Fableon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */; }; F3019606DA7P36H41G408X13 /* ZStreamCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F38E33739F391364D0151P7Z /* ZStreamCell.swift */; }; F30470W590T8274E1642349G /* CControlCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32MR5F8X6Q3HSZ560BD0159 /* CControlCell.swift */; }; @@ -333,6 +348,38 @@ F3ZT3I4VAGB5405FWL36UW12 /* ZFGEtworkCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3342A2631Z4ZPCT74M73CK1 /* ZFGEtworkCell.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 03E9A75C2EC19101000D1067 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3LK276P33H73Y39H9X6VTDI /* Project object */; + proxyType = 1; + remoteGlobalIDString = 03E9A7562EC19101000D1067; + remoteInfo = NotificationService; + }; + 03E9A77C2EC19510000D1067 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3LK276P33H73Y39H9X6VTDI /* Project object */; + proxyType = 1; + remoteGlobalIDString = 03E9A76C2EC1950F000D1067; + remoteInfo = FAWidgetExtension; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 03E9A7632EC19101000D1067 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 03E9A75E2EC19101000D1067 /* NotificationService.appex in Embed Foundation Extensions */, + 03E9A77E2EC19510000D1067 /* FAWidgetExtension.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 031FDEAB2EAF05FB00F4CAC7 /* FAStoreVipCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAStoreVipCell.swift; sourceTree = ""; }; 031FDEAD2EB093B100F4CAC7 /* FABuyRecordsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FABuyRecordsModel.swift; sourceTree = ""; }; @@ -552,6 +599,23 @@ 03E9A74D2EB5E0F7000D1067 /* FALanguageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALanguageModel.swift; sourceTree = ""; }; 03E9A74F2EB5EAC0000D1067 /* FALanguageDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALanguageDataModel.swift; sourceTree = ""; }; 03E9A7512EB83A58000D1067 /* FAAppStartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAAppStartViewController.swift; sourceTree = ""; }; + 03E9A7572EC19101000D1067 /* NotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 03E9A7642EC19110000D1067 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 03E9A7652EC19110000D1067 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; + 03E9A76D2EC1950F000D1067 /* FAWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FAWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 03E9A76E2EC1950F000D1067 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + 03E9A7702EC1950F000D1067 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + 03E9A7832EC19516000D1067 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 03E9A7842EC19516000D1067 /* FAWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAWidget.swift; sourceTree = ""; }; + 03E9A7852EC19516000D1067 /* FAWidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAWidgetBundle.swift; sourceTree = ""; }; + 03E9A7862EC19516000D1067 /* FAWidgetLiveActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAWidgetLiveActivity.swift; sourceTree = ""; }; + 03E9A7872EC19516000D1067 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 03E9A78F2EC1B007000D1067 /* FAActivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAActivityManager.swift; sourceTree = ""; }; + 03E9A7922EC1B0BC000D1067 /* FAWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FAWidgetExtension.entitlements; sourceTree = ""; }; + 03E9A7932EC1B24E000D1067 /* UIImage+FAAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+FAAdd.swift"; sourceTree = ""; }; + 03E9A7962EC2C7DF000D1067 /* FAHomeNewTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAHomeNewTransformer.swift; sourceTree = ""; }; + 03E9A7992EC2C8F3000D1067 /* NSNumber+FAAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSNumber+FAAdd.swift"; sourceTree = ""; }; + 03E9A79B2EC31AD0000D1067 /* FAFeedbackCountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAFeedbackCountModel.swift; sourceTree = ""; }; 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 = ""; }; 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 = ""; }; @@ -663,6 +727,22 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 03E9A7542EC19101000D1067 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 03E9A76A2EC1950F000D1067 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 03E9A7712EC1950F000D1067 /* SwiftUI.framework in Frameworks */, + 03E9A76F2EC1950F000D1067 /* WidgetKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F37182X6857153T873504S9J /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -809,6 +889,8 @@ 03E239772EAA1A29004A8CEC /* UIStackView+FAAdd.swift */, 03E239782EAA1A29004A8CEC /* UIView+FAAdd.swift */, 03E239792EAA1A29004A8CEC /* UserDefaults+FAAdd.swift */, + 03E9A7932EC1B24E000D1067 /* UIImage+FAAdd.swift */, + 03E9A7992EC2C8F3000D1067 /* NSNumber+FAAdd.swift */, ); path = Extension; sourceTree = ""; @@ -897,6 +979,7 @@ 03E239BD2EAA1A4E004A8CEC /* FAHomeItem.swift */, 03E239BE2EAA1A4E004A8CEC /* FAHomeModuleItem.swift */, 03E239BF2EAA1A4E004A8CEC /* FAPopularModel.swift */, + 03E9A7962EC2C7DF000D1067 /* FAHomeNewTransformer.swift */, ); path = M; sourceTree = ""; @@ -988,6 +1071,7 @@ children = ( 03E239ED2EAA1A4E004A8CEC /* FAMeItemModel.swift */, 03E9A7412EB4A603000D1067 /* FAVersionUpdateModel.swift */, + 03E9A79B2EC31AD0000D1067 /* FAFeedbackCountModel.swift */, ); path = M; sourceTree = ""; @@ -1212,6 +1296,7 @@ 03E23A962EAA1A65004A8CEC /* Libs */ = { isa = PBXGroup; children = ( + 03E9A78E2EC1AFEA000D1067 /* ActivityManager */, 031FDEE22EB3487700F4CAC7 /* Alert */, 039CE6122EAB0DE1007B5EED /* FAIap */, 039CE60F2EAB0D2D007B5EED /* JXIAPManager */, @@ -1302,10 +1387,41 @@ path = WaterfallFlowLayout; sourceTree = ""; }; + 03E9A7662EC19110000D1067 /* NotificationService */ = { + isa = PBXGroup; + children = ( + 03E9A7642EC19110000D1067 /* Info.plist */, + 03E9A7652EC19110000D1067 /* NotificationService.swift */, + ); + path = NotificationService; + sourceTree = ""; + }; + 03E9A7882EC19516000D1067 /* FAWidget */ = { + isa = PBXGroup; + children = ( + 03E9A7832EC19516000D1067 /* Assets.xcassets */, + 03E9A7842EC19516000D1067 /* FAWidget.swift */, + 03E9A7852EC19516000D1067 /* FAWidgetBundle.swift */, + 03E9A7862EC19516000D1067 /* FAWidgetLiveActivity.swift */, + 03E9A7872EC19516000D1067 /* Info.plist */, + ); + path = FAWidget; + sourceTree = ""; + }; + 03E9A78E2EC1AFEA000D1067 /* ActivityManager */ = { + isa = PBXGroup; + children = ( + 03E9A78F2EC1B007000D1067 /* FAActivityManager.swift */, + ); + path = ActivityManager; + sourceTree = ""; + }; 612P1QES0606A2642109V515 /* Frameworks */ = { isa = PBXGroup; children = ( C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */, + 03E9A76E2EC1950F000D1067 /* WidgetKit.framework */, + 03E9A7702EC1950F000D1067 /* SwiftUI.framework */, ); name = Frameworks; sourceTree = ""; @@ -1343,7 +1459,10 @@ F31ABI705806054356280I22 = { isa = PBXGroup; children = ( + 03E9A7922EC1B0BC000D1067 /* FAWidgetExtension.entitlements */, F3YR32SS1P8731297KD665X5 /* Fableon */, + 03E9A7662EC19110000D1067 /* NotificationService */, + 03E9A7882EC19516000D1067 /* FAWidget */, F3B536I6734E05L319J6654P /* Products */, A9370738344P8616G77589I7 /* Pods */, 612P1QES0606A2642109V515 /* Frameworks */, @@ -1634,6 +1753,8 @@ isa = PBXGroup; children = ( F36676EN936M89B15P51177W /* Fableon.app */, + 03E9A7572EC19101000D1067 /* NotificationService.appex */, + 03E9A76D2EC1950F000D1067 /* FAWidgetExtension.appex */, ); name = Products; sourceTree = ""; @@ -1788,6 +1909,40 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 03E9A7562EC19101000D1067 /* NotificationService */ = { + isa = PBXNativeTarget; + buildConfigurationList = 03E9A7602EC19101000D1067 /* Build configuration list for PBXNativeTarget "NotificationService" */; + buildPhases = ( + 03E9A7532EC19101000D1067 /* Sources */, + 03E9A7542EC19101000D1067 /* Frameworks */, + 03E9A7552EC19101000D1067 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NotificationService; + productName = NotificationService; + productReference = 03E9A7572EC19101000D1067 /* NotificationService.appex */; + productType = "com.apple.product-type.app-extension"; + }; + 03E9A76C2EC1950F000D1067 /* FAWidgetExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 03E9A7802EC19510000D1067 /* Build configuration list for PBXNativeTarget "FAWidgetExtension" */; + buildPhases = ( + 03E9A7692EC1950F000D1067 /* Sources */, + 03E9A76A2EC1950F000D1067 /* Frameworks */, + 03E9A76B2EC1950F000D1067 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FAWidgetExtension; + productName = FAWidgetExtension; + productReference = 03E9A76D2EC1950F000D1067 /* FAWidgetExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; F3F6B3Q1BI331E859340M109 /* Fableon */ = { isa = PBXNativeTarget; buildConfigurationList = F3511CV60KB1225F8K46932G /* Build configuration list for PBXNativeTarget "Fableon" */; @@ -1797,10 +1952,13 @@ F37182X6857153T873504S9J /* Frameworks */, F3T938414J234X46539JR019 /* Resources */, 4809W21R638Z15866LWB2041 /* [CP] Embed Pods Frameworks */, + 03E9A7632EC19101000D1067 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( + 03E9A75D2EC19101000D1067 /* PBXTargetDependency */, + 03E9A77D2EC19510000D1067 /* PBXTargetDependency */, ); name = Fableon; productName = Fableon; @@ -1814,9 +1972,15 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1640; + LastSwiftUpdateCheck = 2600; LastUpgradeCheck = 1640; TargetAttributes = { + 03E9A7562EC19101000D1067 = { + CreatedOnToolsVersion = 26.0.1; + }; + 03E9A76C2EC1950F000D1067 = { + CreatedOnToolsVersion = 26.0.1; + }; F3F6B3Q1BI331E859340M109 = { CreatedOnToolsVersion = 16.4; LastSwiftMigration = 1640; @@ -1842,11 +2006,28 @@ projectRoot = ""; targets = ( F3F6B3Q1BI331E859340M109 /* Fableon */, + 03E9A7562EC19101000D1067 /* NotificationService */, + 03E9A76C2EC1950F000D1067 /* FAWidgetExtension */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 03E9A7552EC19101000D1067 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 03E9A76B2EC1950F000D1067 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 03E9A78C2EC19516000D1067 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F3T938414J234X46539JR019 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1937,12 +2118,32 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 03E9A7532EC19101000D1067 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 03E9A7682EC19110000D1067 /* NotificationService.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 03E9A7692EC1950F000D1067 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 03E9A7892EC19516000D1067 /* FAWidget.swift in Sources */, + 03E9A78A2EC19516000D1067 /* FAWidgetBundle.swift in Sources */, + 03E9A7912EC1B007000D1067 /* FAActivityManager.swift in Sources */, + 03E9A78B2EC19516000D1067 /* FAWidgetLiveActivity.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F3A707N33187J9XN3E985764 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F39C9Y266RT4H0109L9T1807 /* LKVRecommendedHomeView.swift in Sources */, F37S2W333F5881I12F59EXJ0 /* KCFAlignment.swift in Sources */, + 03E9A79C2EC31AD0000D1067 /* FAFeedbackCountModel.swift in Sources */, F34Y5K0497T0B7D95Q1F4304 /* VRResult.swift in Sources */, F3Q1B8O8164TYQ9724T34V29 /* OACAbleView.swift in Sources */, F36MZ39RQ295569BV1915908 /* FOMptyView.swift in Sources */, @@ -1984,6 +2185,7 @@ F3362Y34741Z8AE0YP4S2Y54 /* YORecommended.swift in Sources */, 03E239632EAA1945004A8CEC /* AppDelegate+FAConfig.swift in Sources */, 03E239642EAA1945004A8CEC /* AppDelegate.swift in Sources */, + 03E9A7972EC2C7DF000D1067 /* FAHomeNewTransformer.swift in Sources */, 03E239652EAA1945004A8CEC /* SceneDelegate.swift in Sources */, 039CE6092EAA2F71007B5EED /* FAAdjustStateManager.swift in Sources */, F333U95746V7VK13QI9275B3 /* UMenuTransformerCell.swift in Sources */, @@ -2089,6 +2291,7 @@ 03E23A5C2EAA1A4E004A8CEC /* FAGenresListViewController.swift in Sources */, 03E23A5D2EAA1A4E004A8CEC /* FARecommendViewModel.swift in Sources */, 03E23A5E2EAA1A4E004A8CEC /* FAHomeMustSeeContentView.swift in Sources */, + 03E9A7902EC1B007000D1067 /* FAActivityManager.swift in Sources */, 03E23A5F2EAA1A4E004A8CEC /* FAEpSelectorCell.swift in Sources */, 031FDEEC2EB35DF600F4CAC7 /* FACoinsPackAlert.swift in Sources */, 03E23A602EAA1A4E004A8CEC /* FASearchResultView.swift in Sources */, @@ -2111,6 +2314,7 @@ 03E23A6E2EAA1A4E004A8CEC /* FARankingListCell.swift in Sources */, 031FDED22EB2F69200F4CAC7 /* FALoginView.swift in Sources */, 03E23A6F2EAA1A4E004A8CEC /* FAHomeBannerCell.swift in Sources */, + 03E9A79A2EC2C8FD000D1067 /* NSNumber+FAAdd.swift in Sources */, 03E23A702EAA1A4E004A8CEC /* FAGenresCell.swift in Sources */, 03E23A712EAA1A4E004A8CEC /* FAHomeSectionTitleView.swift in Sources */, 03E23A722EAA1A4E004A8CEC /* FASettingViewController.swift in Sources */, @@ -2206,6 +2410,7 @@ 03E239AF2EAA1A29004A8CEC /* FAAPI.swift in Sources */, 031FDECA2EB1F8F200F4CAC7 /* FACoinsPackReceiveModel.swift in Sources */, 03E239B02EAA1A29004A8CEC /* FAWebView.swift in Sources */, + 03E9A7942EC1B24E000D1067 /* UIImage+FAAdd.swift in Sources */, 039CE61C2EAB0F29007B5EED /* FAIapOrderModel.swift in Sources */, 03E9A7522EB83A58000D1067 /* FAAppStartViewController.swift in Sources */, 03E239B12EAA1A29004A8CEC /* FANetworkMonitor.swift in Sources */, @@ -2232,6 +2437,19 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 03E9A75D2EC19101000D1067 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 03E9A7562EC19101000D1067 /* NotificationService */; + targetProxy = 03E9A75C2EC19101000D1067 /* PBXContainerItemProxy */; + }; + 03E9A77D2EC19510000D1067 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 03E9A76C2EC1950F000D1067 /* FAWidgetExtension */; + targetProxy = 03E9A77C2EC19510000D1067 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ F3A0557617AU32W3L218F159 /* Localizable.strings */ = { isa = PBXVariantGroup; @@ -2252,6 +2470,132 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 03E9A7612EC19101000D1067 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 6XALB8RSYF; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = NotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = NotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon.NotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 03E9A7622EC19101000D1067 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 6XALB8RSYF; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = NotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = NotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon.NotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 03E9A7812EC19510000D1067 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = FAWidgetExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 6XALB8RSYF; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = FAWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = FAWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon.FAWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 03E9A7822EC19510000D1067 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + CODE_SIGN_ENTITLEMENTS = FAWidgetExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 6XALB8RSYF; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = FAWidget/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = FAWidget; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 16.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon.FAWidget; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; F33W2S46100182427H2605Y0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2391,6 +2735,7 @@ INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; 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_NSSupportsLiveActivities = YES; INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; @@ -2402,7 +2747,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -2432,6 +2777,7 @@ INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; 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_NSSupportsLiveActivities = YES; INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; @@ -2443,7 +2789,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = com.hn.qinjiu.fableon; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -2458,6 +2804,24 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 03E9A7602EC19101000D1067 /* Build configuration list for PBXNativeTarget "NotificationService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 03E9A7612EC19101000D1067 /* Debug */, + 03E9A7622EC19101000D1067 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 03E9A7802EC19510000D1067 /* Build configuration list for PBXNativeTarget "FAWidgetExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 03E9A7812EC19510000D1067 /* Debug */, + 03E9A7822EC19510000D1067 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; F3511CV60KB1225F8K46932G /* Build configuration list for PBXNativeTarget "Fableon" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Fableon/App/AppDelegate+FAAdjust.swift b/Fableon/App/AppDelegate+FAAdjust.swift index 38d1e0a..d5d878e 100644 --- a/Fableon/App/AppDelegate+FAAdjust.swift +++ b/Fableon/App/AppDelegate+FAAdjust.swift @@ -42,7 +42,8 @@ extension SceneDelegate { guard FANetworkMonitor.manager.isReachable == true, manager.isOpenApp, - manager.idfaAuthorizationFinish //idfa授权完成 + manager.idfaAuthorizationFinish, //idfa授权完成 + manager.upgradeAlertFinish else { if let webpageURL = webpageURL { manager.webpageURL = webpageURL diff --git a/Fableon/App/AppDelegate+FAApns.swift b/Fableon/App/AppDelegate+FAApns.swift index 24e06f7..bdf9648 100644 --- a/Fableon/App/AppDelegate+FAApns.swift +++ b/Fableon/App/AppDelegate+FAApns.swift @@ -22,16 +22,16 @@ extension SceneDelegate { center.requestAuthorization(options: [.badge, .sound, .alert]) { grant, error in if !grant { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.showApnsAlert() } + } else { + FAAdjustStateManager.manager.apnsFinish() + } - FAAdjustStateManager.manager.apnsAuthorizationFinish = true - - FATool.sceneDelegate?.retryHandleOpenAppMessage() - FATool.requestIDFAAuthorization(nil) + FAStatAPI.uploadApnsAuthorizationStatus() } UIApplication.shared.registerForRemoteNotifications() diff --git a/Fableon/App/SceneDelegate.swift b/Fableon/App/SceneDelegate.swift index 89f4e4e..940346b 100644 --- a/Fableon/App/SceneDelegate.swift +++ b/Fableon/App/SceneDelegate.swift @@ -8,6 +8,7 @@ import UIKit import YYText import MJRefresh +import Kingfisher class SceneDelegate: UIResponder, UIWindowSceneDelegate { @@ -62,6 +63,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func sceneDidEnterBackground(_ scene: UIScene) { FAAdjustStateManager.manager.allowOpenMessage = true + if #available(iOS 16.1, *) { + startWidgeLiveActivity() + } } @@ -123,10 +127,18 @@ extension SceneDelegate { } @objc private func networkStatusDidChangeNotification() { + let localizedData = FALanguageManager.manager.languageData ?? [:] + if FANetworkMonitor.manager.isReachable == true { + handleOnLine() FATool.requestIDFAAuthorization(nil) self.retryHandleOpenAppMessage() FAIapManager.manager.preloadingProducts() + + ///缺少语言数据,重新获取语言数据 + if localizedData.isEmpty { + self.startApp() + } } } @@ -134,4 +146,35 @@ extension SceneDelegate { MJRefreshConfig.default.languageCode = FALanguageManager.manager.mjLanguageKey setTabBarController() } + + @available(iOS 16.1, *) + private func startWidgeLiveActivity() { + + guard let model = FATool.widgetLiveActivityModel, let imageUrl = URL(string: model.image_url ?? "") else { return } + + KingfisherManager.shared.retrieveImage(with: imageUrl) { result in + switch result { + case .success(let imageResult): + let image = imageResult.image + + guard let data = image.compressImageSize(toByte: 9 * 1024) else { return } + guard let filePath = FAActivityManager.coverFileUrl else { return } + + do { + try data.write(to: filePath, options: .atomic) + + FAActivityManager.liveActivity(with: model.name ?? "", + videoId: model.short_play_id ?? "", + videoEpisode: model.current_episode ?? "") + } catch { + + } + + default: + break + } + } + + + } } diff --git a/Fableon/Fableon.entitlements b/Fableon/Fableon.entitlements index 56de1c5..39eb610 100644 --- a/Fableon/Fableon.entitlements +++ b/Fableon/Fableon.entitlements @@ -12,6 +12,11 @@ applinks:fableon.go.link applinks:kuzt.adj.st + applinks:www.hbqinjiu.com + + com.apple.security.application-groups + + group.com.hn.qinjiu.fableon keychain-access-groups diff --git a/Fableon/Object/Base/Controller/FANavigationController.swift b/Fableon/Object/Base/Controller/FANavigationController.swift index 46ecbe1..03982c2 100644 --- a/Fableon/Object/Base/Controller/FANavigationController.swift +++ b/Fableon/Object/Base/Controller/FANavigationController.swift @@ -12,6 +12,10 @@ class FANavigationController: UINavigationController { override func viewDidLoad() { super.viewDidLoad() + if #available(iOS 26.0, *) { + self.interactiveContentPopGestureRecognizer?.isEnabled = false + } + fd_fullscreenPopGestureRecognizer.isEnabled = true } diff --git a/Fableon/Object/Base/Extension/NSNumber+FAAdd.swift b/Fableon/Object/Base/Extension/NSNumber+FAAdd.swift new file mode 100644 index 0000000..122c1d2 --- /dev/null +++ b/Fableon/Object/Base/Extension/NSNumber+FAAdd.swift @@ -0,0 +1,25 @@ +// +// NSNumber+FAAdd.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/11. +// + +import UIKit + +extension NSNumber { + + func toString(maximumFractionDigits: Int = 10, minimumFractionDigits: Int? = nil, roundingMode: NumberFormatter.RoundingMode? = nil) -> String { + let formatter = NumberFormatter() + formatter.minimumIntegerDigits = 1 + formatter.maximumFractionDigits = maximumFractionDigits + if let minimumFractionDigits = minimumFractionDigits { + formatter.minimumFractionDigits = minimumFractionDigits + } + if let roundingMode = roundingMode { + formatter.roundingMode = roundingMode + } + formatter.numberStyle = .none + return formatter.string(from: self) ?? "0" + } +} diff --git a/Fableon/Object/Base/Extension/UIImage+FAAdd.swift b/Fableon/Object/Base/Extension/UIImage+FAAdd.swift new file mode 100644 index 0000000..bf43683 --- /dev/null +++ b/Fableon/Object/Base/Extension/UIImage+FAAdd.swift @@ -0,0 +1,68 @@ +// +// UIImage+FAAdd.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/10. +// + +import UIKit + +extension UIImage { + /// 根据图片大小计算压缩率 + static func getCompressRate(imageSize: CGFloat, targetSize: CGFloat) -> CGFloat { + var rate = Int(imageSize / targetSize) + rate = (rate == 0) ? 1 : rate + + // 默认压缩范围 + let maxCompressRate: CGFloat = 0.8 + let minCompressRate: CGFloat = 0.2 + + // 反比例压缩函数 + var compressRate = 0.8 / CGFloat(rate) + + // 限制范围 + compressRate = min(max(compressRate, minCompressRate), maxCompressRate) + return compressRate + } + + /// 压缩图片到指定字节大小(JPEG格式) + func compressImageSize(toByte maxLength: Int) -> Data? { + let image = self + + // 初次压缩(质量) + guard var data = image.jpegData(compressionQuality: 1.0) else { return nil } + if data.count < maxLength { + return data + } + + var compressRate = UIImage.getCompressRate(imageSize: CGFloat(data.count), targetSize: CGFloat(maxLength)) + data = image.jpegData(compressionQuality: compressRate) ?? data + if data.count < maxLength { + return data + } + + // 再次通过缩放降低体积 + var resultImage = UIImage(data: data) ?? image + var lastDataLength = 0 + + while data.count > maxLength && data.count != lastDataLength { + lastDataLength = data.count + let ratio = CGFloat(maxLength) / CGFloat(data.count) + let newWidth = max(Int(resultImage.size.width * sqrt(ratio)), 10) + let newHeight = max(Int(resultImage.size.height * sqrt(ratio)), 10) + let newSize = CGSize(width: newWidth, height: newHeight) + + if newSize.width < 10 || newSize.height < 10 { break } + + // 绘制新尺寸图片 + UIGraphicsBeginImageContext(newSize) + resultImage.draw(in: CGRect(origin: .zero, size: newSize)) + resultImage = UIGraphicsGetImageFromCurrentImageContext() ?? resultImage + UIGraphicsEndImageContext() + + data = resultImage.jpegData(compressionQuality: compressRate) ?? data + } + + return data + } +} diff --git a/Fableon/Object/Base/Extension/UIScrollView+FARefresh.swift b/Fableon/Object/Base/Extension/UIScrollView+FARefresh.swift index 2c03c5f..a784330 100644 --- a/Fableon/Object/Base/Extension/UIScrollView+FARefresh.swift +++ b/Fableon/Object/Base/Extension/UIScrollView+FARefresh.swift @@ -18,12 +18,11 @@ extension UIScrollView { } func fa_addRefreshFooter(insetBottom: CGFloat = 0, block: (() -> Void)?) { - let footer = MJRefreshAutoNormalFooter(refreshingBlock: { + self.mj_footer = MJRefreshBackNormalFooter(refreshingBlock: { block?() }) - footer.ignoredScrollViewContentInsetBottom = insetBottom - self.mj_footer = footer + self.mj_footer?.ignoredScrollViewContentInsetBottom = insetBottom } @@ -54,17 +53,17 @@ extension UIScrollView { } func fa_updateNoMoreDataState(_ hasNextPage: Bool?) { - if hasNextPage == false { - self.fa_endRefreshingWithNoMoreData() - } else { - self.fa_resetNoMoreData() - } - - if self.mj_totalDataCount() == 0 { - self.mj_footer?.isHidden = true - } else { - self.mj_footer?.isHidden = false - } +// if hasNextPage == false { +// self.fa_endRefreshingWithNoMoreData() +// } else { +// self.fa_resetNoMoreData() +// } +// +// if self.mj_totalDataCount() == 0 { +// self.mj_footer?.isHidden = true +// } else { +// self.mj_footer?.isHidden = false +// } } } diff --git a/Fableon/Object/Base/Request/FAAPI/FAAPI.swift b/Fableon/Object/Base/Request/FAAPI/FAAPI.swift index 71ffed0..8cd1083 100644 --- a/Fableon/Object/Base/Request/FAAPI/FAAPI.swift +++ b/Fableon/Object/Base/Request/FAAPI/FAAPI.swift @@ -65,6 +65,9 @@ struct FAAPI { ] FANetworkManager.manager.request(FABaseURL + "/myHistorys", method: .get, parameters: parameters, isToast: false) { (response: FANetworkManager.Response>) in + if page == 1, let model = response.data?.list?.first { + FATool.widgetLiveActivityModel = model + } completer?(response.data) } } @@ -103,6 +106,7 @@ struct FAAPI { parameters: parameters, isLoding: true) { (response: FANetworkManager.Response) in if response.isSuccess { + FAToast.show(text: "fableo_success".localized) success?() NotificationCenter.default.post(name: FAAPI.updateShortCollectStateNotification, object: nil, userInfo: [ "state" : isCollect, @@ -301,6 +305,19 @@ struct FAAPI { } } + ///获取反馈红点数量 + static func requestFeedbackRedCount(completer: ((_ model: FAFeedbackCountModel?) -> Void)?) { + + FANetworkManager.manager.request(FABaseURL + "/noticeNum", + method: .post, + parameters: nil, + isLoding: false, + isToast: true) { (response: FANetworkManager.Response) in + completer?(response.data) + } + + } + } diff --git a/Fableon/Object/Base/Request/FANetworkManager.swift b/Fableon/Object/Base/Request/FANetworkManager.swift index a0510a4..d65f2cb 100644 --- a/Fableon/Object/Base/Request/FANetworkManager.swift +++ b/Fableon/Object/Base/Request/FANetworkManager.swift @@ -70,6 +70,10 @@ class FANetworkManager { response.code = -1 completion?(response) } else { + if code == 402, isToast { + FAToast.show(text: "fableon_kick_out_login".localized) + } + self.requestUserToken { if FALogin.manager.token != nil { FALogin.manager.requestUserInfo(completer: nil) @@ -173,8 +177,10 @@ extension FANetworkManager { } private var headers: HTTPHeaders { + + let token = FALogin.manager.token?.token ?? "" - let dic = [ + var dic = [ "authorization" : token, "system-version" : UIDevice.current.systemVersion, "lang-key" : FALanguageManager.manager.currentLanguageKey, @@ -187,8 +193,11 @@ extension FANetworkManager { "idfa" : ASIdentifierManager.shared().advertisingIdentifier.uuidString, "device-id" : FADeviceIDManager.shared.id, //设备id "device-gaid" : UIDevice.current.identifierForVendor?.uuidString ?? "", - "product-prefix" : FAIapManager.IAPPrefix + "product-prefix" : FAIapManager.IAPPrefix, ] +#if DEBUG + dic["security"] = "false" +#endif return HTTPHeaders(dic) } } diff --git a/Fableon/Object/Base/WebView/FABaseWebViewController+Script.swift b/Fableon/Object/Base/WebView/FABaseWebViewController+Script.swift index f7d4150..8fce970 100644 --- a/Fableon/Object/Base/WebView/FABaseWebViewController+Script.swift +++ b/Fableon/Object/Base/WebView/FABaseWebViewController+Script.swift @@ -74,7 +74,7 @@ extension FABaseWebViewController { case kFAWebMessageAccountDeletionFinish: self.navigationController?.popToRootViewController(animated: true) - + NotificationCenter.default.post(name: FALogin.loginStatusChangeNotification, object: nil) default: break diff --git a/Fableon/Object/Class/Home/C/FAGenresListViewController.swift b/Fableon/Object/Class/Home/C/FAGenresListViewController.swift index 7d3457f..28c1fd3 100644 --- a/Fableon/Object/Class/Home/C/FAGenresListViewController.swift +++ b/Fableon/Object/Class/Home/C/FAGenresListViewController.swift @@ -30,12 +30,13 @@ class FAGenresListViewController: FAViewController { let collectionView = FACollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) collectionView.delegate = self collectionView.dataSource = self + collectionView.ly_emptyView = FAEmpty.fa_emptyView() collectionView.contentInset = .init(top: 20, left: 0, bottom: UIScreen.safeBottom + 10, right: 0) collectionView.register(UINib(nibName: "FAGenresListCell", bundle: nil), forCellWithReuseIdentifier: "cell") collectionView.fa_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in self?.handleHeaderRefresh(nil) } - collectionView.fa_addRefreshFooter(insetBottom: 0) { [weak self] in + collectionView.fa_addRefreshFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in self?.handleFooterRefresh(nil) } return collectionView diff --git a/Fableon/Object/Class/Home/C/FAGenresViewController.swift b/Fableon/Object/Class/Home/C/FAGenresViewController.swift index 4b09cec..d9f8914 100644 --- a/Fableon/Object/Class/Home/C/FAGenresViewController.swift +++ b/Fableon/Object/Class/Home/C/FAGenresViewController.swift @@ -31,6 +31,7 @@ class FAGenresViewController: FAViewController { let collectionView = FACollectionView(frame: .zero, collectionViewLayout: self.collectionViewLayout) collectionView.delegate = self collectionView.dataSource = self + collectionView.ly_emptyView = FAEmpty.fa_emptyView() collectionView.contentInset = .init(top: 24, left: 0, bottom: UIScreen.safeBottom + 10, right: 0) collectionView.register(UINib(nibName: "FAGenresCell", bundle: nil), forCellWithReuseIdentifier: "cell") return collectionView @@ -38,7 +39,7 @@ class FAGenresViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Genres".localized + self.title = "fableon_genres".localized fa_setupLayout() diff --git a/Fableon/Object/Class/Home/C/FAHomeViewController.swift b/Fableon/Object/Class/Home/C/FAHomeViewController.swift index 9370ec2..69be5a1 100644 --- a/Fableon/Object/Class/Home/C/FAHomeViewController.swift +++ b/Fableon/Object/Class/Home/C/FAHomeViewController.swift @@ -8,13 +8,21 @@ import UIKit import SwiftUI import SnapKit +import LYEmptyView class FAHomeViewController: FAViewController { private var viewModel = FAHomeViewModel() - + private lazy var notNetworkEmptyView: LYEmptyView = { + let view = FAEmpty.fa_notNetworkEmptyView { [weak self] in + self?.requestAllData(completer: nil) + self?.fa_setupLayout() + } + view.autoShowEmptyView = false + return view + }() private lazy var cvLayout: FAWaterfallFlowLayout = { let layout = FAWaterfallFlowLayout() @@ -80,6 +88,7 @@ class FAHomeViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: FANetworkMonitor.networkStatusDidChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(loginStatusChangeNotification), name: FALogin.loginStatusChangeNotification, object: nil) fa_setupLayout() requestAllData(completer: nil) @@ -107,12 +116,27 @@ class FAHomeViewController: FAViewController { if self.viewModel.dataArr.isEmpty, FANetworkMonitor.manager.isReachable == true { requestAllData(completer: nil) } + self.fa_setupLayout() + } + + @objc private func loginStatusChangeNotification() { + requestAllData(completer: nil) } } extension FAHomeViewController { private func fa_setupLayout() { + if FANetworkMonitor.manager.isReachable == false, collectionView.superview == nil { + view.ly_emptyView = notNetworkEmptyView + view.ly_showEmpty() + return + } + if collectionView.superview != nil { + return + } + view.ly_hideEmpty() + view.addSubview(titleView) view.addSubview(searchButton) view.addSubview(collectionView) @@ -182,7 +206,7 @@ extension FAHomeViewController: UICollectionViewDelegate, UICollectionViewDataSo func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { if kind == UICollectionView.elementKindSectionHeader { - let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FAHomeSectionTitleView", for: indexPath) + let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FAHomeSectionTitleView", for: indexPath) as! FAHomeSectionTitleView return view } return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "footer", for: indexPath) @@ -295,6 +319,8 @@ extension FAHomeViewController { if let playHistory = self.viewModel.playHistory { self.playHistoryView.model = playHistory self.playHistoryView.isHidden = false + } else { + self.playHistoryView.isHidden = true } } } diff --git a/Fableon/Object/Class/Home/C/FAPopularListViewController.swift b/Fableon/Object/Class/Home/C/FAPopularListViewController.swift index d3f27a9..d8c862b 100644 --- a/Fableon/Object/Class/Home/C/FAPopularListViewController.swift +++ b/Fableon/Object/Class/Home/C/FAPopularListViewController.swift @@ -29,6 +29,7 @@ class FAPopularListViewController: FAViewController { collectionView.delegate = self collectionView.dataSource = self collectionView.contentInset = .init(top: 20, left: 0, bottom: UIScreen.safeBottom + 10, right: 0) + collectionView.ly_emptyView = FAEmpty.fa_emptyView() collectionView.register(UINib(nibName: "FAGenresListCell", bundle: nil), forCellWithReuseIdentifier: "cell") collectionView.fa_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in self?.handleHeaderRefresh(nil) diff --git a/Fableon/Object/Class/Home/C/FARankingListViewController.swift b/Fableon/Object/Class/Home/C/FARankingListViewController.swift index 50d960f..1a8d254 100644 --- a/Fableon/Object/Class/Home/C/FARankingListViewController.swift +++ b/Fableon/Object/Class/Home/C/FARankingListViewController.swift @@ -36,6 +36,7 @@ class FARankingListViewController: FAViewController { collectionView.dataSource = self collectionView.showsVerticalScrollIndicator = false collectionView.showsHorizontalScrollIndicator = false + collectionView.ly_emptyView = FAEmpty.fa_emptyView() collectionView.contentInset = .init(top: 15, left: 0, bottom: UIScreen.safeBottom + 10, right: 0) collectionView.register(UINib(nibName: "FARankingListCell", bundle: nil), forCellWithReuseIdentifier: "cell") return collectionView @@ -43,7 +44,7 @@ class FARankingListViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Rankings".localized + self.title = "fableon_rabkings".localized fa_setupLayout() diff --git a/Fableon/Object/Class/Home/M/FACategoryModel.swift b/Fableon/Object/Class/Home/M/FACategoryModel.swift index 83ac296..17c4733 100644 --- a/Fableon/Object/Class/Home/M/FACategoryModel.swift +++ b/Fableon/Object/Class/Home/M/FACategoryModel.swift @@ -13,4 +13,10 @@ struct FACategoryModel: SmartCodable { var id: String? var category_name: String? var short_play_list: [FAShortPlayModel]? + + static func mappingForKey() -> [SmartKeyTransformer]? { + return [ + CodingKeys.category_name <--- ["category_name", "name"], + ] + } } diff --git a/Fableon/Object/Class/Home/M/FAHomeNewTransformer.swift b/Fableon/Object/Class/Home/M/FAHomeNewTransformer.swift new file mode 100644 index 0000000..512b894 --- /dev/null +++ b/Fableon/Object/Class/Home/M/FAHomeNewTransformer.swift @@ -0,0 +1,17 @@ +// +// FAHomeNewTransformer.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/11. +// + +import UIKit +import FSPagerView + +class FAHomeNewTransformer: FSPagerViewTransformer { + + + override func proposedInteritemSpacing() -> CGFloat { + return -50 + } +} diff --git a/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift b/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift index 259b9f1..473de9d 100644 --- a/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift +++ b/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift @@ -61,7 +61,7 @@ struct FAHomeMustSeeView: View { } HStack { - Text("selection".localized) + Text("fableon_selection".localized) .font(Font.font(size: 12, weight: .medium)) .foregroundStyle(textColor) .padding(.leading, 8) diff --git a/Fableon/Object/Class/Home/UI/FAHomeNewView.swift b/Fableon/Object/Class/Home/UI/FAHomeNewView.swift index c36809d..a4b81ac 100644 --- a/Fableon/Object/Class/Home/UI/FAHomeNewView.swift +++ b/Fableon/Object/Class/Home/UI/FAHomeNewView.swift @@ -14,7 +14,7 @@ struct FAHomeNewView: View { @ObservedObject var viewModel: FAHomeViewModel @State private var transformer: FSPagerViewTransformer = { - let transformer = FSPagerViewTransformer(type: .overlap) + let transformer = FAHomeNewTransformer(type: .overlap) transformer.minimumScale = 0.9 transformer.minimumAlpha = 1 return transformer diff --git a/Fableon/Object/Class/Home/V/FAGenresCell.swift b/Fableon/Object/Class/Home/V/FAGenresCell.swift index 7734823..4b5f65c 100644 --- a/Fableon/Object/Class/Home/V/FAGenresCell.swift +++ b/Fableon/Object/Class/Home/V/FAGenresCell.swift @@ -14,14 +14,22 @@ class FAGenresCell: UICollectionViewCell { var list = model?.short_play_list let firstModel = list?.removeFirst() - hotCountLabel.text = "\(firstModel?.watch_total ?? 0)" + let count = firstModel?.watch_total ?? 0 + var countStr = "\(count)" + if count > 1000 { + countStr = NSNumber(value: CGFloat(count) / 1000).toString(maximumFractionDigits: 1) + "k" + } + hotCountLabel.text = countStr + nameLabel.text = model?.category_name coverImageView.fa_setImage(firstModel?.image_url) list?.enumerated().forEach { let i = $0 - let imageView = smallImageViewArr[i] + let viewCount = smallImageViewArr.count + if i > viewCount { return } + let imageView = smallImageViewArr[viewCount - i - 1] imageView.fa_setImage($1.image_url) } } diff --git a/Fableon/Object/Class/Home/V/FAHomeBannerCell.swift b/Fableon/Object/Class/Home/V/FAHomeBannerCell.swift index f4c94ce..333ce0f 100644 --- a/Fableon/Object/Class/Home/V/FAHomeBannerCell.swift +++ b/Fableon/Object/Class/Home/V/FAHomeBannerCell.swift @@ -12,7 +12,11 @@ class FAHomeBannerCell: FSPagerViewCell { var model: FAShortPlayModel? { didSet { - coverImageView.fa_setImage(model?.horizontally_img) + if let image = model?.horizontally_img, image.count > 0 { + coverImageView.fa_setImage(image) + } else { + coverImageView.fa_setImage(model?.image_url) + } } } diff --git a/Fableon/Object/Class/Home/V/FAHomeBannerContentCell.swift b/Fableon/Object/Class/Home/V/FAHomeBannerContentCell.swift index 940f6c2..d8f6dd0 100644 --- a/Fableon/Object/Class/Home/V/FAHomeBannerContentCell.swift +++ b/Fableon/Object/Class/Home/V/FAHomeBannerContentCell.swift @@ -26,6 +26,7 @@ class FAHomeBannerContentCell: UICollectionViewCell { let view = FSPagerView() + view.automaticSlidingInterval = 5 view.itemSize = .init(width: 282, height: 146) view.transformer = transformer view.delegate = self diff --git a/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.swift b/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.swift index 570c361..1ad7001 100644 --- a/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.swift +++ b/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.swift @@ -9,9 +9,12 @@ import UIKit class FAHomeSectionTitleView: UICollectionReusableView { + + @IBOutlet weak var titleLabel: UILabel! + override func awakeFromNib() { super.awakeFromNib() - // Initialization code + self.titleLabel.text = "fableon_recommended_for_you".localized } } diff --git a/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.xib b/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.xib index 50796c9..c40d079 100644 --- a/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.xib +++ b/Fableon/Object/Class/Home/V/FAHomeSectionTitleView.xib @@ -1,9 +1,9 @@ - + - + @@ -11,7 +11,7 @@ - + @@ -27,6 +27,9 @@ + + + diff --git a/Fableon/Object/Class/Home/V/FARankingListCell.swift b/Fableon/Object/Class/Home/V/FARankingListCell.swift index b215904..271e464 100644 --- a/Fableon/Object/Class/Home/V/FARankingListCell.swift +++ b/Fableon/Object/Class/Home/V/FARankingListCell.swift @@ -14,7 +14,14 @@ class FARankingListCell: UICollectionViewCell { coverImageView.fa_setImage(model?.image_url) nameLabel.text = model?.name epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") - countLabel.text = "\(model?.watch_total ?? 0)" + + + let count = model?.watch_total ?? 0 + var countStr = "\(count)" + if count > 1000 { + countStr = NSNumber(value: CGFloat(count) / 1000).toString(maximumFractionDigits: 1) + "k" + } + countLabel.text = countStr } } diff --git a/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift b/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift index 3070c93..a1585b6 100644 --- a/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift +++ b/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift @@ -14,8 +14,14 @@ class FASearchRecommendCell: UICollectionViewCell { didSet { coverImageView.fa_setImage(model?.image_url) titleLabel.text = model?.name - countLabel.text = "\(model?.watch_total ?? 0)" epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") + + let count = model?.watch_total ?? 0 + var countStr = "\(count)" + if count > 1000 { + countStr = NSNumber(value: CGFloat(count) / 1000).toString(maximumFractionDigits: 1) + "k" + } + countLabel.text = countStr } } diff --git a/Fableon/Object/Class/Home/V/FASearchResultCell.swift b/Fableon/Object/Class/Home/V/FASearchResultCell.swift index 69f8a5e..16a63af 100644 --- a/Fableon/Object/Class/Home/V/FASearchResultCell.swift +++ b/Fableon/Object/Class/Home/V/FASearchResultCell.swift @@ -19,7 +19,7 @@ class FASearchResultCell: UICollectionViewCell { titleLabel.text = model?.name coverImageView.fa_setImage(model?.image_url) - if let category = model?.category?.first, !category.isEmpty { + if let category = model?.categoryList?.first?.category_name, !category.isEmpty { categoryView.isHidden = false categoryLabel.text = category } else { diff --git a/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift b/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift index f536dfa..b9296c9 100644 --- a/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift +++ b/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift @@ -41,10 +41,10 @@ class FAHomeViewModel: ObservableObject { $0.title = "fableon_popular".localized popularItem = $0 } else if $0.module_key == .week_ranking { - $0.title = "Rankings".localized + $0.title = "fableon_rabkings".localized rankingsItem = $0 } else if $0.module_key == .cagetory_recommand, genresItem == nil { - $0.title = "Genres".localized + $0.title = "fableon_genres".localized genresItem = $0 } else if $0.module_key == .new_recommand { $0.title = "fableon_new".localized @@ -109,6 +109,8 @@ class FAHomeViewModel: ObservableObject { guard let self = self else { return } if let model = listModel?.list?.first { self.playHistory = model + } else { + self.playHistory = nil } completer?() } diff --git a/Fableon/Object/Class/Me/C/FACoinPackViewController.swift b/Fableon/Object/Class/Me/C/FACoinPackViewController.swift index 867f9bc..766055a 100644 --- a/Fableon/Object/Class/Me/C/FACoinPackViewController.swift +++ b/Fableon/Object/Class/Me/C/FACoinPackViewController.swift @@ -101,6 +101,8 @@ class FACoinPackViewController: FAViewController { return label }() + private weak var recommandView: UIView? + private lazy var tipTextLabel: UILabel = { let att = NSMutableAttributedString(string: "coins_pack_tips".localized) att.yy_lineSpacing = 3 @@ -210,7 +212,34 @@ extension FACoinPackViewController { FAStoreAPI.requestReceiveCoinsPackCoins(id: id) { [weak self] finish in guard let self = self else { return } self.requestCoinsPackData() + if finish { + self.showVideoRecommand() + } } } + ///展示视频推荐 + private func showVideoRecommand() { + guard self.recommandView == nil else { return } + + FAAPI.requestDetailRecommendVideo { [weak self] list in + guard let self = self else { return } + guard let list = list else { return } + guard self.recommandView == nil else { return } + + let view = FADetailRecommendView() + view.dataArr = list + view.didSelectedVideo = { [weak self] model in + guard let self = self else { return } + let vc = FAPlayerDetailViewController() + vc.shortPlayId = model.short_play_id + self.navigationController?.pushViewController(vc, animated: true) + } + view.show(in: FATool.keyWindow) + self.recommandView = view + } + + + } + } diff --git a/Fableon/Object/Class/Me/C/FAFeedbackViewController.swift b/Fableon/Object/Class/Me/C/FAFeedbackViewController.swift index b9cc413..bb9552c 100644 --- a/Fableon/Object/Class/Me/C/FAFeedbackViewController.swift +++ b/Fableon/Object/Class/Me/C/FAFeedbackViewController.swift @@ -8,12 +8,60 @@ import UIKit class FAFeedbackViewController: FAAppWebViewController { + + + private lazy var rightButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "Frame 2085663258"), for: .normal) + button.addTarget(self, action: #selector(handleRightBarButton), for: .touchUpInside) + return button + }() + + private lazy var redView: UIView = { + let view = UIView() + view.backgroundColor = .FF_313_B + view.layer.cornerRadius = 8 + view.isHidden = true + return view + }() + + private lazy var redLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 12, weight: .bold) + label.textColor = .FFFFFF + return label + }() override func viewDidLoad() { self.webUrl = kFAFeedBackHomeWebUrl super.viewDidLoad() - self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "Frame 2085663258"), style: .plain, target: self, action: #selector(handleRightBarButton)) +// self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "Frame 2085663258"), style: .plain, target: self, action: #selector(handleRightBarButton)) + + self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: rightButton) + + + rightButton.addSubview(redView) + redView.addSubview(redLabel) + + redView.snp.makeConstraints { make in + make.height.equalTo(16) + make.width.greaterThanOrEqualTo(16) + make.top.equalToSuperview().offset(-8) + make.right.equalToSuperview().offset(8) + } + + redLabel.snp.makeConstraints { make in + make.center.equalToSuperview() +// make.left.equalToSuperview().offset(5) + make.left.greaterThanOrEqualToSuperview().offset(3) + } + + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.requestRedCount() } @@ -23,7 +71,23 @@ class FAFeedbackViewController: FAAppWebViewController { vc.webUrl = kFAFeedBackListWebUrl self.navigationController?.pushViewController(vc, animated: true) - } } + +extension FAFeedbackViewController { + + private func requestRedCount() { + FAAPI.requestFeedbackRedCount { [weak self] model in + guard let self = self else { return } + if let count = model?.feedback_notice_num, count > 0 { + self.redView.isHidden = false + self.redLabel.text = "\(count)" + } else { + self.redView.isHidden = true + } + } + + } + +} diff --git a/Fableon/Object/Class/Me/C/FAMeListViewController.swift b/Fableon/Object/Class/Me/C/FAMeListViewController.swift index 410a2c4..3531f8c 100644 --- a/Fableon/Object/Class/Me/C/FAMeListViewController.swift +++ b/Fableon/Object/Class/Me/C/FAMeListViewController.swift @@ -12,22 +12,7 @@ class FAMeListViewController: FAViewController, JXPagingViewListViewDelegate { var scrollCallback: ((_ : UIScrollView) -> Void)? - private lazy var dataArr: [FAMeItemModel] = { - let arr = [ - FAMeItemModel(type: .language, name: "fableon_language".localized, icon: UIImage(named: "icon_language")), - FAMeItemModel(type: .feedback, name: "fableon_feedback".localized, icon: UIImage(named: "icon_feedback")), - FAMeItemModel(type: .about, name: "fableon_about_us".localized, icon: UIImage(named: "icon_about")), - - FAMeItemModel(type: .privacyPolicy, name: "fableon_privacy_policy".localized, icon: UIImage(named: "icon_privacy")), - FAMeItemModel(type: .userAgreement, name: "fableon_user_agreement".localized, icon: UIImage(named: "icon_user")), -// FAMeItemModel(type: .visitWebsite, name: "fableon_visit_website".localized, icon: UIImage(named: "icon_visit")), - - FAMeItemModel(type: .setting, name: "fableon_settings".localized, icon: UIImage(named: "icon_setting")) - ] - return arr - }() - - + private lazy var dataArr: [FAMeItemModel] = [] private lazy var tableViewHeaderView: FAMeTableViewHeaderView = { let view = FAMeTableViewHeaderView(frame: .init(x: 0, y: 0, width: UIScreen.width, height: 124)) @@ -49,7 +34,6 @@ class FAMeListViewController: FAViewController, JXPagingViewListViewDelegate { tableView.rowHeight = 56 tableView.separatorInset = .init(top: 0, left: 32, bottom: 0, right: 32) tableView.register(UINib(nibName: "FAMeCell", bundle: nil), forCellReuseIdentifier: "cell") -// tableView.addObserver(self, forKeyPath: "contentSize", context: nil) return tableView }() @@ -61,7 +45,7 @@ class FAMeListViewController: FAViewController, JXPagingViewListViewDelegate { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(userInfoUpdateNotification), name: FALogin.userInfoUpdateNotification, object: nil) - + setDataArr() self.bgView.isHidden = true fa_setupLayout() @@ -70,6 +54,7 @@ class FAMeListViewController: FAViewController, JXPagingViewListViewDelegate { @objc private func userInfoUpdateNotification() { tableViewHeaderView.userInfo = FALogin.manager.userInfo + setDataArr() } func listScrollView() -> UIScrollView { @@ -159,3 +144,27 @@ extension FAMeListViewController: UITableViewDelegate, UITableViewDataSource { } } +extension FAMeListViewController { + + private func setDataArr() { + + var arr = [ + FAMeItemModel(type: .language, name: "fableon_language".localized, icon: UIImage(named: "icon_language")), + FAMeItemModel(type: .feedback, name: "fableon_feedback".localized, icon: UIImage(named: "icon_feedback")), + FAMeItemModel(type: .about, name: "fableon_about_us".localized, icon: UIImage(named: "icon_about")), + + FAMeItemModel(type: .privacyPolicy, name: "fableon_privacy_policy".localized, icon: UIImage(named: "icon_privacy")), + FAMeItemModel(type: .userAgreement, name: "fableon_user_agreement".localized, icon: UIImage(named: "icon_user")), + ] + + if FALogin.manager.isLogin { + arr.append( + FAMeItemModel(type: .setting, name: "fableon_settings".localized, icon: UIImage(named: "icon_setting")) + ) + } + self.dataArr = arr + self.tableView.reloadData() + } + +} + diff --git a/Fableon/Object/Class/Me/M/FAFeedbackCountModel.swift b/Fableon/Object/Class/Me/M/FAFeedbackCountModel.swift new file mode 100644 index 0000000..29d3b75 --- /dev/null +++ b/Fableon/Object/Class/Me/M/FAFeedbackCountModel.swift @@ -0,0 +1,15 @@ +// +// FAFeedbackCountModel.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/11. +// + +import UIKit +import SmartCodable + +struct FAFeedbackCountModel: SmartCodable { + + var feedback_notice_num: Int? + +} diff --git a/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift b/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift index 97802fa..073c7d0 100644 --- a/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift +++ b/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift @@ -104,7 +104,7 @@ class FACoinPackHeaderView: UIView { .foregroundColor : UIColor.FFFFFF ])) - let countAtt = AttributedString(" \(0)".localized, attributes: AttributeContainer([ + let countAtt = AttributedString(" \(self.model?.receive_coins ?? 0)".localized, attributes: AttributeContainer([ .font : UIFont.font(ofSize: 14, weight: .bold), .foregroundColor : UIColor.FFFFFF ])) diff --git a/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift b/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift index 9051045..72a3221 100644 --- a/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift +++ b/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift @@ -24,7 +24,8 @@ class FACoinsPackClaimListCell: UICollectionViewCell { titleAtt.yy_color = .FFFFFF titleAtt.yy_font = .font(ofSize: 14, weight: .bold) - let dayAtt = NSMutableAttributedString(string: " (Day \(model?.day_text ?? ""))") + let day = "fableon_d".localized + 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) diff --git a/Fableon/Object/Class/Me/V/FAMeHeaderView.swift b/Fableon/Object/Class/Me/V/FAMeHeaderView.swift index edfdf26..f2cd5a1 100644 --- a/Fableon/Object/Class/Me/V/FAMeHeaderView.swift +++ b/Fableon/Object/Class/Me/V/FAMeHeaderView.swift @@ -97,6 +97,24 @@ class FAMeHeaderView: UIView { return button }() + private lazy var topUpButton: UIButton = { + let button = FAGradientButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in + guard let self = self else { return } + let vc = FAWalletViewController() + self.viewController?.navigationController?.pushViewController(vc, animated: 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.layer.cornerRadius = 18 + button.layer.masksToBounds = true + button.setTitle("GO", for: .normal) + button.setTitleColor(._000000, for: .normal) + button.titleLabel?.font = .font(ofSize: 14, weight: .semibold) + return button + }() + override init(frame: CGRect) { super.init(frame: frame) @@ -118,6 +136,7 @@ extension FAMeHeaderView { addSubview(bonusCoinsView) addSubview(coinPackButton) addSubview(loginButton) + addSubview(topUpButton) avatarImageView.snp.makeConstraints { make in make.left.equalToSuperview().offset(16) @@ -159,6 +178,13 @@ extension FAMeHeaderView { make.width.equalTo(76) make.height.equalTo(28) } + + topUpButton.snp.makeConstraints { make in + make.centerY.equalTo(coinsView) + make.right.equalToSuperview().offset(-16) + make.width.equalTo(84) + make.height.equalTo(36) + } } } diff --git a/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift b/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift index 9123892..17a0899 100644 --- a/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift +++ b/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift @@ -11,18 +11,18 @@ class FAMeTableViewHeaderView: UIView { var userInfo: FAUserInfo? { didSet { + subtitleLabel.text = "vip_tip_01".localized if userInfo?.is_vip == true { subscribeView.isHidden = true expirationView.isHidden = false vipImageView.image = UIImage(named: "vip_image_02") titleLabel.text = "fableon_activated".localized - subtitleLabel.text = "vip_tip_01".localized } else { subscribeView.isHidden = false expirationView.isHidden = true vipImageView.image = UIImage(named: "vip_image_01") titleLabel.text = "fableon_not_activated".localized - subtitleLabel.text = "vip_tip_02".localized +// subtitleLabel.text = "vip_tip_02".localized } diff --git a/Fableon/Object/Class/Me/V/FASettingFooterView.swift b/Fableon/Object/Class/Me/V/FASettingFooterView.swift index b603748..134c404 100644 --- a/Fableon/Object/Class/Me/V/FASettingFooterView.swift +++ b/Fableon/Object/Class/Me/V/FASettingFooterView.swift @@ -49,7 +49,10 @@ class FASettingFooterView: UIView { let view = FALogoutAlert() view.clickHighlightButton = { - FALogin.manager.logout(completer: nil) + FALogin.manager.logout { [weak self] finish in + guard let self = self else { return } + self.viewController?.navigationController?.popToRootViewController(animated: true) + } } view.show() } diff --git a/Fableon/Object/Class/MyShort/C/FACollectViewController.swift b/Fableon/Object/Class/MyShort/C/FACollectViewController.swift index 659b38a..3109cff 100644 --- a/Fableon/Object/Class/MyShort/C/FACollectViewController.swift +++ b/Fableon/Object/Class/MyShort/C/FACollectViewController.swift @@ -21,6 +21,8 @@ class FACollectViewController: FAViewController { } } + private var needUpdate = false + private lazy var collectionViewLayout: UICollectionViewFlowLayout = { let width = floor((UIScreen.width - 16 - 32) / 3) @@ -67,11 +69,17 @@ class FACollectViewController: FAViewController { return item }() + + deinit { + NotificationCenter.default.removeObserver(self) + } + override func viewDidLoad() { super.viewDidLoad() self.edgesForExtendedLayout = .top self.title = "fableon_collect".localized - + NotificationCenter.default.addObserver(self, selector: #selector(loginStatusChangeNotification), name: FALogin.loginStatusChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(updateShortCollectStateNotification), name: FAAPI.updateShortCollectStateNotification, object: nil) self.navigationItem.rightBarButtonItems = [historyButton, spaceButton, editBarButton] @@ -87,6 +95,14 @@ class FACollectViewController: FAViewController { self.navigationController?.setNavigationBarHidden(false, animated: true) } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + if needUpdate { + needUpdate = false + requestDataArr(page: 1, completer: nil) + } + } + override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) self.fa_isEditing = false @@ -138,6 +154,13 @@ class FACollectViewController: FAViewController { } } + @objc private func loginStatusChangeNotification() { + requestDataArr(page: 1, completer: nil) + } + + @objc private func updateShortCollectStateNotification() { + needUpdate = true + } } extension FACollectViewController { diff --git a/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift b/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift index cc5498b..7d86f24 100644 --- a/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift +++ b/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift @@ -31,7 +31,7 @@ class FAHistoryViewController: FAViewController { guard let self = self else { return } self.handleHeaderRefresh(nil) } - collectionView.fa_addRefreshFooter(insetBottom: 0) { [weak self] in + collectionView.fa_addRefreshFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in self?.handleFooterRefresh(nil) } return collectionView diff --git a/Fableon/Object/Class/Player/M/FAShortPlayModel.swift b/Fableon/Object/Class/Player/M/FAShortPlayModel.swift index db6af31..a95f02a 100644 --- a/Fableon/Object/Class/Player/M/FAShortPlayModel.swift +++ b/Fableon/Object/Class/Player/M/FAShortPlayModel.swift @@ -22,6 +22,7 @@ class FAShortPlayModel: NSObject, Identifiable, SmartCodable { var episode_total: Int? var horizontally_img: String? var category: [String]? + var categoryList: [FACategoryModel]? var short_play_id: String? var short_play_video_id: String? var video_info: FAVideoInfoModel? diff --git a/Fableon/Object/Class/Player/V/FADetailRecommendCell.swift b/Fableon/Object/Class/Player/V/FADetailRecommendCell.swift index 4eed2eb..00224c8 100644 --- a/Fableon/Object/Class/Player/V/FADetailRecommendCell.swift +++ b/Fableon/Object/Class/Player/V/FADetailRecommendCell.swift @@ -21,6 +21,7 @@ class FADetailRecommendCell: FSPagerViewCell { private lazy var player: JXPlayer = { let player = JXPlayer(controlView: nil) player.playerView = self.playerView + player.isLoop = true return player }() diff --git a/Fableon/Object/Class/Player/V/FADetailRecommendView.swift b/Fableon/Object/Class/Player/V/FADetailRecommendView.swift index e2f841c..a281cfe 100644 --- a/Fableon/Object/Class/Player/V/FADetailRecommendView.swift +++ b/Fableon/Object/Class/Player/V/FADetailRecommendView.swift @@ -16,6 +16,7 @@ class FADetailRecommendView: FABaseAlert { var dataArr: [FAShortPlayModel] = [] { didSet { self.pagerView.reloadData() + pageControl.numberOfPages = dataArr.count DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in self?.updateCurrentData() @@ -68,6 +69,15 @@ class FADetailRecommendView: FABaseAlert { return view }() + private lazy var pageControl: UIPageControl = { + let view = UIPageControl() + view.isUserInteractionEnabled = false + view.pageIndicatorTintColor = .FFFFFF.withAlphaComponent(0.6) + view.currentPageIndicatorTintColor = .FFFFFF + view.numberOfPages = 0 + return view + }() + override init(frame: CGRect) { super.init(frame: frame) contentWidth = UIScreen.width @@ -96,6 +106,7 @@ class FADetailRecommendView: FABaseAlert { guard let cell = self.pagerView.cellForItem(at: self.pagerView.currentIndex) as? FADetailRecommendCell else { return } self.currentCell = cell + self.pageControl.currentPage = self.pagerView.currentIndex // let model = cell.model // self.videoNameLabel.text = model?.name } @@ -109,6 +120,7 @@ extension FADetailRecommendView { contentView.addSubview(bgView) contentView.addSubview(cancelButton) bgView.addSubview(pagerView) + bgView.addSubview(pageControl) titleLabel.snp.makeConstraints { make in make.top.equalToSuperview() @@ -131,6 +143,11 @@ extension FADetailRecommendView { make.height.equalTo(267) make.center.equalToSuperview() } + + pageControl.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(pagerView.snp.bottom).offset(10) + } } } @@ -158,3 +175,13 @@ extension FADetailRecommendView: FSPagerViewDelegate, FSPagerViewDataSource { } } + +extension FADetailRecommendView { + + class PageControl: UIPageControl{ + override func size(forNumberOfPages pageCount: Int) -> CGSize { + return .init(width: 4, height: 4) + } + } + +} diff --git a/Fableon/Object/Class/Player/V/FAEpSelectorView.swift b/Fableon/Object/Class/Player/V/FAEpSelectorView.swift index 58f960a..752f479 100644 --- a/Fableon/Object/Class/Player/V/FAEpSelectorView.swift +++ b/Fableon/Object/Class/Player/V/FAEpSelectorView.swift @@ -192,9 +192,8 @@ extension FAEpSelectorView: UICollectionViewDelegate, UICollectionViewDataSource return } - self.didSelected?(indexPath.row) - self.dismiss(animated: true) { - + self.dismiss(animated: true) { [weak self] in + self?.didSelected?(indexPath.row) } } diff --git a/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift b/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift index da0ab27..31ae57e 100644 --- a/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift +++ b/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift @@ -71,7 +71,7 @@ class FAOldVideoRechargeView: FAPanModalContentView { private lazy var scrollView: FAScrollView = { let scrollView = FAScrollView() - scrollView.clipsToBounds = false +// scrollView.clipsToBounds = false return scrollView }() @@ -148,7 +148,7 @@ class FAOldVideoRechargeView: FAPanModalContentView { let label = UILabel() label.font = .font(ofSize: 12, weight: .medium) label.textColor = .FFFFFF - label.text = "store_tips_title".localized + label.text = "fableon_tips".localized return label }() diff --git a/Fableon/Object/Class/Player/V/FAPlayerDetailCell.swift b/Fableon/Object/Class/Player/V/FAPlayerDetailCell.swift index 903a2e1..695f529 100644 --- a/Fableon/Object/Class/Player/V/FAPlayerDetailCell.swift +++ b/Fableon/Object/Class/Player/V/FAPlayerDetailCell.swift @@ -32,6 +32,8 @@ class FAPlayerDetailCell: JXPlayerListCell { didSet { let controlView = self.controlView as? FAPlayerDetailControlView controlView?.shortModel = shortModel + + self.player.coverImageView?.fa_setImage(shortModel?.image_url) } } diff --git a/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift b/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift index ba84531..5b551db 100644 --- a/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift +++ b/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift @@ -58,6 +58,12 @@ class FAPlayerDetailControlView: JXPlayerListControlView { } } + override var isLoading: Bool { + didSet { + progressView.isLoading = isLoading + } + } + private lazy var epButton: UIHostingController = { let view = FAPlayerEpUIButton() let hc = UIHostingController(rootView: view) @@ -126,7 +132,15 @@ class FAPlayerDetailControlView: JXPlayerListControlView { let videoId = (self.model as? FAVideoInfoModel)?.short_play_video_id let isCollect = !(self.shortModel?.is_collect ?? false) - FAAPI.requestShortCollect(isCollect: isCollect, shortPlayId: shortPlayId, videoId: videoId, success: nil) + if isCollect { + FAAPI.requestShortCollect(isCollect: isCollect, shortPlayId: shortPlayId, videoId: videoId, success: nil) + } else { + let alert = FARemoveCollectAlert() + alert.clickHighlightButton = { + FAAPI.requestShortCollect(isCollect: isCollect, shortPlayId: shortPlayId, videoId: videoId, success: nil) + } + alert.show() + } }), for: .touchUpInside) diff --git a/Fableon/Object/Class/Player/V/FAPlayerProgressView.swift b/Fableon/Object/Class/Player/V/FAPlayerProgressView.swift index c3cb456..ef6a4e9 100644 --- a/Fableon/Object/Class/Player/V/FAPlayerProgressView.swift +++ b/Fableon/Object/Class/Player/V/FAPlayerProgressView.swift @@ -152,7 +152,7 @@ class FAPlayerProgressView: UIView { if self.isPaning { progress = self.panProgress } - + let currentProgressWidth = progressWidth * progress ///绘制进度 let progressPath = UIBezierPath(roundedRect: CGRect(x: progressX, y: progressY, width: progressWidth, height: lineWidth), cornerRadius: lineWidth / 2) @@ -165,6 +165,12 @@ class FAPlayerProgressView: UIView { context.addPath(currentPath.cgPath) context.setFillColor(currentProgress.cgColor) context.fillPath() + + ///绘制一个点 + let path = UIBezierPath(arcCenter: .init(x: currentProgressWidth + progressX, y: progressY + lineWidth / 2), radius: 3, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true) + context.addPath(path.cgPath) + context.setFillColor(currentProgress.cgColor) + context.fillPath() } diff --git a/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift b/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift index 370cdcb..ca7fb83 100644 --- a/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift +++ b/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift @@ -78,13 +78,13 @@ class FAPlayerDetailViewController: JXPlayerListViewController { self.viewModel.currentCell?.pause() } - override var previousVideoUrl: String? { - return self.fa_viewModel.previousEpisode?.video_url - } - - override var nextVideoUrl: String? { - return self.fa_viewModel.nextEpisode?.video_url - } +// override var previousVideoUrl: String? { +// return self.fa_viewModel.previousEpisode?.video_url +// } +// +// override var nextVideoUrl: String? { +// return self.fa_viewModel.nextEpisode?.video_url +// } override func play() { let videoInfo = self.viewModel.currentCell?.model as? FAVideoInfoModel @@ -92,6 +92,11 @@ class FAPlayerDetailViewController: JXPlayerListViewController { if videoInfo?.is_lock != true { super.play() FAAPI.requestCreatePlayHistory(videoId: videoInfo?.short_play_video_id, shortPlayId: videoInfo?.short_play_id) + + if let cell = viewModel.currentCell as? FAPlayerDetailCell, let model = cell.shortModel { + FATool.widgetLiveActivityModel = model + FATool.widgetLiveActivityModel?.current_episode = videoInfo?.episode + } return } self.pause() @@ -114,7 +119,7 @@ class FAPlayerDetailViewController: JXPlayerListViewController { @objc private func handleBackButton() { self.pause() - if !self.fa_viewModel.recommandDataArr.isEmpty { + if !self.fa_viewModel.recommandDataArr.isEmpty, self.fa_viewModel.isShowRecommand { let view = FADetailRecommendView() view.dataArr = self.fa_viewModel.recommandDataArr view.clickCloseButton = { [weak self] in @@ -126,6 +131,8 @@ class FAPlayerDetailViewController: JXPlayerListViewController { self.requestDetailList() } view.show(in: FATool.keyWindow) + } else { + self.handleNavigationBack() } // self.handleNavigationBack() diff --git a/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift b/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift index 78f8337..74fd689 100644 --- a/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift +++ b/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift @@ -7,6 +7,7 @@ import SwiftUI import JXPlayer +import YYText //@MainActor class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject { @@ -14,6 +15,9 @@ class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject { private(set) var dataArr: [FAShortDetailModel] = [] private(set) var recommandDataArr: [FAShortPlayModel] = [] + ///是否展示推荐数据 + private(set) var isShowRecommand = false + private var recommandTimer: Timer? var shortPlayId: String = "" @@ -43,6 +47,11 @@ class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject { func requestDetailData(indexPath: IndexPath? = nil, completer: ((_ code: Int) -> Void)?) { + isShowRecommand = false + recommandTimer?.invalidate() + recommandTimer = nil + recommandTimer = Timer.scheduledTimer(timeInterval: 6, target: YYTextWeakProxy(target: self), selector: #selector(handleRecommandTimer), userInfo: nil, repeats: false) + FAAPI.requestShortDetailData(shortPlayId: shortPlayId) { [weak self] model, code, msg in guard let self = self else { return } if let model = model { @@ -99,6 +108,18 @@ class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject { FAAPI.requestUploadPlayTime(shortPlayId: shortPlayId, videoId: videoId, seconds: Int(time) * 1000) } + override func playFinish(player: any JXPlayerCell) { + super.playFinish(player: player) + + let videoInfo = self.currentCell?.model as? FAVideoInfoModel + guard let shortPlayId = videoInfo?.short_play_id, let videoId = videoInfo?.short_play_video_id else { return } + FAAPI.requestUploadPlayTime(shortPlayId: shortPlayId, videoId: videoId, seconds: 0) + } + + @objc private func handleRecommandTimer() { + self.isShowRecommand = true + } + } extension FAShortDetailViewModel { @@ -119,6 +140,7 @@ extension FAShortDetailViewModel { func handleUnlockVideo() { unlockVideo { [weak self] finish in if finish { + FAToast.show(text: "fableo_success".localized) self?.playerListVC?.reloadData { self?.playerListVC?.play() } @@ -166,6 +188,10 @@ extension FAShortDetailViewModel { } private func _openOldRechargeView(_ model: FAPayDateModel, _ videoInfo: FAVideoInfoModel) { + FAStatAPI.requestEventStat(orderCode: nil, shortPlayId: videoInfo.short_play_id, videoId: videoInfo.short_play_video_id, eventKey: .payTemplateDialog, errorMsg: nil, otherParamenters: [ + "event_name" : "pay open" + ]) + let view = FAOldVideoRechargeView() view.model = model view.videoInfo = videoInfo diff --git a/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift b/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift index ed059bd..0baf1c4 100644 --- a/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift +++ b/Fableon/Object/Class/Recommend/C/FARecommendViewController.swift @@ -7,6 +7,7 @@ import UIKit import JXPlayer +import LYEmptyView class FARecommendViewController: JXPlayerListViewController { @@ -21,16 +22,38 @@ class FARecommendViewController: JXPlayerListViewController { var fa_viewModel: FARecommendViewModel { return self.viewModel as! FARecommendViewModel } + + private lazy var notNetworkEmptyView: LYEmptyView = { + let view = FAEmpty.fa_notNetworkEmptyView { [weak self] in + self?.fa_viewModel.requestDataArr(page: 1) + self?.fa_setupLayout() + } + view.autoShowEmptyView = false + return view + }() + + deinit { + NotificationCenter.default.removeObserver(self) + } override func viewDidLoad() { super.viewDidLoad() + NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: FANetworkMonitor.networkStatusDidChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(loginStatusChangeNotification), name: FALogin.loginStatusChangeNotification, object: nil) self.register(FARecommendPlayerCell.self, forCellWithReuseIdentifier: "cell") + self.collectionView.fa_addRefreshHeader { [weak self] in + self?.fa_viewModel.requestDataArr(page: 1) { + self?.collectionView.fa_endHeaderRefreshing() + } + } + self.collectionView.isHidden = true self.delegate = self self.dataSource = self self.fa_viewModel.requestDataArr(page: 1) + fa_setupLayout() } override func viewWillAppear(_ animated: Bool) { @@ -43,12 +66,39 @@ class FARecommendViewController: JXPlayerListViewController { self.viewModel.currentCell?.pause() } - override var previousVideoUrl: String? { - return self.fa_viewModel.previousEpisode?.video_url +// override var previousVideoUrl: String? { +// return self.fa_viewModel.previousEpisode?.video_url +// } +// +// override var nextVideoUrl: String? { +// return self.fa_viewModel.nextEpisode?.video_url +// } + + @objc private func loginStatusChangeNotification() { + self.fa_viewModel.requestDataArr(page: 1) } - override var nextVideoUrl: String? { - return self.fa_viewModel.nextEpisode?.video_url + @objc private func networkStatusDidChangeNotification() { + if FANetworkMonitor.manager.isReachable == true, self.fa_viewModel.dataArr.isEmpty { + self.fa_viewModel.requestDataArr(page: 1) + } + fa_setupLayout() + } +} + +extension FARecommendViewController { + + private func fa_setupLayout() { + if FANetworkMonitor.manager.isReachable == false, self.collectionView.isHidden { + view.ly_emptyView = notNetworkEmptyView + view.ly_showEmpty() + return + } + if !self.collectionView.isHidden { + return + } + view.ly_hideEmpty() + self.collectionView.isHidden = false } } @@ -69,5 +119,7 @@ extension FARecommendViewController: JXPlayerListViewControllerDataSource { //MARK: JXPlayerListViewControllerDelegate extension FARecommendViewController: JXPlayerListViewControllerDelegate { - + func jx_playerViewControllerLoadMoreData(playerViewController: JXPlayerListViewController) { + self.fa_viewModel.requestDataArr(page: self.fa_viewModel.page + 1) + } } diff --git a/Fableon/Object/Class/Recommend/V/FARecommendPlayerCell.swift b/Fableon/Object/Class/Recommend/V/FARecommendPlayerCell.swift index 6db6ff5..086c526 100644 --- a/Fableon/Object/Class/Recommend/V/FARecommendPlayerCell.swift +++ b/Fableon/Object/Class/Recommend/V/FARecommendPlayerCell.swift @@ -21,6 +21,7 @@ class FARecommendPlayerCell: JXPlayerListCell { let videoInfo = model?.video_info self.player.setPlayUrl(url: videoInfo?.video_url ?? "") + self.player.coverImageView?.fa_setImage(model?.image_url) } } diff --git a/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift b/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift index 5a8084d..8e71af8 100644 --- a/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift +++ b/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift @@ -57,12 +57,12 @@ class FARecommendPlayerControlView: JXPlayerListControlView { } } - private lazy var epButton: UIHostingController = { - let view = FAPlayerEpUIButton() - let hc = UIHostingController(rootView: view) - hc.view.backgroundColor = .clear - return hc - }() +// private lazy var epButton: UIHostingController = { +// let view = FAPlayerEpUIButton() +// let hc = UIHostingController(rootView: view) +// hc.view.backgroundColor = .clear +// return hc +// }() private lazy var progressView: FAPlayerProgressView = { let view = FAPlayerProgressView() @@ -79,6 +79,9 @@ class FARecommendPlayerControlView: JXPlayerListControlView { label.font = .font(ofSize: 12, weight: .regular); label.textColor = UIColor(named: .color_FFFFFF)!.withAlphaComponent(0.8) label.numberOfLines = 2 + label.isUserInteractionEnabled = true + let tap = UITapGestureRecognizer(target: self, action: #selector(handleEp)) + label.addGestureRecognizer(tap) return label }() @@ -125,7 +128,15 @@ class FARecommendPlayerControlView: JXPlayerListControlView { let videoId = (self.model as? FAVideoInfoModel)?.short_play_video_id let isCollect = !(self.shortModel?.is_collect ?? false) - FAAPI.requestShortCollect(isCollect: isCollect, shortPlayId: shortPlayId, videoId: videoId, success: nil) + if isCollect { + FAAPI.requestShortCollect(isCollect: isCollect, shortPlayId: shortPlayId, videoId: videoId, success: nil) + } else { + let alert = FARemoveCollectAlert() + alert.clickHighlightButton = { + FAAPI.requestShortCollect(isCollect: isCollect, shortPlayId: shortPlayId, videoId: videoId, success: nil) + } + alert.show() + } }), for: .touchUpInside) @@ -154,17 +165,20 @@ class FARecommendPlayerControlView: JXPlayerListControlView { } private func updateEp() { -// let model = self.model as? FAVideoInfoModel - let model = self.model as? FAShortPlayModel - let videoInfo = model?.video_info - - - let text = "fableon_episode_set".localizedReplace(text: videoInfo?.episode ?? "") + "/" + "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") - var view = FAPlayerEpUIButton(text: text) - view.clickHandle = { [weak self] in - self?.fa_viewModel?.pushPlayerDetail(self?.shortModel) - } - epButton.rootView = view +// let model = self.model as? FAShortPlayModel +// let videoInfo = model?.video_info +// +// +// let text = "fableon_episode_set".localizedReplace(text: videoInfo?.episode ?? "") + "/" + "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") +// var view = FAPlayerEpUIButton(text: text) +// view.clickHandle = { [weak self] in +// self?.fa_viewModel?.pushPlayerDetail(self?.shortModel) +// } +// epButton.rootView = view + } + + @objc private func handleEp() { + self.fa_viewModel?.pushPlayerDetail(self.shortModel) } private func updateProgress() { @@ -191,7 +205,7 @@ extension FARecommendPlayerControlView { private func fa_setupLayout() { - addSubview(epButton.view) +// addSubview(epButton.view) addSubview(progressView) addSubview(textLabel) addSubview(shortNameLabel) @@ -199,16 +213,17 @@ extension FARecommendPlayerControlView { addSubview(collectButton) - epButton.view.snp.makeConstraints { make in - make.left.equalToSuperview().offset(16) - make.centerX.equalToSuperview() - make.bottom.equalToSuperview().offset(-10) - } +// epButton.view.snp.makeConstraints { make in +// make.left.equalToSuperview().offset(16) +// make.centerX.equalToSuperview() +// make.bottom.equalToSuperview().offset(-10) +// } progressView.snp.makeConstraints { make in make.left.equalToSuperview() make.centerX.equalToSuperview() - make.bottom.equalTo(epButton.view.snp.top).offset(-8) +// make.bottom.equalTo(epButton.view.snp.top).offset(-8) + make.bottom.equalToSuperview().offset(-1) } textLabel.snp.makeConstraints { make in diff --git a/Fableon/Object/Class/Recommend/VM/FARecommendViewModel.swift b/Fableon/Object/Class/Recommend/VM/FARecommendViewModel.swift index 29de1c8..78736a1 100644 --- a/Fableon/Object/Class/Recommend/VM/FARecommendViewModel.swift +++ b/Fableon/Object/Class/Recommend/VM/FARecommendViewModel.swift @@ -11,7 +11,7 @@ import JXPlayer class FARecommendViewModel: JXPlayerListViewModel { private(set) var dataArr: [FAShortPlayModel] = [] - + private(set) lazy var page = 1 var previousEpisode: FAVideoInfoModel? { @@ -65,6 +65,7 @@ extension FARecommendViewModel { FAAPI.requestRecommendVideo(page: page) { [weak self] listModel in guard let self = self else { return } if let listModel = listModel, let list = listModel.list { + self.page = page if page == 1 { self.playerListVC?.clearData() self.dataArr = list diff --git a/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift b/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift index 895c2d9..9a04899 100644 --- a/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift +++ b/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift @@ -25,7 +25,7 @@ class FACoinRecordViewController: FAViewController { tableView.fa_addRefreshHeader(insetTop: tableView.contentInset.top) { [weak self] in self?.handleHeaderRefresh(nil) } - tableView.fa_addRefreshFooter(insetBottom: 0) { [weak self] in + tableView.fa_addRefreshFooter(insetBottom: tableView.contentInset.bottom) { [weak self] in self?.handleFooterRefresh(nil) } return tableView @@ -65,11 +65,7 @@ extension FACoinRecordViewController: UITableViewDelegate, UITableViewDataSource func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let model = self.dataArr[indexPath.row] let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FAOrderRecordCell - if model.type == "send" { - cell.titleLabel.text = "fableo_bonus_coins".localized - } else { - cell.titleLabel.text = "fableo_recharge_coins".localized - } + cell.titleLabel.text = model.type cell.dateLabel.text = model.created_at cell.countLabel.text = "+\(model.value ?? "0")" return cell diff --git a/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift b/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift index 7bf4a35..1d19a82 100644 --- a/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift +++ b/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift @@ -25,7 +25,7 @@ class FAConsumptionRecordsViewController: FAViewController { tableView.fa_addRefreshHeader(insetTop: tableView.contentInset.top) { [weak self] in self?.handleHeaderRefresh(nil) } - tableView.fa_addRefreshFooter(insetBottom: 0) { [weak self] in + tableView.fa_addRefreshFooter(insetBottom: tableView.contentInset.bottom) { [weak self] in self?.handleFooterRefresh(nil) } return tableView diff --git a/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift b/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift index 89991fa..6edd377 100644 --- a/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift +++ b/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift @@ -25,7 +25,7 @@ class FARewardCoinsViewController: FAViewController { tableView.fa_addRefreshHeader(insetTop: tableView.contentInset.top) { [weak self] in self?.handleHeaderRefresh(nil) } - tableView.fa_addRefreshFooter(insetBottom: 0) { [weak self] in + tableView.fa_addRefreshFooter(insetBottom: tableView.contentInset.bottom) { [weak self] in self?.handleFooterRefresh(nil) } return tableView diff --git a/Fableon/Object/Class/Store/C/FAStoreViewController.swift b/Fableon/Object/Class/Store/C/FAStoreViewController.swift index cfa9e16..0227aca 100644 --- a/Fableon/Object/Class/Store/C/FAStoreViewController.swift +++ b/Fableon/Object/Class/Store/C/FAStoreViewController.swift @@ -73,7 +73,7 @@ class FAStoreViewController: FAViewController { let label = UILabel() label.font = .font(ofSize: 12, weight: .medium) label.textColor = .FFFFFF - label.text = "store_tips_title".localized + label.text = "fableon_tips".localized return label }() @@ -130,21 +130,21 @@ class FAStoreViewController: FAViewController { self.stackView.fa_removeAllArrangedSubview() guard let model = self.payDataModel else { return } - if model.pay_mode == 1 { - self.addCoinsView() - } else { - if let sort = model.sort, sort.count > 0 { - sort.forEach { - if $0 == .vip { - self.addVipView() - } else if $0 == .coin { - self.addCoinsView() - } +// if model.pay_mode == 1 { +// self.addCoinsView() +// } else { +// } + if let sort = model.sort, sort.count > 0 { + sort.forEach { + if $0 == .vip { + self.addVipView() + } else if $0 == .coin { + self.addCoinsView() } - } else { - self.addVipView() - self.addCoinsView() } + } else { + self.addVipView() + self.addCoinsView() } self.stackView.addArrangedSubview(tipView) } @@ -154,18 +154,18 @@ class FAStoreViewController: FAViewController { var newList: [FAPayItem] = [] - if model.show_type == 1, model.pay_mode == 1 { - if let list = model.list_coins, list.count > 0 { - list.forEach { - if $0.buy_type == .subCoins { - newList.append($0) - } - } - } - } else { - if let list = model.list_coins, list.count > 0 { - newList = list - } +// if model.show_type == 1, model.pay_mode == 1 { +// if let list = model.list_coins, list.count > 0 { +// list.forEach { +// if $0.buy_type == .subCoins { +// newList.append($0) +// } +// } +// } +// } else { +// } + if let list = model.list_coins, list.count > 0 { + newList = list } if newList.count > 0 { coinsView.setDataArr(newList) diff --git a/Fableon/Object/Class/Store/C/FAVipRecordViewController.swift b/Fableon/Object/Class/Store/C/FAVipRecordViewController.swift index d920d4b..42a7a8e 100644 --- a/Fableon/Object/Class/Store/C/FAVipRecordViewController.swift +++ b/Fableon/Object/Class/Store/C/FAVipRecordViewController.swift @@ -25,7 +25,7 @@ class FAVipRecordViewController: FAViewController { tableView.fa_addRefreshHeader(insetTop: tableView.contentInset.top) { [weak self] in self?.handleHeaderRefresh(nil) } - tableView.fa_addRefreshFooter(insetBottom: 0) { [weak self] in + tableView.fa_addRefreshFooter(insetBottom: tableView.contentInset.bottom) { [weak self] in self?.handleFooterRefresh(nil) } return tableView diff --git a/Fableon/Object/Class/Store/V/FACoinPackConfirmItem2View.swift b/Fableon/Object/Class/Store/V/FACoinPackConfirmItem2View.swift index fb3e96d..1abeb02 100644 --- a/Fableon/Object/Class/Store/V/FACoinPackConfirmItem2View.swift +++ b/Fableon/Object/Class/Store/V/FACoinPackConfirmItem2View.swift @@ -38,7 +38,7 @@ class FACoinPackConfirmItem2View: FACoinPackConfirmItemView { override init(frame: CGRect) { super.init(frame: frame) - self.titleLabel.text = "How Do I Receive Coins?" + self.titleLabel.text = "fableon_coin_bag_buy_tip_title".localized fa_setupLayout() } diff --git a/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift b/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift index d74654c..20a8965 100644 --- a/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift +++ b/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift @@ -13,7 +13,12 @@ class FAStoreCoinsPackCell: FAStoreCoinsCell { override var model: FAPayItem? { didSet { coinsLabel.text = "\(model?.ext_info?.max_total_coins ?? 0)" - ratioLabel.text = "\(model?.ext_info?.receive_coins_rate ?? "0%")" + if let text = model?.ext_info?.receive_coins_rate, !text.isEmpty { + ratioLabel.text = text + ratioBgView.isHidden = false + } else { + ratioBgView.isHidden = true + } priceView.setNeedsUpdateConfiguration() } @@ -124,9 +129,9 @@ class FAStoreCoinsPackCell: FAStoreCoinsCell { var subtitle = AttributedString("\(currency)\(oldPrice)", attributes: AttributeContainer([ .font : UIFont.font(ofSize: 12, weight: .regular), - .foregroundColor : UIColor._636_F_7_B.withAlphaComponent(0.2), - .strikethroughStyle: NSUnderlineStyle.single.rawValue, - .strikethroughColor: UIColor._636_F_7_B.withAlphaComponent(0.2) + .foregroundColor : UIColor._636_F_7_B.withAlphaComponent(0.05), + .strikethroughStyle: NSUnderlineStyle.double.rawValue, + .strikethroughColor: UIColor._636_F_7_B.withAlphaComponent(0.05) ])) button.configuration?.attributedSubtitle = subtitle diff --git a/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift b/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift index 46ea103..d7a909e 100644 --- a/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift +++ b/Fableon/Object/Class/Store/V/FAStoreCoinsView.swift @@ -110,7 +110,9 @@ extension FAStoreCoinsView { addSubview(collectionView) collectionView.snp.makeConstraints { make in - make.edges.equalToSuperview() +// make.edges.equalToSuperview() + make.top.equalToSuperview().offset(8) + make.left.right.bottom.equalToSuperview() make.height.equalTo(1) } } @@ -190,6 +192,8 @@ extension FAStoreCoinsView: UICollectionViewDelegate, UICollectionViewDataSource if model.buy_type == .subCoins { let view = FACoinPackConfirmView() + view.shortPlayId = self.shortPlayId + view.videoId = self.videoId view.model = model view.buyFinishHandle = { [weak self] in guard let self = self else { return } diff --git a/Fableon/Object/Class/Store/V/FAStoreVipCell.swift b/Fableon/Object/Class/Store/V/FAStoreVipCell.swift index 9d30eb9..82776a9 100644 --- a/Fableon/Object/Class/Store/V/FAStoreVipCell.swift +++ b/Fableon/Object/Class/Store/V/FAStoreVipCell.swift @@ -12,7 +12,7 @@ class FAStoreVipCell: UICollectionViewCell { var item: FAPayItem? { didSet { - nameLabel.text = item?.title + nameLabel.text = item?.brief desLabel.text = item?.fa_description // coinTimeLabel.text = item?.auto_sub @@ -43,7 +43,7 @@ class FAStoreVipCell: UICollectionViewCell { let oldPriceStr = NSMutableAttributedString(string: oldPrice) oldPriceStr.yy_strikethroughColor = discountLabel.textColor - oldPriceStr.yy_strikethroughStyle = .single + oldPriceStr.yy_strikethroughStyle = .double discountLabel.attributedText = oldPriceStr discountLabel.isHidden = false @@ -156,7 +156,7 @@ class FAStoreVipCell: UICollectionViewCell { private lazy var discountLabel: UILabel = { let label = UILabel() label.font = .font(ofSize: 16, weight: .medium) - label.textColor = .FFFFFF.withAlphaComponent(0.4) + label.textColor = .FFFFFF.withAlphaComponent(0.03) return label }() diff --git a/Fableon/Object/Class/Store/V/FAStoreVipView.swift b/Fableon/Object/Class/Store/V/FAStoreVipView.swift index ae3e6b5..f5f23ca 100644 --- a/Fableon/Object/Class/Store/V/FAStoreVipView.swift +++ b/Fableon/Object/Class/Store/V/FAStoreVipView.swift @@ -20,16 +20,18 @@ class FAStoreVipView: UIView { var buyFinishHandle: (() -> Void)? + private lazy var collectionViewLayout: UICollectionViewCompositionalLayout = { let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(110)), subitems: [item]) - group.interItemSpacing = .fixed(14) let layoutSection = NSCollectionLayoutSection(group: group) + layoutSection.interGroupSpacing = 14 layoutSection.contentInsets = .init(top: 0, leading: 16, bottom: 0, trailing: 16) + let config = UICollectionViewCompositionalLayoutConfiguration() let layout = UICollectionViewCompositionalLayout(section: layoutSection) diff --git a/Fableon/Object/Libs/ActivityManager/FAActivityManager.swift b/Fableon/Object/Libs/ActivityManager/FAActivityManager.swift new file mode 100644 index 0000000..358acdc --- /dev/null +++ b/Fableon/Object/Libs/ActivityManager/FAActivityManager.swift @@ -0,0 +1,62 @@ +// +// FAActivityManager.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/10. +// + +import UIKit +import ActivityKit + +struct ActivityManagerAttributes: ActivityAttributes { + public struct ContentState: Codable, Hashable { + // Dynamic stateful properties about your activity go here! + var videoTitle: String + var videoCoverPath: String + var videoEpisode:String + var videoId: String + } + + // Fixed non-changing properties about your activity go here! + var name: String +} + +@available(iOS 16.1, *) +class FAActivityManager { + static var coverFileUrl: URL? { + let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.hn.qinjiu.fableon") + let fileURL = sharedContainerURL?.appendingPathComponent("cover.png") + return fileURL + } + + @objc public static func liveActivity(with videoTitle: String, videoId: String, videoEpisode: String) { + + let fileURL = self.coverFileUrl?.absoluteString ?? "" + + let contentState = ActivityManagerAttributes.ContentState(videoTitle: videoTitle, + videoCoverPath: fileURL, + videoEpisode: videoEpisode, + videoId:videoId) + + do { + if Activity.activities.count == 0 { + let attributes = ActivityManagerAttributes(name: "live activity") + let activity = try Activity.request(attributes: attributes, + contentState: contentState, + pushType: nil) + + print("Requested a pizza delivery Live Activity \(activity.id)") + } else { + Task { + for activity in Activity.activities { + await activity.update(using: contentState) + } + } + } + } catch (let error) { + print("Error requesting pizza delivery Live Activity \(error.localizedDescription)") + } + + + } +} diff --git a/Fableon/Object/Libs/AdjustStateManager/FAAdjustStateManager.swift b/Fableon/Object/Libs/AdjustStateManager/FAAdjustStateManager.swift index 2db0040..5dcd4d0 100644 --- a/Fableon/Object/Libs/AdjustStateManager/FAAdjustStateManager.swift +++ b/Fableon/Object/Libs/AdjustStateManager/FAAdjustStateManager.swift @@ -20,5 +20,14 @@ class FAAdjustStateManager { var idfaAuthorizationFinish = false - var apnsAuthorizationFinish = false + private(set) var apnsAuthorizationFinish = false + + var upgradeAlertFinish = false + + + func apnsFinish() { + self.apnsAuthorizationFinish = true + FATool.sceneDelegate?.retryHandleOpenAppMessage() + FATool.requestIDFAAuthorization(nil) + } } diff --git a/Fableon/Object/Libs/Alert/FAApnsAlert.swift b/Fableon/Object/Libs/Alert/FAApnsAlert.swift index f6273b0..b470c02 100644 --- a/Fableon/Object/Libs/Alert/FAApnsAlert.swift +++ b/Fableon/Object/Libs/Alert/FAApnsAlert.swift @@ -58,6 +58,12 @@ class FAApnsAlert: FABaseAlert { override func handleHighlightButton() { super.handleHighlightButton() FATool.openApnsSetting() + FAAdjustStateManager.manager.apnsFinish() + } + + override func dismiss() { + super.dismiss() + FAAdjustStateManager.manager.apnsFinish() } } diff --git a/Fableon/Object/Libs/Alert/FAUpdatesAlert.swift b/Fableon/Object/Libs/Alert/FAUpdatesAlert.swift index 550a685..07c9585 100644 --- a/Fableon/Object/Libs/Alert/FAUpdatesAlert.swift +++ b/Fableon/Object/Libs/Alert/FAUpdatesAlert.swift @@ -56,7 +56,7 @@ class FAUpdatesAlert: FABaseAlert { override init(frame: CGRect) { super.init(frame: frame) highlightButton.layer.cornerRadius = 18 - highlightButton.setTitle("fableon_update_now", for: .normal) + highlightButton.setTitle("fableon_update_now".localized, for: .normal) fa_setupLayout() } @@ -74,6 +74,12 @@ class FAUpdatesAlert: FABaseAlert { application.open(url) } } + + override func dismiss() { + super.dismiss() + FAAdjustStateManager.manager.upgradeAlertFinish = true + FATool.sceneDelegate?.retryHandleOpenAppMessage() + } } extension FAUpdatesAlert { diff --git a/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift b/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift index ac566c5..ae00ab6 100644 --- a/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift +++ b/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift @@ -132,6 +132,7 @@ extension FAVipRetainAlert { var payItem: FAPayItem? { didSet { nameLabel.text = payItem?.getVipTitle() + textLabel.text = "vip_tip_01".localized button.setNeedsUpdateConfiguration() } @@ -215,9 +216,9 @@ extension FAVipRetainAlert { 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) + .foregroundColor : UIColor._000000.withAlphaComponent(0.05), + .strikethroughStyle: NSUnderlineStyle.double.rawValue, + .strikethroughColor: UIColor._000000.withAlphaComponent(0.05) ])) } else { @@ -239,7 +240,7 @@ extension FAVipRetainAlert { override init(frame: CGRect) { super.init(frame: frame) nameLabel.text = "Weekly VIP" - textLabel.text = "Unlimited access to all series" + addSubview(bgView) bgView.addSubview(bgIconImageView4) diff --git a/Fableon/Object/Libs/Empty/FAEmpty.swift b/Fableon/Object/Libs/Empty/FAEmpty.swift index f63c490..4696202 100644 --- a/Fableon/Object/Libs/Empty/FAEmpty.swift +++ b/Fableon/Object/Libs/Empty/FAEmpty.swift @@ -24,4 +24,33 @@ struct FAEmpty { return view! } + + static func fa_notNetworkEmptyView(clickBlock: (() -> Void)?) -> LYEmptyView { + + let view = LYEmptyView.emptyActionView(with: UIImage(named: "__startap"), titleStr: "No connection", detailStr: "Please check your network", btnTitleStr: "Try again") { + clickBlock?() + } + + view?.titleLabFont = .font(ofSize: 17, weight: .bold) + view?.titleLabTextColor = .FFFFFF + view?.detailLabFont = .font(ofSize: 15, weight: .regular) + view?.detailLabTextColor = .E_5_E_5_E_5 + + view?.actionBtnHeight = 32 + view?.actionBtnHorizontalMargin = 26 + view?.actionBtnCornerRadius = 16 + view?.actionBtnBorderWidth = 1 + view?.actionBtnBorderColor = .FFFFFF + view?.actionBtnBackGroundColor = .clear + view?.actionBtnTitleColor = .FFFFFF + view?.actionBtnFont = .font(ofSize: 14, weight: .medium) + + view?.contentViewOffset = -20 + view?.titleLabMargin = 30 + view?.detailLabMargin = 2 + view?.actionBtnMargin = 20 + return view! + + + } } diff --git a/Fableon/Object/Libs/FALogin/FALogin.swift b/Fableon/Object/Libs/FALogin/FALogin.swift index 23036de..9ba013f 100644 --- a/Fableon/Object/Libs/FALogin/FALogin.swift +++ b/Fableon/Object/Libs/FALogin/FALogin.swift @@ -77,6 +77,7 @@ class FALogin: NSObject { FAStatAPI.requestStatOnLine() completer?(true) NotificationCenter.default.post(name: FALogin.userInfoUpdateNotification, object: nil) + NotificationCenter.default.post(name: FALogin.loginStatusChangeNotification, object: nil) } } @@ -93,6 +94,7 @@ class FALogin: NSObject { FAStatAPI.requestStatOnLine() completer?(true) NotificationCenter.default.post(name: FALogin.userInfoUpdateNotification, object: nil) + NotificationCenter.default.post(name: FALogin.loginStatusChangeNotification, object: nil) } else { completer?(false) } @@ -129,5 +131,7 @@ extension FALogin { ///用户信息更新 @objc static let userInfoUpdateNotification = NSNotification.Name(rawValue: "FALogin.userInfoUpdateNotification") + ///登录状态发生变化 + @objc static let loginStatusChangeNotification = NSNotification.Name(rawValue: "FALogin.loginStatusChangeNotification") } diff --git a/Fableon/Object/Libs/FATool/FATool.swift b/Fableon/Object/Libs/FATool/FATool.swift index 58daa7f..14413c5 100644 --- a/Fableon/Object/Libs/FATool/FATool.swift +++ b/Fableon/Object/Libs/FATool/FATool.swift @@ -32,6 +32,9 @@ class FATool { return keyWindow?.rootViewController } + ///灵动岛数据 + static var widgetLiveActivityModel: FAShortPlayModel? + ///获得启动图 static func getLanuchViewController() -> UIViewController? { let storyboard = UIStoryboard(name: "LaunchScreen", bundle: nil) @@ -102,18 +105,31 @@ extension FATool { //MARK: 检查更新 extension FATool { + static weak var updateAlert: UIView? + static func checkUpdates() { + guard self.self.updateAlert == nil else { return } + FAAPI.requestVersionUpdateData { model in - guard let model = model else { return } + guard let model = model else { + FAAdjustStateManager.manager.upgradeAlertFinish = true + FATool.sceneDelegate?.retryHandleOpenAppMessage() + return + } self.showUpdatesAlert(model) } } static func showUpdatesAlert(_ model: FAVersionUpdateModel) { + guard self.self.updateAlert == nil else { return } #if !DEBUG if model.force != true { if let date = UserDefaults.standard.object(forKey: kFAVersionUpdateAlertDefaultsKey) as? Date { - if date.fa_isToday { return } + if date.fa_isToday { + FAAdjustStateManager.manager.upgradeAlertFinish = true + FATool.sceneDelegate?.retryHandleOpenAppMessage() + return + } } UserDefaults.standard.set(Date(), forKey: kFAVersionUpdateAlertDefaultsKey) } @@ -121,9 +137,17 @@ extension FATool { if model.canUpdate() { + FAStatAPI.requestEventStat(orderCode: nil, shortPlayId: nil, videoId: nil, eventKey: .forceUpdate, errorMsg: nil, otherParamenters: [ + "is_force" : model.force == true ? "true" : "false" + ]) + let view = FAUpdatesAlert() view.model = model view.show() + self.updateAlert = view + } else { + FAAdjustStateManager.manager.upgradeAlertFinish = true + FATool.sceneDelegate?.retryHandleOpenAppMessage() } } diff --git a/Fableon/Source/Assets.xcassets/color/#FF313B.colorset/Contents.json b/Fableon/Source/Assets.xcassets/color/#FF313B.colorset/Contents.json new file mode 100644 index 0000000..6e3ce87 --- /dev/null +++ b/Fableon/Source/Assets.xcassets/color/#FF313B.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x3B", + "green" : "0x31", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Contents.json index f48a40a..a3401c1 100644 --- a/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Contents.json +++ b/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "Thalire@2x.png", + "filename" : "Fableon@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "Thalire@3x.png", + "filename" : "Fableon@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Fableon@2x.png b/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Fableon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c9c5486a2c3e70b2ce0ac67d6fadf6b404e3dbb0 GIT binary patch literal 3759 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 Ze*(D&5mL|vYZ?Fm002ovPDHLkV1n()GOPdq literal 0 HcmV?d00001 diff --git a/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Fableon@3x.png b/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Fableon@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..2391f2fd5de67ce8d728da3692f526719968ae89 GIT binary patch literal 6558 zcmV;P8DZv$P)7>zL!BgCcgDKM?qDH0(txb{+%(OxXwJzQsSEzJ=} z9C1V@iZe!FR8#o(5+uV5qhN$uCKv*gBfn~Z5hHVK%n?T%aYP0NGe)*VehvR$nFuo+ z$_N8AY)Fpg$Q+M2;)nsr=1?dZqP`G5UYI>FLk~SZ=J@=$tUlt1BT|vXt+dQ=7mUyc z$sB>!vtNJxbzzP;;)o*>@TBiYTqdKg5SZKxVu}aH3?&T+#~eXo#HIbh{GS8g<56-x zA_OP!zkECyLs@vAMFKrZ#%|1Hr+M!nJ=Pzr2WJ-a=c*OO)5B1`(%bg20mQh?Epp=>NGUSZ*Aw6 zG#YF-uwFq~?>&sA)b(ITW=_P&d*2h*51EAdFN5_kKYCZ+V|8ZF+?pN2{+y^D6#ZkT zv~fK81+#~oafb}PNd0(c-UU;{G71m)?|=XOclLm{-JWd~V<|bS;!C&P(&lbR{pCB0 zwJ+ek841unA30qSI?`wH9Re94F~Opf6-h+385z{C9|CP3>MOT)$5O3g{N1LsSAfa7 zw*O*1!a)_t2$!JkVA+x1VG0`j6VMSXf%XqWEYY@`QBk*AyYI06ee@2semjO}m9t^) zJHa}*y2$#BwWSg#DMR{BC}aJ-$1&f1e^8zTIB0+-3~ch!X08(W`*Q6b=udNKqw6tr zd$yBqKliwp}`=qMB;#OtngR(zl3!6Fj$tmPzIC!XDtQ#>Tb8UA}-LO z+#~{-FkH8N18z(Mmu~>TbzZ8SZD;MgbN8WsBcsHH||-;ewrC8n{K%Nls<`^F4}?Iwy-UPk13vujWvKi15v#4g)2(TKU}6eHc2?;EQzcWC&CA zp@5!QEp=KEQ*#&APc*Ku&pTy`{Jk+ODI!$%7(o>ct$xN}ikQ!}83|Hg(2NZsHTqU; z>JUnQC&d!Dy9(aBTsv4C~ptS`u38?+|D$(S5YhSeUXr zXF0se)iFiRULReGNVGC$OCKd*yJc>cF~I7VS-4$HCBCE7$fa=WF`UTn@Uu?}fbVb# z^2T;b_xHYCJDU2+@^d9O+9Fw-4D4Z5(YOx@?|Dli?2!r^l;m+~2KisYzagK7e)cJ`a`FvAwANzenH$bKUALlod(C15jvohK_beV=jyw- z(I#>7Y<9gB5X%3`jWB)Csyt9lf`bc}V`CZ{$g{=*smo&+9VpZScP2c-x2|5{U!EUYc$$&*Ip-Nq2CC~hEa zzjA}R4rH5kj*IPdix=)*+xSviQ>IhRQV!6rxSaZzWj>Ue0jSwAk-`)`E+bhw<)O`6en%$b8gL;76o({Ckn$2O@7@8+U*-tvXjA~fM^7^9OKOH5+9(xPXD zH76bIJ$oj}_=4c>X_Y9jrY$-0P^*n)bnGPv!ZGb9Vt%#BvutHCMZ_c9kdDxHAkHje z%Te}h)_zjd6Vj46h!72uk)|%CJWKX-n8@_XX9n!(K;x~J7EU`n`|oP^!E-0HFV_Y2 z4ZdgV*&lB^f6J$IU)!Ia2{liP%jc@x{`0LMCj%zIEri;D*T2e)4IuHzf;+^X5iV=RF=5PfM9VY|pEss`flbslZw<_>V%8MkJT_5}^1 zrB&?4kxTHzGUbx|8khJc6KI?>%KqYJz>N3PhAzDFTcH(#pClY4T~uT}lufCOvQT!4oRzO=xSB#1K7zFE6?E zDvbb>AX~PckghcZVB`zOmT$iO4cb!hcJ)2VT$`kbhfi&XMC1pucb%%IqAMc$}`*cuM zrU9l8l+QZqh0Y1vvrLmElwFtrZA?Oyls!?%*jfG`SD2~5oyi~_k3=p zJ(AFbcZ?Wp7yNa~^HZc*e1cjb)^OHn#IPwVauOf zAE+@=ZSIGxwdr7ambCjqT4s@1Smm}cK_i9~!?QmyjM>8gzptV(F+%`pZLl(!CZO8g zr*!sQLr)2m^r7>i$6%(O;OY6Tt*nYP8~0=}zv`QWxF4xzIc+oi8gm4e6acfn$jQ4B zJH<8_;~_#?pOk5EhE?kq?e=E*GyI?FSf2HI48O^ zJOdTae7?&$K#T_Yg}aZnw|J)uvnLFZa)$!i|6kf?QyGcf-a&Plq6f6hpVS5{*-}NI zRfX8@D356%pDaKg-`(ew6@VD?-{kKn+!|xcy4VcD${&)ciKQDjP+RLT?X!GOPPDaA zKv>Fr<;+&f^Kl{lv@fp`@aT*&I?I<->;DiY4m9i}l8z4pq}(KUB)E+wYb0&bvQt`~ zarvC8s-OVUi$I>Ca%-bNs=$(p+!cV2ui(xXbd_iatHv5NCPJ<<82StbZDVwK3~Ky} zIVgK(UzOF;m2J13r>A6*>vfQYw7)YSKcj_J`l?CeftWq#pf~!al`>L{L_#fczprJq z&D;%@3QvDVW_1nA+PP66m3fQ4_EuYt1eA3N=^wPuQ(MmZo*BE%Z5NHb&dh&H;ys}d zJ4;r885`CUnrRh2PV-u$AEA6}GeBC5A@yZC{gO=Qi*dR#(l^n;4C}tRcaENrGw^Exu>? zZ8RuxNoi56&T85>KJ)#aixbihtUIYz>d+v>0JZs}M3Lf3lG6AwePN|{K9533N}u|q zF^W#3Qf5cmv8g(Lxj7CLpLE943+7n!9Ya0kPfebluG!TY#S$dU;J zd(bXvPZGDZV$c@tvr-pdb&>Z6!3u|G3DItoKI?R)&n1?au&p)Hh-e{SUOZ4e1O zY@NjRnkO1#85aT$Ug!*;UFSimDaG;EW(F`A+eOJEIrJWCUuAgh6Pi_b4DEuBpo>T+(Ws|xm z>eW$gZfwBk7ry64)-BfjCTBeRyiZ!jh=T|!c*ZxUYnfvrL&Vwa9-haJ@)bEXMp7R7 zA`z>e^Jpb@r7n==pyZ&?l}_DV>qi*)@RoNREUO)D^*S_ZQ2?cgOHjHm zVh?Kf8(Za!XFDtSJH9W~<*l8$N!K;^q0F%OU8B#zy&~liqe?rq%Rz(GH<+Z zL)h6aMrd*%*jzU#e19UJ-g51B%uzJ>;60A7^Vs<=AV{Fz%)}u2^1MoqRf=@Jp?0d)L%`h%pqK=z=p86vn=ZJtx~< z%NXUd)OO3E3rPQ(>i~Jai9TMn?|T^F6PHg)e$XB`Q{&dOm&mZI%`IlJ5_L#VOQCgX#H55R)=Y4cTd6SjGV?vC-&yilq9!xFx~=vxON?tEW<)wVOV=QN&si`2_4C1xpjm`xp;th-kXs5@tUJD3cbV=?3}l2?*5iK` z>v#%loqT@XhB4+gmINRtkJwgBnhbZk$6kxjxjQzp&23kZZS5PVLzuxB@bnS9KaVjP zz9+t~4$>&XnJrGxlELP-hgI$jlB2NUg@+&pV$xa4g)or}OWRPm{W10oG0Ketg6R7w zBa)q-f^@{7vhbFc1XliF2Pr4^ttFj(4_slfyz)K64Fvn5*TY=A%TSWGK84cl3O*^( zbiTP~8uvVE^XLRBjEXO$)Gx=QhB?aLtAyYhk}>`n%CrZ6nH>W;K85XSOd6U>>G$R< zL(?W=Ir>MXaL3@Y;SgoD7At?i1625<74dncbRnTh<{+d-yBQE86bN=1O0x@i)D<84 z25Qyqs~@aiOT{W2@MYac62j6sU49GY7`l{w5bu5Cv5(Qp-&P4*Q8ySPb@Ya1WI~0q z&wE*(5QB?0xR{AjcS^K76^ycTdUP34=@ju82}4!_ZsrfrKc~(M` zFhJSX3zBf>MoY6Ocu9=F@Phm9GtWgS0_leoYoHt^j=D72Iel1dA3k)h?LhFtn!dc; zcc}xJGmb!7WQfn;9bRfBX$h&CNFBI+j4uRNuO4I6?>+RQnxNt3mt>GWrtWzLR}yEM z{(($l)ty+mMoF6c=tR(J=4}-?T~LFnC$ym~+eUWqgqUNf9@y6Se1V`I?Vz6Z1c%_) zt=Thh7lD%22b;Oc9@5@~Hm&>03T;de0b?-w>Jcgf0nd9k&%5t?uJ1p7{J6<&3m-5* zhAd|l2-2XSFZ?_0w(m)U4nLe$GN9QLb_Q`zUwPghZNc!owjh`7s&TZtZePM zLr5Epn|Y)^%uFV#P@!<$+WzxNn$+N%V?aYI&bYX&O4lCy0s3qB_zLxiQ06zc zG{$FBqyij(AStUo8*+j40i7rX4Gu*%GR;fU!F?(sU3p-;t%-LgKtHt8TWy4M2MX+r z{Q-CFAyaMRlA00g(GJ#CcRupgj8anKD1p$7x=IXV9|G1FC6b;Q>UKz*U|MYN*esYh z>)&9WrDy&C{gX)h_-OosX$G9VJs8x-zht&EmpZ@mHb*8lR=W?R886&peurb*wf`>q z2!i_gT(n`^j^==%^8c`1yhG&1ZRn?c9+KV%oIR>8xIrszlnR2&L2WUE8R{vO^SQJX zhD;vv+>lVwbpx%GBppu!Nn7Ir&iwld>OoQgz6aa~yb(T(bl9Jf#*zUPO2GAT>OU9) zt!6*tdq#=sFOpD~u5VHOCi_@9ahg{YBm(*k(uomtoSqfGM>?^szryp2J#NTYgBWBD z{S@1Ai4(~o(B&|Wi~JFTK~fYh6WU3LFAE&=F!y41H&_x@)khR;C!s3|^n0 zP+`dlRc!rM+5S9iIVs44a4BwSf~wF1l9m|X$FKt+PspF(^?T?EJ#OX|#~yY7q)(gW z0)?FVx|jVS|G1gf8sdUVU$2j#b@VA`zkmO(eGEIv!*fC<%d5;cqoNWLeNxsrD1M~=Q8HNHt zXRAfg>6+N)`w$a&HxGq?x`)OyzHa3I_#{X4Cy|S)Yb>%4_1iGw*Ns#uGqz zcE`^QoOpBKwNpYT>wbW`A3(5=o9(RS(x@!@ z&~_3?S>)z1wwZ*i%X9-Id=HO~9r|@9XxJ)AoeN50BA40F z;e!_}HJL1dc;{M}l4#rOThmQyLeK`LDdrv3$J~IBC4DV0aUUBxABKLfV#b`p^_xWp z+MB*0^A68%&`FlGRDJXd5AoV`N?e^4VqTN<%6~QO@lMe$O{D<@Z^xy)r;ZmjjPveU6xxT=9v1yv zo~;B{8bl=1O#w#@RhkpD#w#sEbhKb}EIRab#&h6igN( zOD?=ZSbz|&B4kbXAovWvNeMuoiKao=5z??IWvQ`YmSX$G$;JkXk7TD zn;Vqt9vmD@!j`Z!QGASSO(8_V0p6yxNn9AIlvNH7gyeH3m^u`FS@c+NN8&f~^abYR z5;lo#-h%@e=tho8EabFL&VRi;Tw%X8_s`JdW!^-c zQ{)9R5>1<$LP5UJnV&~_A>jUu(lV2fFljlk@JE%}DG8_y0XVVh0qv>og8{-(S#9VT z(Onn4@eE!Nn3_VDW{iR5vNoEx@zn8Q4RSPJ(Fi`nH&l6zX?lm|_+#h**jYdM zK05vxJbwqi#F_9-79I~edc)KNpD-wz%riR2H+Xi5eW1S*gdpmGB|hdM=LXGhny;=< z`N+z6ztKldJHy!KA#E$Xirf{*@zrg=ARUgf`=4n~* zXOJ=TClTa$U-BsijspvwXpHfi>qGxB7#19VstwVf$u`#f>T~(jIQ0CHOw0;10UYRz zz0_1uGAXvlVCNvgFX8$F6OV(Q-^mfJn$9=rXToY)A8uE~6VZDVg d+lvx@{{x&8;K5(25WN5Z002ovPDHLkV1g9z)5QP) diff --git a/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Thalire@3x.png b/Fableon/Source/Assets.xcassets/image/Thalire.imageset/Thalire@3x.png deleted file mode 100644 index 6b3c25cab296a291e1061ed426a7937cacb3478a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4183 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

-t`B$jZjij)hOa|nuC%M=; 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 Ae*gdg literal 0 HcmV?d00001 diff --git a/Fableon/Source/Assets.xcassets/image/__startap.imageset/__startap@3x.png b/Fableon/Source/Assets.xcassets/image/__startap.imageset/__startap@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d82388d04a5fcf3c2d5538fae11946c00a736a49 GIT binary patch literal 92552 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�DfY3M=!t~g|{Y+^6=+tyr&JM;`b_YrMlh`fmqk*W6pL%2N*!2`S zQ@FkN5SPi~y1}xExjllT;)~RMLSE1t8nyO+Qcb)42D9yPi+&lR*|HsUPygOG(=Kff zERi18Yw=(4c^q6S_`~owwe5&4r@fDf+hY`GU`<^!=>9u^XO&ZR-`er0lx}3Tl)O8f zG7l-6{gF0_M82(_g#7v}i;M{{8pD(ki0S6W-a({zLujL-D73w#6<{F?wo@^V?o5(-5t^R%y`E!v+MzyK0 z_0>L9JFCQgvHCn$kfY6ogFl6+cWP5YZ_6hCbFbywU)FRnYQLcC!As$q-xe(iGggzC zf_p*~e^gzPS$S3ypgFx>FX(`4V997yyG9Zh1v~)aQ$HpFSt@x#v$n&a?Vt6)VEX)p z0|qNYKsMUM4}%y{x85Lv;na1 zs8xFSJj@8I52n;Gz1p7QS^v~4Wi#T*!L?8eXg9z%gNC=YHK(*mtGgw3yGj)XxO|I(o)@AZ+_m+2a?|MNK!!ZI+ zWd@juVN|>ocd2d+$r1Hao4l>Kmfg2QDpWed3S`7NQhdws>r#=y&;6eLd9ZYN4eb9_`IguSOXXuqrHi2_R);?5R3)Y{hE2NC^01d0?0=SzzC^0C*NX4_ z(0g^0D|D}gl|RgcxfBVy3tnm65Y;Kp(KL=0*VbOqdx9lgV?TYQnz122DZUm5! z+SUYpU*GFQQ_ZyOf@&9M_M~`u`u27Wc3M;T&NStcH>u<;I9@6XV3Gh8(EyOQF1;4; z!=B?7-=gi(F#`q=y6w*x3=JjFzfP2s)@M7l)}MR?7;xn2ymdOpG^<*wmRlT|nK82? z%UK_m+@{oePshpN7SVUsAfn`~O89OGYH>EH96kj9N2gVaXync#1iJ(Ut~GE^W0_$M z^knitJWK+d6N_D-rulHrLtNZ)XR^`vq->LvcJT4wg@x)}{ydhTtcBdz7_@|uUY)DS zg#0_OjPaQ zX^jRg+cBMFRl58k^^$z-1iaZ-ZXX>95x~d&s z)+01^?`HUD?q^Z7YWVbW$aU&R%}((D1|22^f9i8cYO;Bkb0qnQvKKoR(55i|uTLg_ zB|>+Vc-f>#SscbtN@p`#T+T{!TT;S2?{`N`xL!@JerSPFV2MOkp#Ie|X))JJg&y zIEnkTd#j&8jK-{yXds$te$0&gb|(|Hi?L(UvtB+2s*vAP*se-By$6vRT%UGlsQs7Q z)MQ78vS8OSo@0+1u$vJ?3>*iVzKEr*6=#9y{7sqwba24YpLOrFE7lP{={YnrMkIPk z-wuSUa`BM?})T{mA z{8ERQ1{Qd2(+=AIBwiNhMBLhaK9*V?y2&o-w-W&M+Ftp6G;+y=c0`bfUD@S3BBfk#uGCJTFGFw&2; zc-ysL!QxcQ&u_}=R1S^zjJeyMPQv&ExE^yS^8A>*37Vgg%Ny{bzo@W(wcaf(z;VH| zXj|hfK2N{*V!?JV>-deOia_`J4aQy)J(7bS`Y?7l*9o%Mp+8=xv^x;&bq}(`RX}R^ z{FaM*yB^T~046AkeNU|YxM-V^^^OX?_`!GjOi^g2B{KBsqYocGOnVzA^wv4fH8~MW z>63_EbDfCwHCm5|BYH#a!M_!wBH|5;j(_O`nLOhQ1K=RxKp-pg2yJn*m}DiQE_CrO zVez+R0&3j~t=_dg@Xpk}CJ^5fZK5xV3s19xdkv;JueC(4;XmoUkC6H6xM~~bTSt$5 z`g96O*yH8VVg|DvEFHlDoVz9@Uzgp-aw;#CVQ%(pXx^tg%QQB(r0x^|1Ec}hWLApn z{@9eh#tfCVYc0!!I{M^Fw%a&v_G`5nEoqnX&%lO(0u&_K*dr@aR4ywKRqQ6!6nGHZ zAx2)C51Mc_wrndLS(k9vL>N2xzm8VWk zUjA8S`Jp=~(g8FcW_ES#T-G)QiuZsfm1K!Ki*~*=Cu-qqnyjDhw~yBjhs^`l?`(I= zUz1e6SVMoWP}CqRCIBwZ;JvHRV_U*R#`olaQ03M$EgIs5`LZ@=$0MZ-c@vtD--nL^ z-1;0q-__b(_?=OQzLlv#gE1RN`Pavld*3n6R0q>WuHj!z%c5?yta@sXP8COz z16wuZsr^Y);^AzZg2e?DW(B|vD6#siLd3`wTti4AH_S85Nfg5N8(|gBc1JmPtZu8E zW-ILj(WyBvJxIYx33GKT|9M~gxj9?6)Tl@Xs(Den##WHsQMa zMJ&E@!|EyiUHn_DVAfsx#SQLEJ!R9I*}}3(#Kx~jVi}nrjb@GRYdC!NWQeX((Q3Sh zeCdR8kim4?A=01nJ~W?#Kap_Jxyu?^@Kxd!-korAbz}r zyHrvFL>ZYD_o&3xhU2C$TTS709pmT<6jOZf0_B{t5NGQH@iMfXYl#${VCeEgtXMxE z7b4uT`ih*j(t9XX^)^ONzTL1o%b}1d3L5+&rEJ_`R%TluOa1($K$-IX=~dY^+?a%k zUP^*R==!{hMGp&l;M~SyZmbJQ+~y6n3Y~vWcnTZV@0wF0i!o3P7>5Cn8F7dhuW*bY zOuWbbbL1GDn8yLFDZ`q;J9$_HOReWRYcXYB^F@=YctRKVt7^;NXC7BSX>5|#@RPHC zyj<-EVY|$n)5^+QT;}Uvd z3+L-sFNP7e#RpPK1YG}sfRDcZT7;sx(OSC7Ws71{P1>3?qu~oJse5x6Bdv&dVZ5Y< z1b!LC2f9jvFo=C^dXLqIOFlio_*?Lfk6Uxl;MDo_b*+B0c`{JN>C@Uee6AJo=~Vw;R;SO)Xcx9xB}39cRsgR?x!$jY9=-Qu#r_J`+e|Co8u>z+iLXbS|9#NnRBL9>hj;bcw^?( zz|}ojd=suqYtcQ{$nv7auVL#0%W5ZING_}YY^%uG&};A4k0fne&K`0*g}-q>Lp6=C zC?Uni>um6mfl&(W74I79Dw~V4tOUewCmm?Y47e+mjl%U^6$|`f(_0O&kSBTT$PIZ# zOd&l-=u-dWx{WaYLx&bg4}YkF{oM0r*;lrw#@#3QX{-vh%rag#OX|Xg>xlch28M$q zvfRka7ke+niJQKy+(rFsCibZC6D9ANB&5?5$OmST8MD!UWJ;?g1@#>?^6XSifd);o zyv##Dv?Mu?%ig~^r&Qm-{gPRcQBrnzTUwNao(gt)2%FWNZ(_c{&;ryqFc;4c)nzRPfm228eeT+zwniIX8$9}nW6|}3jLQE-M8TutN zs%rqosZq@-myWN*rNU$5d|RE5%Go)WU-nDg1|BEiRg;(MY;Svb1kRT&$eRSRfk2uS$5fqof&)8*>~GcbBDt$snIW3-B|c0Lw&IJ+YXZ-ffyT? z0Y7H`n|9BukE}RQxdzts^h{B?%oYI{4Hmg&9O%ZH%%6O)%m(Zv=B*9t(-T>o74dL< zq~q1eg;9cfqV!VWx?CMaHI)zzp=gUclmn`pp#h)8Kjbp)o>PBh+tp{79pzXM%!c7o z=Hp9+md5eiy}e8)y>1^xYwlF!LPb>A^&KA2NC?4=>%j?4y3FXrY#e^`U(2N`W$)<$^IDf1aW%Mk zYNMY0VRFtexnDHCe_bgi!TVdjxAL=u=lPI9&LPT`1tY4A0^;Al1k4)zcxchV$#a}1+Dv24r4W8O7!hR*t2%*Yt=Y^?T8Phd@%?Av-ej1zi z3h*TaZRJ@KOwia@wRMXB?3JMxou<-nljx*FmojUFn~`>f;(Y)m_Iqmp)6T@ngW&V* zMDMd9JFHyI8PPz}caAnoI`FP`K9sdor+r442|>p%>8j%ExBfMRb$YE5^C< z{m7i`u7>y%E4 z+`WpDD&HFGGAW?MF(SrTYvj{wnZ7KQX1P2zmYp>ew~=D>H(Lz=MRbE3Ne4sJeOch~ z9|1fABIvoFscrEPjRZ^rzWGG&lKk>_aTr}!?5#VinnoNOTodTd!X$in@*?qdIB^VL zdeqMg2r|rfz@9@XxU$N>|9+Mp_IWnix*2=;KQR`oPp^X>Mrm8G%g>1jQ;R;$8t-U- zF?r(|E~}I(z5lnIUP&~6MnUVzZzxs~M&+?n>nd40T-%UN9?6(~<8vP+gOXsII_I+q zpDj0Z6m)Ancv~s8;&alyPOIC1j*0irR}NOAYL`2Wnk8ywqBF);O&#r*+bZm;QtZME zra?8-4YOV9td5hOW1VlJks*JlIB`p?afeTubIJjhr*ba?`r&m(^e?3mX1BiM?=LtU z{FAelPb8X<;9e;^<*e&PAWU@Fs4H7r_{AqC?AsQzvrqw6|#6tr{ z|EsVsz1w8*7=?Q#w+y4SZvvA8ncRO!f0eK%=AazBs+~KGLb(WctS>sj3m1$reGLIeLai=H^FT1`vPX zoN|s6IgJReTmamg&n-}tg&|x8Phox>$#1$mAOOf?)(JgL*vGpWO7k&mQXe3LA(!^m zW$JI%ybiv9LJKm^K)rXerg&b9-^Jf+l|XF%dg6xbVu;&*6Ji-+-klF}R-V3@f@<6S zB@dmR;BV~N775)?8R69uAWbmjV60%a)TVqhW-22QQ8xYlHrCg-;4#9iva+(U@6wbC z$3Sn2Qn=>l8pi7I0xGf&BV0TfgLZSVz_R+C_#ib&W%*{qPgU3cWWOq=V9b+nn;}HD zE8L@y;p}56ar?j3->{xe7uZ4Y6u+h&3Svl&xh_Uwe__#JOBo=5iyZ9X#Z|f#%)Vt5 z(vDS&!Wm)+(3j^eTD5m64o=iH%z9SbiGiLf3*0>}LMbBARbpP7CbZypj;B|EQ*mKg zuj=1~Kh3I%nc3sclyZo8p7#yc&|iTjSLahT$gw!-gj~l0rs>PQ;m?^5rD_qlVZ_=2 zgds_@M38I@-d?r(?KL2@p#KjA`}ah^0!V^+_O|^uVKeZBv1XT=C^vV{> z`Wtkh-UxK|Jnd#mN8SDRj`ai~6~`xg^upINF2~iTVFp@Ui2|oHTliFHnsdWKP%rFI z3F`$JVFr^DfSgWFZ3Fs}liU21r;wm}xth;?d&rC4{5b)ik5+4x=uYW=F-rKDE>UX+ zI|_6n_P?(X;!j)&bv(_q`m`yYy7GxW*@j>TvbYATxQZU zy?Rh_0vbU`U#cuX$IqB@l>!+kaj!er`r<+f?~M+=<$g9s$u$@BWBwo%F4IlOwVEGv zLu`NvjYYKX)>kWGORleU;3Pob$1wYPvE_+hw4w>lfTB|YID<)|A`PXIvThe`7zfh+ z+`pBfZoUW?k`&wprw=KO4sxC%_qE&1I3+VvtbDZip#wnGhv#D?t7jmU$t zY2XU7HQlxgc$UkXTr1x$9vl>V1I7mfeY-S6gMgB8rgWlpRZ)qipej9_ZTqJ8_9)CC zSjls3vZ}%vbPqoEaBWm#zqR-}f`x*NO2cN9uocHOfqOJcAkmZgTyA7!f0sFf4Ix4m zS?-hDnY^srQ;bryO;}=-GjjpP+?pH=Q8xhZWWAuh z9J&*`;bl;D@y{LF2h+Apt2h#0s{2)#Gm?!`zOv|@D zJ~1_QI~B*s{p9_bHj+{=gxDIo#>h*emBxZWaVIp%$8BFvB(Ba06Irs{w3F(K2whuR z3*V!8w73{BWClW3lZ?~4pu5EdO=2<0QmAE=Atd|vOn>WP8)(ueh`-Wwo8P65 z0SBpC^BzUsJ literal 0 HcmV?d00001 diff --git a/Fableon/Source/Info.plist b/Fableon/Source/Info.plist index 7db30cc..0fa6392 100755 --- a/Fableon/Source/Info.plist +++ b/Fableon/Source/Info.plist @@ -46,5 +46,12 @@ + UIBackgroundModes + + fetch + remote-notification + + UIDesignRequiresCompatibility + diff --git a/Fableon/Source/en.lproj/Localizable.strings b/Fableon/Source/en.lproj/Localizable.strings index af56ca0..996fa73 100644 --- a/Fableon/Source/en.lproj/Localizable.strings +++ b/Fableon/Source/en.lproj/Localizable.strings @@ -91,6 +91,13 @@ "fableon_editor's_picks" = "Editor's Picks"; "fableon_home_new" = "New Releases"; "fableon_watch" = "Watch"; +"fableon_top_up" = "Top Up"; +"fableon_selection" = "selection"; +"fableon_coin_bag_buy_tip_title" = "How Do I Receive Coins?"; +"fableon_d" = "Day"; +"fableon_kick_out_login" = "Your account is already logged in on another device~"; +"fableon_rabkings" = "Rankings"; +"fableon_recommended_for_you" = "Recommended for you"; "remove_collect_alert_title" = "Remove from Favorites?"; "remove_collect_alert_text" = "This drama will be removed from your favorites."; @@ -107,6 +114,7 @@ "network_error_01" = "The service is abnormal. Check the network."; + "buy_fail_toast_01" = "Purchase failed, please try again later!"; "buy_fail_toast_02" = "The prequel to this series is not unlocked. Please unlock the prequel before unlocking this series"; @@ -130,4 +138,4 @@ "coins_pack_tips_title" = "Subscription Rules"; -"coins_pack_tips" = "1.Up to 2 subscriptions can be active at once.
2.Coins are delivered instantly upon purchase.
3.Daily bonus coins available from the next day.
4.All coins will be revoked when the subscription expires, including both initial and daily coins."; +"coins_pack_tips" = "1.Coins are delivered instantly upon purchase.
2.Daily bonus coins available from the next day.
3.All coins will be revoked when the subscription expires, including both initial and daily coins."; diff --git a/Fableon/firstpass/grey/preservesYoga/FFCheck.swift b/Fableon/firstpass/grey/preservesYoga/FFCheck.swift index cedcd6c..82af676 100644 --- a/Fableon/firstpass/grey/preservesYoga/FFCheck.swift +++ b/Fableon/firstpass/grey/preservesYoga/FFCheck.swift @@ -169,7 +169,7 @@ withUnsafeMutablePointer(to: &writeclearWatchdog) { pointer in $0.title = "fableon_popular".localized popularItem = $0 } else if $0.module_key == .week_ranking { - $0.title = "Rankings".localized + $0.title = "fableon_rabkings".localized rankingsItem = $0 } else if $0.module_key == .cagetory_recommand, genresItem == nil { $0.title = "veloriaDetailPath".localized diff --git a/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift b/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift index 1937fbc..ac6c617 100644 --- a/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift +++ b/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift @@ -74,7 +74,7 @@ var deceleratingMax: Double = 0.0 } HStack { - Text("selection".localized) + Text("fableon_selection".localized) .font(Font.font(size: 12, weight: .medium)) .foregroundStyle(textColor) .padding(.leading, 8) diff --git a/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift b/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift index e8316ff..80c7a67 100644 --- a/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift +++ b/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift @@ -16,8 +16,14 @@ var bottomProgressDict: [String: Any]? didSet { coverImageView.fa_setImage(model?.image_url) titleLabel.text = model?.name - countLabel.text = "\(model?.watch_total ?? 0)" epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") + + let count = model?.watch_total ?? 0 + var countStr = "\(count)" + if count > 1000 { + countStr = NSNumber(value: CGFloat(count) / 1000).toString(maximumFractionDigits: 1) + "k" + } + countLabel.text = countStr } } diff --git a/NotificationService/Info.plist b/NotificationService/Info.plist new file mode 100644 index 0000000..57421eb --- /dev/null +++ b/NotificationService/Info.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/NotificationService/NotificationService.swift b/NotificationService/NotificationService.swift new file mode 100644 index 0000000..6a5fd19 --- /dev/null +++ b/NotificationService/NotificationService.swift @@ -0,0 +1,69 @@ +// +// NotificationService.swift +// NotificationService +// +// Created by 湖北秦九 on 2025/11/10. +// + +import UserNotifications + +class NotificationService: UNNotificationServiceExtension { + + var contentHandler: ((UNNotificationContent) -> Void)? + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + + self.contentHandler = contentHandler + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + guard let bestAttemptContent = bestAttemptContent else { + contentHandler(request.content) + return + } + + if let options = request.content.userInfo["fcm_options"] as? [String : Any], + let imageURLString = options["image"] as? String, + let imageURL = URL(string: imageURLString) { + + downloadImage(from: imageURL) { attachment in + if let attachment = attachment { + bestAttemptContent.attachments = [attachment] + } + contentHandler(bestAttemptContent) + } + } else { + contentHandler(bestAttemptContent) + } + } + + override func serviceExtensionTimeWillExpire() { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + contentHandler(bestAttemptContent) + } + } + + private func downloadImage(from url: URL, completion: @escaping (UNNotificationAttachment?) -> Void) { + let task = URLSession.shared.downloadTask(with: url) { (downloadedUrl, _, error) in + guard let downloadedUrl = downloadedUrl else { + completion(nil) + return + } + + let tmpDir = FileManager.default.temporaryDirectory + let tmpFile = tmpDir.appendingPathComponent(url.lastPathComponent) + + do { + try FileManager.default.moveItem(at: downloadedUrl, to: tmpFile) + let attachment = try UNNotificationAttachment(identifier: UUID().uuidString, url: tmpFile, options: nil) + completion(attachment) + } catch { + completion(nil) + } + } + task.resume() + } + +} diff --git a/Podfile b/Podfile index 06a7d0b..322e6be 100755 --- a/Podfile +++ b/Podfile @@ -20,7 +20,7 @@ target 'Fableon' do pod 'YYText' pod 'Alamofire' pod 'SmartCodable' - pod 'JXPlayer', '~> 0.1.5' + pod 'JXPlayer', '~> 0.1.8' pod 'Kingfisher' pod 'SnapKit' pod 'FSPagerView' diff --git a/Podfile.lock b/Podfile.lock index c7d7b9c..1fb1ef7 100755 --- a/Podfile.lock +++ b/Podfile.lock @@ -50,9 +50,9 @@ PODS: - IQTextView (1.0.5): - IQKeyboardToolbar/Placeholderable - JXPagingView/Paging (2.1.3) - - JXPlayer (0.1.5): - - SJMediaCacheServer - - SJVideoPlayer + - JXPlayer (0.1.8): + - SJMediaCacheServer (= 2.1.6) + - SJVideoPlayer (= 3.4.3) - JXSegmentedView (1.4.1) - Kingfisher (8.5.0) - LYEmptyView (1.3.1) @@ -86,10 +86,10 @@ PODS: - SJUIKit/ObserverHelper - SJUIKit/Queues - SJUIKit/SQLite3 - - SJMediaCacheServer (2.1.7): - - SJMediaCacheServer/Core (= 2.1.7) + - SJMediaCacheServer (2.1.6): + - SJMediaCacheServer/Core (= 2.1.6) - SJUIKit/SQLite3 - - SJMediaCacheServer/Core (2.1.7): + - SJMediaCacheServer/Core (2.1.6): - SJUIKit/SQLite3 - SJUIKit/AttributesFactory (0.0.0.59): - SJUIKit/AttributesFactory/Deprecated (= 0.0.0.59) @@ -148,7 +148,7 @@ DEPENDENCIES: - HWPanModal - IQKeyboardManagerSwift - JXPagingView/Paging - - JXPlayer (~> 0.1.5) + - JXPlayer (~> 0.1.8) - JXSegmentedView - Kingfisher - LYEmptyView @@ -215,14 +215,14 @@ SPEC CHECKSUMS: IQTextInputViewNotification: 3b9fb27a16e7ee8958cc9092cfb07a1a9e1fd559 IQTextView: ae13b4922f22e6f027f62c557d9f4f236b19d5c7 JXPagingView: afdd2e9af09c90160dd232b970d603cc6e7ddd0e - JXPlayer: 0e0cd9a2ee406ebb3051d00c760cd5fc599bf09b + JXPlayer: 8ca57987b506419cb51a8c84e6196c25043634ca JXSegmentedView: cd73555ce2134d1656db2cb383ba9c2f36fb5078 Kingfisher: ff0d31a1f07bdff6a1ebb3ba08b8e6e567b6500c LYEmptyView: b6d418cfa38b78df0cf243f9a9c25ccbdc399922 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 MJRefresh: ff9e531227924c84ce459338414550a05d2aea78 SJBaseVideoPlayer: b3122de12225b27b71bd9a8a1f08f4dcf2f4e5ec - SJMediaCacheServer: 0ca17fcdd5340fe1d2ad03110e511376f290d924 + SJMediaCacheServer: f6cd08ff32f5c6fc18ff06e676b42d6c17ce4cf1 SJUIKit: a40111941e408cc17d4c1c23495aa92999e814b0 SJVideoPlayer: 4f09814f58522e0975cb2dccfda925f6c8643467 SmartCodable: 545dd052990fe7e80085463b79a1a5e462ee29ff @@ -234,6 +234,6 @@ SPEC CHECKSUMS: YYText: 5c461d709e24d55a182d1441c41dc639a18a4849 ZLPhotoBrowser: d5928f08485c90a0b349a3a1e804e82c83ccf193 -PODFILE CHECKSUM: ee93369942c41a1babdca4fd27a29e21997fc357 +PODFILE CHECKSUM: 0d6c1bc4222cac60ce66cfe1a22456b0a9cc1685 COCOAPODS: 1.16.2 diff --git a/账号信息/银行卡信息.txt b/账号信息/银行卡信息.txt index 075035f..84605f4 100644 --- a/账号信息/银行卡信息.txt +++ b/账号信息/银行卡信息.txt @@ -1,3 +1,7 @@ + +hb.qinjiu@icloud.com +Discover2024 + 账户持有人: Hubei Qinjiu Network Technology Co., Ltd 银行账号: