diff --git a/StickerSlack.xcodeproj/project.pbxproj b/StickerSlack.xcodeproj/project.pbxproj index 2ddd742..ac583bf 100644 --- a/StickerSlack.xcodeproj/project.pbxproj +++ b/StickerSlack.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ A9104C802EB4022500D160EA /* MSSticker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9104C7D2EB4022500D160EA /* MSSticker.swift */; }; A921C2DF2ED067BB00E57B1A /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A921C2DE2ED067BB00E57B1A /* WelcomeView.swift */; }; A921C2E02ED067BB00E57B1A /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A921C2DE2ED067BB00E57B1A /* WelcomeView.swift */; }; + A921C2E22ED071C900E57B1A /* ListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A921C2E12ED071C900E57B1A /* ListRow.swift */; }; + A921C2E32ED071C900E57B1A /* ListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A921C2E12ED071C900E57B1A /* ListRow.swift */; }; A924C3732EA9127200F20781 /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = A924C3712EA9127200F20781 /* Emoji.swift */; }; A924C3782EA9225800F20781 /* Haptics in Frameworks */ = {isa = PBXBuildFile; productRef = A924C3772EA9225800F20781 /* Haptics */; }; A931D4082EBC9646007BC75B /* Haptics in Frameworks */ = {isa = PBXBuildFile; productRef = A931D4072EBC9646007BC75B /* Haptics */; }; @@ -110,6 +112,7 @@ A9104C732EB3AE4700D160EA /* StickerSlack.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = StickerSlack.icon; sourceTree = ""; }; A9104C7D2EB4022500D160EA /* MSSticker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSSticker.swift; sourceTree = ""; }; A921C2DE2ED067BB00E57B1A /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; }; + A921C2E12ED071C900E57B1A /* ListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRow.swift; sourceTree = ""; }; A924C3712EA9127200F20781 /* Emoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Emoji.swift; sourceTree = ""; }; A924C3742EA9134C00F20781 /* StickerSlack.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = StickerSlack.entitlements; sourceTree = ""; }; A935437A2EB2A3C800BB80A4 /* FilterCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterCategory.swift; sourceTree = ""; }; @@ -241,6 +244,7 @@ A955B3F42EC22EE900E1732D /* SearchView.swift */, A957C1732ECCE2CE00EA3EE9 /* SettingsView.swift */, A921C2DE2ED067BB00E57B1A /* WelcomeView.swift */, + A921C2E12ED071C900E57B1A /* ListRow.swift */, ); path = SwiftUI; sourceTree = ""; @@ -503,6 +507,7 @@ A949B1F82EA04F2300215164 /* EmojiHoarder.swift in Sources */, A9BBC5182EB8FA4500FFE82F /* ViewModifiers.swift in Sources */, A9EB72492EB948C400658CEB /* EmojiRow.swift in Sources */, + A921C2E22ED071C900E57B1A /* ListRow.swift in Sources */, A9773C2F2EA54AF000F3B753 /* EmojiPreview.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -533,6 +538,7 @@ A9B9A8302EB2CD0B004C9245 /* Emoji.swift in Sources */, A955B3F12EC22E9700E1732D /* BrowseView.swift in Sources */, A9B9A82F2EB2CCED004C9245 /* EmojiHoarder.swift in Sources */, + A921C2E32ED071C900E57B1A /* ListRow.swift in Sources */, A9EB724A2EB948E000658CEB /* EmojiCollectionView.swift in Sources */, A9EB724D2EB94A6B00658CEB /* TrieTestingView.swift in Sources */, A9BBC51A2EB8FA4500FFE82F /* ViewModifiers.swift in Sources */, diff --git a/StickerSlack/Emoji/EmojiHoarder.swift b/StickerSlack/Emoji/EmojiHoarder.swift index 45640b3..033ea6c 100644 --- a/StickerSlack/Emoji/EmojiHoarder.swift +++ b/StickerSlack/Emoji/EmojiHoarder.swift @@ -26,7 +26,9 @@ class EmojiHoarder: ObservableObject { @Published var downloadedEmojis: Set = [] @Published var downloadedEmojisArr: [String] = [] @Published var searchTerm: String = "" + @Published var letterStats: [EmojiHoarder.LetterStat] = [] + @Published var letterStatsSorting: EmojiHoarder.LetterStatSorting = .init(by: .letter, ascending: true) @Published var showWelcome: Bool = true @@ -115,6 +117,7 @@ class EmojiHoarder: ObservableObject { } buildTrieDict() saveTrie() + generateLetterStats() print("done building trie in", Date().timeIntervalSince1970-start) } @@ -206,20 +209,52 @@ class EmojiHoarder: ObservableObject { self.showWelcome = newValue } - func generateLetterStats() -> [EmojiHoarder.LetterStat] { + func generateLetterStats() { var result: [EmojiHoarder.LetterStat] = [] for child in trie.root.children { let count = trie.collectWords(startingWith: child.key, from: child.value).count let stat = LetterStat(char: child.key, count: count) result.append(stat) } - return result + self.letterStats = result + sortLetterStats(by: self.letterStatsSorting) + } + + func sortLetterStats(by: EmojiHoarder.LetterStatSorting) { + self.letterStatsSorting = by + let sortByLetter = letterStatsSorting.by == .letter + switch by.ascending { + case true: + letterStats.sort { + if sortByLetter { + $0.char > $1.char + } else { + $0.count > $1.count + } + } + case false: + letterStats.sort { + if sortByLetter { + $0.char > $1.char + } else { + $0.count < $1.count + } + } + } } struct LetterStat: Hashable { var char: String var count: Int } + enum SortLetterStatsBy: String, CaseIterable { + case letter = "Letter" + case count = "Count" + } + struct LetterStatSorting: Hashable, Equatable { + var by: EmojiHoarder.SortLetterStatsBy = .count + var ascending: Bool = true + } // func filterEmojis(byCategory category: FilterCategory, searchTerm: String) { // guard category != .none else { diff --git a/StickerSlack/SwiftUI/ListRow.swift b/StickerSlack/SwiftUI/ListRow.swift new file mode 100644 index 0000000..c31d01b --- /dev/null +++ b/StickerSlack/SwiftUI/ListRow.swift @@ -0,0 +1,26 @@ +// +// ListRow.swift +// StickerSlack +// +// Created by neon443 on 21/11/2025. +// + +import SwiftUI + +struct ListRow: View { + @State var number: Int + @State var text: String + + var body: some View { + HStack { + Text("\(number)") + .padding(.trailing, 10) + .foregroundStyle(.gray) + Text(text) + } + } +} + +#Preview { + ListRow(number: 1, text: "hi!") +} diff --git a/StickerSlack/SwiftUI/SettingsView.swift b/StickerSlack/SwiftUI/SettingsView.swift index a6c7172..d33df8a 100644 --- a/StickerSlack/SwiftUI/SettingsView.swift +++ b/StickerSlack/SwiftUI/SettingsView.swift @@ -39,8 +39,29 @@ struct SettingsView: View { Text("\(hoarder.downloadedEmojis.count) downloaded Emoji") NavigationLink { List { - ForEach(hoarder.generateLetterStats(), id: \.self) { stat in - Text("\(stat.count) Emoji starting with \(stat.char)") + Picker(selection: $hoarder.letterStatsSorting.by) { + ForEach(EmojiHoarder.SortLetterStatsBy.allCases, id: \.self) { sortType in + Text(sortType.rawValue).tag(sortType) + } + } label: { + Label("Sort by", systemImage: "arrow.up.arrow.down") + } + Picker(selection: $hoarder.letterStatsSorting.ascending) { + Text("Ascending").tag(true) + Text("Descending").tag(false) + } label: { + Label("Order", systemImage: "greaterthan") + } + .onChange(of: hoarder.letterStatsSorting) { _ in + hoarder.sortLetterStats(by: hoarder.letterStatsSorting) + } + + ForEach(hoarder.letterStats, id: \.self) { stat in + HStack { + Text("\(stat.char)") + Spacer() + Text("\(stat.count)") + } } } } label: { diff --git a/StickerSlack/SwiftUI/WelcomeView.swift b/StickerSlack/SwiftUI/WelcomeView.swift index 1dd5442..96d013d 100644 --- a/StickerSlack/SwiftUI/WelcomeView.swift +++ b/StickerSlack/SwiftUI/WelcomeView.swift @@ -30,20 +30,6 @@ struct WelcomeView: View { } } -struct ListRow: View { - @State var number: Int - @State var text: String - - var body: some View { - HStack { - Text("\(number)") - .padding(.trailing, 10) - .foregroundStyle(.gray) - Text(text) - } - } -} - #Preview { WelcomeView() }