From c07be8c189ae809552e8cc549429921e5491fe7c Mon Sep 17 00:00:00 2001 From: Lain Iwakura Date: Fri, 8 Aug 2025 14:43:55 +0300 Subject: [PATCH] fully works ios 15 widgets! --- FavoritesWidget/AppIntent.swift | 19 --------- FavoritesWidget/FavoritesWidget.swift | 58 ++++++++++++++++++--------- MobileMkch.xcodeproj/project.pbxproj | 6 ++- MobileMkch/ThreadDetailView.swift | 4 +- 4 files changed, 45 insertions(+), 42 deletions(-) delete mode 100644 FavoritesWidget/AppIntent.swift diff --git a/FavoritesWidget/AppIntent.swift b/FavoritesWidget/AppIntent.swift deleted file mode 100644 index ef1eca8..0000000 --- a/FavoritesWidget/AppIntent.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// AppIntent.swift -// FavoritesWidget -// -// Created by Platon on 08.08.2025. -// - -import WidgetKit -import AppIntents - -struct ConfigurationAppIntent: WidgetConfigurationIntent, AppIntent { - static var title: LocalizedStringResource { "Конфигурация виджета" } - static var description: IntentDescription { "Выберите доску для загрузки в случае отсутствия доступа к данным приложения." } - - @Parameter(title: "Код доски", default: "b") - var boardCode: String - - static var openAppWhenRun: Bool { true } -} diff --git a/FavoritesWidget/FavoritesWidget.swift b/FavoritesWidget/FavoritesWidget.swift index 502650d..45b31aa 100644 --- a/FavoritesWidget/FavoritesWidget.swift +++ b/FavoritesWidget/FavoritesWidget.swift @@ -31,29 +31,38 @@ struct SimpleEntry: TimelineEntry { let offline: Bool } -struct Provider: AppIntentTimelineProvider { +struct Provider: TimelineProvider { func placeholder(in context: Context) -> SimpleEntry { - SimpleEntry(date: Date(), favorites: sample(), offline: false) + SimpleEntry(date: Date(), favorites: [ + FavoriteThreadWidget(id: 1, title: "Загрузка...", board: "b", boardDescription: "", addedDate: Date()) + ], offline: false) } - func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry { + func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { let favs = loadFavorites() if favs.isEmpty { - return SimpleEntry(date: Date(), favorites: await loadFromNetwork(board: configuration.boardCode), offline: false) + Task { + let networkFavs = await loadFromNetwork(board: "b") + completion(SimpleEntry(date: Date(), favorites: networkFavs, offline: false)) + } + } else { + completion(SimpleEntry(date: Date(), favorites: favs, offline: loadOffline())) } - return SimpleEntry(date: Date(), favorites: favs, offline: loadOffline()) } - func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline { - var favorites = loadFavorites() - var offline = loadOffline() - if favorites.isEmpty { - favorites = await loadFromNetwork(board: configuration.boardCode) - offline = false + func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { + Task { + var favorites = loadFavorites() + var offline = loadOffline() + if favorites.isEmpty { + favorites = await loadFromNetwork(board: "b") + offline = false + } + let entry = SimpleEntry(date: Date(), favorites: favorites, offline: offline) + let refresh = Calendar.current.date(byAdding: .minute, value: 15, to: Date()) ?? Date().addingTimeInterval(900) + let timeline = Timeline(entries: [entry], policy: .after(refresh)) + completion(timeline) } - let entry = SimpleEntry(date: Date(), favorites: favorites, offline: offline) - let refresh = Calendar.current.date(byAdding: .minute, value: 15, to: Date()) ?? Date().addingTimeInterval(900) - return Timeline(entries: [entry], policy: .after(refresh)) } private func loadFavorites() -> [FavoriteThreadWidget] { @@ -71,7 +80,7 @@ struct Provider: AppIntentTimelineProvider { } private func sample() -> [FavoriteThreadWidget] { - [FavoriteThreadWidget(id: 1, title: "Пример треда", board: "b", boardDescription: "Болталка", addedDate: Date())] + [] } private func loadFromNetwork(board: String) async -> [FavoriteThreadWidget] { @@ -102,8 +111,18 @@ struct FavoritesWidgetEntryView : View { } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) .padding(padding) - .foregroundStyle(.primary) - .containerBackground(.background, for: .widget) + .background( + Group { + if #available(iOS 17.0, *) { + Color.clear + .containerBackground(for: .widget) { + Color.clear + } + } else { + Color.clear + } + } + ) } private var spacing: CGFloat { family == .systemSmall ? 4 : 6 } @@ -116,6 +135,7 @@ struct FavoritesWidgetEntryView : View { HStack(spacing: 6) { Text("Избранное") .font(headerFont) + .foregroundColor(.primary) .lineLimit(1) .minimumScaleFactor(0.8) Spacer() @@ -137,6 +157,7 @@ struct FavoritesWidgetEntryView : View { BoardTag(code: fav.board) Text(fav.title) .font(titleFont) + .foregroundColor(.primary) .lineLimit(1) .truncationMode(.tail) } @@ -145,6 +166,7 @@ struct FavoritesWidgetEntryView : View { BoardTag(code: fav.board) Text(fav.title) .font(titleFont) + .foregroundColor(.primary) .lineLimit(2) .truncationMode(.tail) .multilineTextAlignment(.leading) @@ -172,7 +194,7 @@ struct FavoritesWidget: Widget { let kind: String = "FavoritesWidget" var body: some WidgetConfiguration { - AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in + StaticConfiguration(kind: kind, provider: Provider()) { entry in FavoritesWidgetEntryView(entry: entry) } .configurationDisplayName("Избранное MobileMkch") diff --git a/MobileMkch.xcodeproj/project.pbxproj b/MobileMkch.xcodeproj/project.pbxproj index 4f35b65..c998b26 100644 --- a/MobileMkch.xcodeproj/project.pbxproj +++ b/MobileMkch.xcodeproj/project.pbxproj @@ -272,6 +272,7 @@ INFOPLIST_FILE = FavoritesWidget/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = FavoritesWidget; INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.3; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -300,6 +301,7 @@ INFOPLIST_FILE = FavoritesWidget/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = FavoritesWidget; INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.3; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -459,7 +461,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = "2.1.0-ios"; + MARKETING_VERSION = "2.1.1-ios"; PRODUCT_BUNDLE_IDENTIFIER = com.mkch.MobileMkch; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -496,7 +498,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = "2.1.0-ios"; + MARKETING_VERSION = "2.1.1-ios"; PRODUCT_BUNDLE_IDENTIFIER = com.mkch.MobileMkch; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; diff --git a/MobileMkch/ThreadDetailView.swift b/MobileMkch/ThreadDetailView.swift index e91810c..372da34 100644 --- a/MobileMkch/ThreadDetailView.swift +++ b/MobileMkch/ThreadDetailView.swift @@ -107,9 +107,7 @@ struct ThreadDetailView: View { } .onAppear { if settings.liveActivityEnabled { - if #available(iOS 16.1, *) { - activityOn = LiveActivityManager.shared.isActive(threadId: thread.id) - } + activityOn = LiveActivityManager.shared.isActive(threadId: thread.id) } } }