Implement first working version of widget (IOS-37)
There's still plenty of stuff to do, like: Show text (instead of source) and configure the hashtag ... you know the paretro principle)
This commit is contained in:
parent
50945f5285
commit
7b59fdf3bc
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import WidgetKit
|
import WidgetKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import MastodonSDK
|
||||||
|
|
||||||
struct HashtagWidgetProvider: IntentTimelineProvider {
|
struct HashtagWidgetProvider: IntentTimelineProvider {
|
||||||
func placeholder(in context: Context) -> HashtagWidgetTimelineEntry {
|
func placeholder(in context: Context) -> HashtagWidgetTimelineEntry {
|
||||||
|
@ -21,17 +22,70 @@ struct HashtagWidgetProvider: IntentTimelineProvider {
|
||||||
|
|
||||||
extension HashtagWidgetProvider {
|
extension HashtagWidgetProvider {
|
||||||
func loadMostRecentHashtag(for configuration: HashtagIntent, in context: Context, completion: @escaping (HashtagWidgetTimelineEntry) -> Void ) {
|
func loadMostRecentHashtag(for configuration: HashtagIntent, in context: Context, completion: @escaping (HashtagWidgetTimelineEntry) -> Void ) {
|
||||||
let hashtagTimelineEntry = HashtagWidgetTimelineEntry.placeholder
|
|
||||||
|
guard
|
||||||
|
let authBox = WidgetExtension.appContext
|
||||||
|
.authenticationService
|
||||||
|
.mastodonAuthenticationBoxes
|
||||||
|
.first
|
||||||
|
else {
|
||||||
|
if context.isPreview {
|
||||||
|
return completion(.placeholder)
|
||||||
|
} else {
|
||||||
|
return completion(.unconfigured)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Task {
|
||||||
|
let desiredHashtag: String
|
||||||
|
|
||||||
|
if let hashtag = configuration.hashtag {
|
||||||
|
desiredHashtag = hashtag
|
||||||
|
} else {
|
||||||
|
return completion(.notFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
let mostRecentStatuses = try await WidgetExtension.appContext
|
||||||
|
.apiService
|
||||||
|
.hashtagTimeline(domain: authBox.domain, limit: 1, hashtag: desiredHashtag, authenticationBox: authBox)
|
||||||
|
.value
|
||||||
|
|
||||||
|
if let mostRecentStatus = mostRecentStatuses.first {
|
||||||
|
|
||||||
|
let hashtagEntry = HashtagEntry(
|
||||||
|
accountName: mostRecentStatus.account.displayNameWithFallback,
|
||||||
|
account: mostRecentStatus.account.acct,
|
||||||
|
content: mostRecentStatus.content ?? "-",
|
||||||
|
reblogCount: mostRecentStatus.reblogsCount,
|
||||||
|
favoriteCount: mostRecentStatus.favouritesCount,
|
||||||
|
hashtag: "#\(desiredHashtag)",
|
||||||
|
timestamp: mostRecentStatus.createdAt
|
||||||
|
)
|
||||||
|
|
||||||
|
let hashtagTimelineEntry = HashtagWidgetTimelineEntry(
|
||||||
|
date: mostRecentStatus.createdAt,
|
||||||
|
hashtag: hashtagEntry
|
||||||
|
)
|
||||||
|
|
||||||
completion(hashtagTimelineEntry)
|
completion(hashtagTimelineEntry)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
completion(.notFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HashtagWidgetTimelineEntry: TimelineEntry {
|
struct HashtagWidgetTimelineEntry: TimelineEntry {
|
||||||
var date: Date
|
var date: Date
|
||||||
//TODO: implement, add relevant information
|
|
||||||
var hashtag: HashtagEntry
|
var hashtag: HashtagEntry
|
||||||
|
|
||||||
static var placeholder: Self {
|
static var placeholder: Self {
|
||||||
|
//TODO: @zeitschlag Add Localization
|
||||||
HashtagWidgetTimelineEntry(
|
HashtagWidgetTimelineEntry(
|
||||||
date: .now,
|
date: .now,
|
||||||
hashtag: HashtagEntry(
|
hashtag: HashtagEntry(
|
||||||
|
@ -40,7 +94,39 @@ struct HashtagWidgetTimelineEntry: TimelineEntry {
|
||||||
content: "Caturday is the best day of the week #CatsOfMastodon",
|
content: "Caturday is the best day of the week #CatsOfMastodon",
|
||||||
reblogCount: 13,
|
reblogCount: 13,
|
||||||
favoriteCount: 12,
|
favoriteCount: 12,
|
||||||
hashtag: "#CatsOfMastodon")
|
hashtag: "#CatsOfMastodon",
|
||||||
|
timestamp: .now.addingTimeInterval(-3600 * 18)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var notFound: Self {
|
||||||
|
HashtagWidgetTimelineEntry(
|
||||||
|
date: .now,
|
||||||
|
hashtag: HashtagEntry(
|
||||||
|
accountName: "Not Found",
|
||||||
|
account: "404",
|
||||||
|
content: "Couldn't find a status, sorryyyyyyy",
|
||||||
|
reblogCount: 0,
|
||||||
|
favoriteCount: 0,
|
||||||
|
hashtag: "",
|
||||||
|
timestamp: .now
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var unconfigured: Self {
|
||||||
|
HashtagWidgetTimelineEntry(
|
||||||
|
date: .now,
|
||||||
|
hashtag: HashtagEntry(
|
||||||
|
accountName: "Unconfigured",
|
||||||
|
account: "@unconfigured@mastodon.social",
|
||||||
|
content: "Caturday is the best day of the week #CatsOfMastodon",
|
||||||
|
reblogCount: 14,
|
||||||
|
favoriteCount: 13,
|
||||||
|
hashtag: "#CatsOfMastodon",
|
||||||
|
timestamp: .now.addingTimeInterval(-3600 * 18)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +145,7 @@ struct HashtagWidget: Widget {
|
||||||
IntentConfiguration(kind: "Hashtag", intent: HashtagIntent.self, provider: HashtagWidgetProvider()) { entry in
|
IntentConfiguration(kind: "Hashtag", intent: HashtagIntent.self, provider: HashtagWidgetProvider()) { entry in
|
||||||
HashtagWidgetView(entry: entry)
|
HashtagWidgetView(entry: entry)
|
||||||
}
|
}
|
||||||
|
//TODO: @zeitschlag Add Localization
|
||||||
.configurationDisplayName("Hashtag")
|
.configurationDisplayName("Hashtag")
|
||||||
.description("Show a Hashtag")
|
.description("Show a Hashtag")
|
||||||
.supportedFamilies(availableFamilies)
|
.supportedFamilies(availableFamilies)
|
||||||
|
@ -72,4 +159,5 @@ struct HashtagEntry {
|
||||||
var reblogCount: Int
|
var reblogCount: Int
|
||||||
var favoriteCount: Int
|
var favoriteCount: Int
|
||||||
var hashtag: String
|
var hashtag: String
|
||||||
|
var timestamp: Date
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,14 @@ struct HashtagWidgetView: View {
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
Text("18h") //TODO: Implement
|
Text(entry.hashtag.timestamp.localizedShortTimeAgo(since: .now))
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Check MetaLabelRepresentable, maybe it's a way to color Hashtags?
|
||||||
Text(entry.hashtag.content)
|
Text(entry.hashtag.content)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
HStack(alignment: .center, spacing: 16) {
|
HStack(alignment: .center, spacing: 16) {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
|
|
Loading…
Reference in New Issue