2024-01-26 22:58:57 +01:00
|
|
|
//Made by Lumaa
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
struct EmojiSelector: View {
|
|
|
|
@Environment(AccountManager.self) private var accountManager
|
|
|
|
|
2024-01-28 17:51:16 +01:00
|
|
|
@State private var loading: Bool = true
|
2024-01-26 22:58:57 +01:00
|
|
|
@State private var emojiContainers: [CategorizedEmojiContainer] = []
|
2024-01-28 17:51:16 +01:00
|
|
|
|
2024-02-04 10:44:51 +01:00
|
|
|
@State var viewModel: PostingView.ViewModel
|
2024-01-26 22:58:57 +01:00
|
|
|
|
|
|
|
var body: some View {
|
2024-02-04 10:44:51 +01:00
|
|
|
ZStack {
|
|
|
|
if loading {
|
|
|
|
ProgressView()
|
|
|
|
.ignoresSafeArea()
|
|
|
|
} else if !loading && !emojiContainers.isEmpty {
|
|
|
|
ScrollView(.vertical, showsIndicators: false) {
|
|
|
|
ForEach(emojiContainers) { container in
|
|
|
|
LazyVGrid(columns: [.init(.adaptive(minimum: 40, maximum: 40))]) {
|
|
|
|
Section {
|
|
|
|
ForEach(container.emojis) { emoji in
|
|
|
|
Button {
|
|
|
|
viewModel.append(text: ":\(emoji.shortcode):")
|
|
|
|
} label: {
|
|
|
|
OnlineImage(url: emoji.url, size: 40, useNuke: true)
|
|
|
|
}
|
|
|
|
.buttonStyle(NoTapAnimationStyle())
|
2024-01-26 22:58:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-04 10:44:51 +01:00
|
|
|
.padding()
|
|
|
|
.padding(.vertical)
|
|
|
|
} else {
|
|
|
|
ContentUnavailableView("status.posting.no-emojis", systemImage: "network.slash")
|
2024-01-26 22:58:57 +01:00
|
|
|
}
|
2024-02-04 10:44:51 +01:00
|
|
|
}
|
|
|
|
.task {
|
|
|
|
loading = true
|
|
|
|
await fetchCustomEmojis()
|
|
|
|
loading = false
|
2024-01-26 22:58:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CategorizedEmojiContainer: Identifiable, Equatable {
|
|
|
|
let id = UUID().uuidString
|
|
|
|
let categoryName: String
|
|
|
|
var emojis: [Emoji]
|
|
|
|
}
|
|
|
|
|
|
|
|
private func fetchCustomEmojis() async {
|
|
|
|
typealias EmojiContainer = CategorizedEmojiContainer
|
|
|
|
|
|
|
|
guard let client = accountManager.getClient() else { return }
|
|
|
|
do {
|
|
|
|
let customEmojis: [Emoji] = try await client.get(endpoint: CustomEmojis.customEmojis) ?? []
|
|
|
|
var emojiContainers: [EmojiContainer] = []
|
|
|
|
|
|
|
|
customEmojis.reduce([String: [Emoji]]()) { currentDict, emoji in
|
|
|
|
var dict = currentDict
|
|
|
|
let category = emoji.category ?? "Custom"
|
|
|
|
|
|
|
|
if let emojis = dict[category] {
|
|
|
|
dict[category] = emojis + [emoji]
|
|
|
|
} else {
|
|
|
|
dict[category] = [emoji]
|
|
|
|
}
|
|
|
|
|
|
|
|
return dict
|
|
|
|
}.sorted(by: { lhs, rhs in
|
|
|
|
if rhs.key == "Custom" { false }
|
|
|
|
else if lhs.key == "Custom" { true }
|
|
|
|
else { lhs.key < rhs.key }
|
|
|
|
}).forEach { key, value in
|
|
|
|
emojiContainers.append(.init(categoryName: key, emojis: value))
|
|
|
|
}
|
|
|
|
|
|
|
|
self.emojiContainers = emojiContainers
|
|
|
|
} catch {}
|
|
|
|
}
|
|
|
|
}
|