fully works ios 15 widgets!
This commit is contained in:
parent
f1864dc2ba
commit
c07be8c189
@ -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 }
|
|
||||||
}
|
|
||||||
@ -31,29 +31,38 @@ struct SimpleEntry: TimelineEntry {
|
|||||||
let offline: Bool
|
let offline: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Provider: AppIntentTimelineProvider {
|
struct Provider: TimelineProvider {
|
||||||
func placeholder(in context: Context) -> SimpleEntry {
|
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()
|
let favs = loadFavorites()
|
||||||
if favs.isEmpty {
|
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<SimpleEntry> {
|
func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> ()) {
|
||||||
var favorites = loadFavorites()
|
Task {
|
||||||
var offline = loadOffline()
|
var favorites = loadFavorites()
|
||||||
if favorites.isEmpty {
|
var offline = loadOffline()
|
||||||
favorites = await loadFromNetwork(board: configuration.boardCode)
|
if favorites.isEmpty {
|
||||||
offline = false
|
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] {
|
private func loadFavorites() -> [FavoriteThreadWidget] {
|
||||||
@ -71,7 +80,7 @@ struct Provider: AppIntentTimelineProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func sample() -> [FavoriteThreadWidget] {
|
private func sample() -> [FavoriteThreadWidget] {
|
||||||
[FavoriteThreadWidget(id: 1, title: "Пример треда", board: "b", boardDescription: "Болталка", addedDate: Date())]
|
[]
|
||||||
}
|
}
|
||||||
|
|
||||||
private func loadFromNetwork(board: String) async -> [FavoriteThreadWidget] {
|
private func loadFromNetwork(board: String) async -> [FavoriteThreadWidget] {
|
||||||
@ -102,8 +111,18 @@ struct FavoritesWidgetEntryView : View {
|
|||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||||||
.padding(padding)
|
.padding(padding)
|
||||||
.foregroundStyle(.primary)
|
.background(
|
||||||
.containerBackground(.background, for: .widget)
|
Group {
|
||||||
|
if #available(iOS 17.0, *) {
|
||||||
|
Color.clear
|
||||||
|
.containerBackground(for: .widget) {
|
||||||
|
Color.clear
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Color.clear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var spacing: CGFloat { family == .systemSmall ? 4 : 6 }
|
private var spacing: CGFloat { family == .systemSmall ? 4 : 6 }
|
||||||
@ -116,6 +135,7 @@ struct FavoritesWidgetEntryView : View {
|
|||||||
HStack(spacing: 6) {
|
HStack(spacing: 6) {
|
||||||
Text("Избранное")
|
Text("Избранное")
|
||||||
.font(headerFont)
|
.font(headerFont)
|
||||||
|
.foregroundColor(.primary)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.minimumScaleFactor(0.8)
|
.minimumScaleFactor(0.8)
|
||||||
Spacer()
|
Spacer()
|
||||||
@ -137,6 +157,7 @@ struct FavoritesWidgetEntryView : View {
|
|||||||
BoardTag(code: fav.board)
|
BoardTag(code: fav.board)
|
||||||
Text(fav.title)
|
Text(fav.title)
|
||||||
.font(titleFont)
|
.font(titleFont)
|
||||||
|
.foregroundColor(.primary)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
}
|
}
|
||||||
@ -145,6 +166,7 @@ struct FavoritesWidgetEntryView : View {
|
|||||||
BoardTag(code: fav.board)
|
BoardTag(code: fav.board)
|
||||||
Text(fav.title)
|
Text(fav.title)
|
||||||
.font(titleFont)
|
.font(titleFont)
|
||||||
|
.foregroundColor(.primary)
|
||||||
.lineLimit(2)
|
.lineLimit(2)
|
||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
.multilineTextAlignment(.leading)
|
.multilineTextAlignment(.leading)
|
||||||
@ -172,7 +194,7 @@ struct FavoritesWidget: Widget {
|
|||||||
let kind: String = "FavoritesWidget"
|
let kind: String = "FavoritesWidget"
|
||||||
|
|
||||||
var body: some WidgetConfiguration {
|
var body: some WidgetConfiguration {
|
||||||
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
|
StaticConfiguration(kind: kind, provider: Provider()) { entry in
|
||||||
FavoritesWidgetEntryView(entry: entry)
|
FavoritesWidgetEntryView(entry: entry)
|
||||||
}
|
}
|
||||||
.configurationDisplayName("Избранное MobileMkch")
|
.configurationDisplayName("Избранное MobileMkch")
|
||||||
|
|||||||
@ -272,6 +272,7 @@
|
|||||||
INFOPLIST_FILE = FavoritesWidget/Info.plist;
|
INFOPLIST_FILE = FavoritesWidget/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = FavoritesWidget;
|
INFOPLIST_KEY_CFBundleDisplayName = FavoritesWidget;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -300,6 +301,7 @@
|
|||||||
INFOPLIST_FILE = FavoritesWidget/Info.plist;
|
INFOPLIST_FILE = FavoritesWidget/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = FavoritesWidget;
|
INFOPLIST_KEY_CFBundleDisplayName = FavoritesWidget;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -459,7 +461,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = "2.1.0-ios";
|
MARKETING_VERSION = "2.1.1-ios";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.mkch.MobileMkch;
|
PRODUCT_BUNDLE_IDENTIFIER = com.mkch.MobileMkch;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
@ -496,7 +498,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = "2.1.0-ios";
|
MARKETING_VERSION = "2.1.1-ios";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.mkch.MobileMkch;
|
PRODUCT_BUNDLE_IDENTIFIER = com.mkch.MobileMkch;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
|||||||
@ -107,9 +107,7 @@ struct ThreadDetailView: View {
|
|||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
if settings.liveActivityEnabled {
|
if settings.liveActivityEnabled {
|
||||||
if #available(iOS 16.1, *) {
|
activityOn = LiveActivityManager.shared.isActive(threadId: thread.id)
|
||||||
activityOn = LiveActivityManager.shared.isActive(threadId: thread.id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user