From 21874b09661eb613cb609706f391ee5ed26d057e Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 28 Nov 2022 22:13:06 -0500 Subject: [PATCH] Organize expanded custom emoji picker by category Closes #223 --- Pachyderm/Sources/Pachyderm/Model/Emoji.swift | 3 ++ .../Compose/ComposeAutocompleteView.swift | 41 ++++++++++++++++--- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/Pachyderm/Sources/Pachyderm/Model/Emoji.swift b/Pachyderm/Sources/Pachyderm/Model/Emoji.swift index 9d85a3dae2..505fafb8bb 100644 --- a/Pachyderm/Sources/Pachyderm/Model/Emoji.swift +++ b/Pachyderm/Sources/Pachyderm/Model/Emoji.swift @@ -16,6 +16,7 @@ public class Emoji: Codable { public let url: WebURL public let staticURL: WebURL public let visibleInPicker: Bool + public let category: String? public required init(from decoder: Decoder) throws { 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.staticURL = try container.decode(WebURL.self, forKey: .staticURL) self.visibleInPicker = try container.decode(Bool.self, forKey: .visibleInPicker) + self.category = try container.decodeIfPresent(String.self, forKey: .category) } private enum CodingKeys: String, CodingKey { @@ -31,6 +33,7 @@ public class Emoji: Codable { case url case staticURL = "static_url" case visibleInPicker = "visible_in_picker" + case category } } diff --git a/Tusker/Screens/Compose/ComposeAutocompleteView.swift b/Tusker/Screens/Compose/ComposeAutocompleteView.swift index 39265460b0..e7bf458244 100644 --- a/Tusker/Screens/Compose/ComposeAutocompleteView.swift +++ b/Tusker/Screens/Compose/ComposeAutocompleteView.swift @@ -176,6 +176,19 @@ struct ComposeAutocompleteEmojisView: View { @State private var emojis: [Emoji] = [] @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 { // When exapnded, the toggle button should be at the top. When collapsed, it should be centered. HStack(alignment: expanded ? .top : .center, spacing: 0) { @@ -214,12 +227,28 @@ struct ComposeAutocompleteEmojisView: View { private var verticalGrid: some View { ScrollView { LazyVGrid(columns: [GridItem(.adaptive(minimum: emojiSize), spacing: 4)]) { - ForEach(emojis, id: \.shortcode) { (emoji) in - Button { - uiState.currentInput?.autocomplete(with: ":\(emoji.shortcode):") - } label: { - CustomEmojiImageView(emoji: emoji) - .frame(height: emojiSize) + ForEach(emojisBySection.keys.sorted(), id: \.self) { section in + Section { + ForEach(emojisBySection[section]!, id: \.shortcode) { emoji in + Button { + uiState.currentInput?.autocomplete(with: ":\(emoji.shortcode):") + } 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) + } } } }