Organize expanded custom emoji picker by category

Closes #223
This commit is contained in:
Shadowfacts 2022-11-28 22:13:06 -05:00
parent 08c63a2f84
commit 21874b0966
2 changed files with 38 additions and 6 deletions

View File

@ -16,6 +16,7 @@ public class Emoji: Codable {
public let url: WebURL public let url: WebURL
public let staticURL: WebURL public let staticURL: WebURL
public let visibleInPicker: Bool public let visibleInPicker: Bool
public let category: String?
public required init(from decoder: Decoder) throws { public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self) let container = try decoder.container(keyedBy: CodingKeys.self)
@ -24,6 +25,7 @@ public class Emoji: Codable {
self.url = try container.decode(WebURL.self, forKey: .url) self.url = try container.decode(WebURL.self, forKey: .url)
self.staticURL = try container.decode(WebURL.self, forKey: .staticURL) self.staticURL = try container.decode(WebURL.self, forKey: .staticURL)
self.visibleInPicker = try container.decode(Bool.self, forKey: .visibleInPicker) self.visibleInPicker = try container.decode(Bool.self, forKey: .visibleInPicker)
self.category = try container.decodeIfPresent(String.self, forKey: .category)
} }
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
@ -31,6 +33,7 @@ public class Emoji: Codable {
case url case url
case staticURL = "static_url" case staticURL = "static_url"
case visibleInPicker = "visible_in_picker" case visibleInPicker = "visible_in_picker"
case category
} }
} }

View File

@ -176,6 +176,19 @@ struct ComposeAutocompleteEmojisView: View {
@State private var emojis: [Emoji] = [] @State private var emojis: [Emoji] = []
@ScaledMetric private var emojiSize = 30 @ScaledMetric private var emojiSize = 30
private var emojisBySection: [String: [Emoji]] {
var values: [String: [Emoji]] = [:]
for emoji in emojis {
let key = emoji.category ?? ""
if !values.keys.contains(key) {
values[key] = [emoji]
} else {
values[key]!.append(emoji)
}
}
return values
}
var body: some View { var body: some View {
// When exapnded, the toggle button should be at the top. When collapsed, it should be centered. // When exapnded, the toggle button should be at the top. When collapsed, it should be centered.
HStack(alignment: expanded ? .top : .center, spacing: 0) { HStack(alignment: expanded ? .top : .center, spacing: 0) {
@ -214,12 +227,28 @@ struct ComposeAutocompleteEmojisView: View {
private var verticalGrid: some View { private var verticalGrid: some View {
ScrollView { ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: emojiSize), spacing: 4)]) { LazyVGrid(columns: [GridItem(.adaptive(minimum: emojiSize), spacing: 4)]) {
ForEach(emojis, id: \.shortcode) { (emoji) in ForEach(emojisBySection.keys.sorted(), id: \.self) { section in
Button { Section {
uiState.currentInput?.autocomplete(with: ":\(emoji.shortcode):") ForEach(emojisBySection[section]!, id: \.shortcode) { emoji in
} label: { Button {
CustomEmojiImageView(emoji: emoji) uiState.currentInput?.autocomplete(with: ":\(emoji.shortcode):")
.frame(height: emojiSize) } label: {
CustomEmojiImageView(emoji: emoji)
.frame(height: emojiSize)
}
}
} header: {
if !section.isEmpty {
VStack(alignment: .leading, spacing: 2) {
Text(section)
.font(.caption)
Rectangle()
.foregroundColor(Color(.separator))
.frame(height: 0.5)
}
.padding(.top, 4)
}
} }
} }
} }