mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 17:51:01 +00:00
Make categorized emoji picker (#1680)
Signed-off-by: Euigyom Kim <egkim@dehol.kr>
This commit is contained in:
parent
1e35ffb82b
commit
d3b52b3206
4 changed files with 64 additions and 23 deletions
|
@ -13,4 +13,5 @@ public struct Emoji: Codable, Hashable, Identifiable, Equatable, Sendable {
|
|||
public let url: URL
|
||||
public let staticUrl: URL
|
||||
public let visibleInPicker: Bool
|
||||
public let category: String?
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ struct StatusEditorAccessoryView: View {
|
|||
}
|
||||
}
|
||||
|
||||
if !viewModel.customEmojis.isEmpty {
|
||||
if !viewModel.customEmojiContainer.isEmpty {
|
||||
Button {
|
||||
isCustomEmojisSheetDisplay = true
|
||||
} label: {
|
||||
|
@ -283,29 +283,37 @@ struct StatusEditorAccessoryView: View {
|
|||
private var customEmojisSheet: some View {
|
||||
NavigationStack {
|
||||
ScrollView {
|
||||
LazyVGrid(columns: [GridItem(.adaptive(minimum: 40))], spacing: 9) {
|
||||
ForEach(viewModel.customEmojis) { emoji in
|
||||
LazyImage(url: emoji.url) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 40, height: 40)
|
||||
.accessibilityLabel(emoji.shortcode.replacingOccurrences(of: "_", with: " "))
|
||||
.accessibilityAddTraits(.isButton)
|
||||
} else if state.isLoading {
|
||||
Rectangle()
|
||||
.fill(Color.gray)
|
||||
.frame(width: 40, height: 40)
|
||||
.accessibility(hidden: true)
|
||||
.shimmering()
|
||||
ForEach(viewModel.customEmojiContainer) { container in
|
||||
VStack(alignment: .leading) {
|
||||
Text(container.categoryName)
|
||||
.font(.scaledFootnote)
|
||||
LazyVGrid(columns: [GridItem(.adaptive(minimum: 40))], spacing: 9) {
|
||||
ForEach(container.emojis) { emoji in
|
||||
LazyImage(url: emoji.url) { state in
|
||||
if let image = state.image {
|
||||
image
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 40, height: 40)
|
||||
.accessibilityLabel(emoji.shortcode.replacingOccurrences(of: "_", with: " "))
|
||||
.accessibilityAddTraits(.isButton)
|
||||
} else if state.isLoading {
|
||||
Rectangle()
|
||||
.fill(Color.gray)
|
||||
.frame(width: 40, height: 40)
|
||||
.accessibility(hidden: true)
|
||||
.shimmering()
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
viewModel.insertStatusText(text: " :\(emoji.shortcode): ")
|
||||
}
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
viewModel.insertStatusText(text: " :\(emoji.shortcode): ")
|
||||
}
|
||||
}
|
||||
}.padding(.horizontal)
|
||||
.padding(.horizontal)
|
||||
.padding(.bottom)
|
||||
}
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import Foundation
|
||||
import Models
|
||||
|
||||
struct StatusEditorCategorizedEmojiContainer: Identifiable, Equatable {
|
||||
let id = UUID().uuidString
|
||||
let categoryName: String
|
||||
var emojis: [Emoji]
|
||||
}
|
|
@ -100,7 +100,7 @@ import SwiftUI
|
|||
var replyToStatus: Status?
|
||||
var embeddedStatus: Status?
|
||||
|
||||
var customEmojis: [Emoji] = []
|
||||
var customEmojiContainer: [StatusEditorCategorizedEmojiContainer] = []
|
||||
|
||||
var postingError: String?
|
||||
var showPostingErrorAlert: Bool = false
|
||||
|
@ -726,9 +726,33 @@ import SwiftUI
|
|||
// MARK: - Custom emojis
|
||||
|
||||
func fetchCustomEmojis() async {
|
||||
typealias EmojiContainer = StatusEditorCategorizedEmojiContainer
|
||||
|
||||
guard let client else { return }
|
||||
do {
|
||||
customEmojis = try await client.get(endpoint: CustomEmojis.customEmojis) ?? []
|
||||
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 ?? "Uncategorized"
|
||||
|
||||
if let emojis = dict[category] {
|
||||
dict[category] = emojis + [emoji]
|
||||
} else {
|
||||
dict[category] = [emoji]
|
||||
}
|
||||
|
||||
return dict
|
||||
}.sorted(by: { lhs, rhs in
|
||||
if rhs.key == "Uncategorized" { return false }
|
||||
else if lhs.key == "Uncategorized" { return true }
|
||||
else { return lhs.key < rhs.key }
|
||||
}).forEach { key, value in
|
||||
emojiContainers.append(.init(categoryName: key, emojis: value))
|
||||
}
|
||||
|
||||
customEmojiContainer = emojiContainers
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue