adding gifs

added sticker.swift to add a protocol for stickers and an extension that has shared default implementations of functions and computed properties
added stickertype enum
This commit is contained in:
Nihaal Sharma
2026-03-06 23:46:09 +00:00
parent 23670efcfb
commit 2b8c636945
10 changed files with 215 additions and 61 deletions

View File

@@ -63,6 +63,17 @@
A9BBC5182EB8FA4500FFE82F /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */; }; A9BBC5182EB8FA4500FFE82F /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */; };
A9BBC5192EB8FA4500FFE82F /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */; }; A9BBC5192EB8FA4500FFE82F /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */; };
A9BBC51A2EB8FA4500FFE82F /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */; }; A9BBC51A2EB8FA4500FFE82F /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */; };
A9BE30EC2F5AFE1E00A57668 /* StickerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30EB2F5AFE1E00A57668 /* StickerType.swift */; };
A9BE30EF2F5B004800A57668 /* GifHoarder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30EE2F5B004800A57668 /* GifHoarder.swift */; };
A9BE30F02F5B004800A57668 /* GifHoarder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30EE2F5B004800A57668 /* GifHoarder.swift */; };
A9BE30F22F5B004E00A57668 /* Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F12F5B004E00A57668 /* Gif.swift */; };
A9BE30F32F5B004E00A57668 /* Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F12F5B004E00A57668 /* Gif.swift */; };
A9BE30F62F5B011A00A57668 /* StickerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F52F5B011A00A57668 /* StickerProtocol.swift */; };
A9BE30F72F5B011A00A57668 /* StickerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F52F5B011A00A57668 /* StickerProtocol.swift */; };
A9BE30F82F5B02BF00A57668 /* StickerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F52F5B011A00A57668 /* StickerProtocol.swift */; };
A9BE30FA2F5B03F400A57668 /* Sticker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F92F5B03F400A57668 /* Sticker.swift */; };
A9BE30FB2F5B03F400A57668 /* Sticker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F92F5B03F400A57668 /* Sticker.swift */; };
A9BE30FC2F5B03F400A57668 /* Sticker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BE30F92F5B03F400A57668 /* Sticker.swift */; };
A9C172DC2EB8C9AC008A7885 /* Trie.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C172DB2EB8C9AC008A7885 /* Trie.swift */; }; A9C172DC2EB8C9AC008A7885 /* Trie.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C172DB2EB8C9AC008A7885 /* Trie.swift */; };
A9C172DD2EB8C9AC008A7885 /* Trie.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C172DB2EB8C9AC008A7885 /* Trie.swift */; }; A9C172DD2EB8C9AC008A7885 /* Trie.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C172DB2EB8C9AC008A7885 /* Trie.swift */; };
A9CD6C352EDDE22800B7F421 /* EmojiPackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CD6C342EDDE22800B7F421 /* EmojiPackView.swift */; }; A9CD6C352EDDE22800B7F421 /* EmojiPackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CD6C342EDDE22800B7F421 /* EmojiPackView.swift */; };
@@ -148,6 +159,11 @@
A9B9A8232EB2CCB5004C9245 /* StickerSlackTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StickerSlackTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; A9B9A8232EB2CCB5004C9245 /* StickerSlackTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StickerSlackTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A9B9A82C2EB2CCBE004C9245 /* StickerSlackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerSlackTests.swift; sourceTree = "<group>"; }; A9B9A82C2EB2CCBE004C9245 /* StickerSlackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerSlackTests.swift; sourceTree = "<group>"; };
A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModifiers.swift; sourceTree = "<group>"; }; A9BBC5172EB8FA4500FFE82F /* ViewModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModifiers.swift; sourceTree = "<group>"; };
A9BE30EB2F5AFE1E00A57668 /* StickerType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerType.swift; sourceTree = "<group>"; };
A9BE30EE2F5B004800A57668 /* GifHoarder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GifHoarder.swift; sourceTree = "<group>"; };
A9BE30F12F5B004E00A57668 /* Gif.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Gif.swift; sourceTree = "<group>"; };
A9BE30F52F5B011A00A57668 /* StickerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerProtocol.swift; sourceTree = "<group>"; };
A9BE30F92F5B03F400A57668 /* Sticker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sticker.swift; sourceTree = "<group>"; };
A9C172DB2EB8C9AC008A7885 /* Trie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Trie.swift; sourceTree = "<group>"; }; A9C172DB2EB8C9AC008A7885 /* Trie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Trie.swift; sourceTree = "<group>"; };
A9CD6C342EDDE22800B7F421 /* EmojiPackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPackView.swift; sourceTree = "<group>"; }; A9CD6C342EDDE22800B7F421 /* EmojiPackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPackView.swift; sourceTree = "<group>"; };
A9CD6C372EDDE37500B7F421 /* EmojiPackManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPackManager.swift; sourceTree = "<group>"; }; A9CD6C372EDDE37500B7F421 /* EmojiPackManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPackManager.swift; sourceTree = "<group>"; };
@@ -295,6 +311,9 @@
children = ( children = (
A924C3742EA9134C00F20781 /* StickerSlack.entitlements */, A924C3742EA9134C00F20781 /* StickerSlack.entitlements */,
A949B1F12EA04E8200215164 /* StickerSlackApp.swift */, A949B1F12EA04E8200215164 /* StickerSlackApp.swift */,
A9BE30EB2F5AFE1E00A57668 /* StickerType.swift */,
A9BE30F42F5B011400A57668 /* Stickers */,
A9BE30ED2F5B003A00A57668 /* Gifs */,
A949B1F92EA0517800215164 /* Emoji */, A949B1F92EA0517800215164 /* Emoji */,
A91C09892EBBD75A00210C34 /* Trie */, A91C09892EBBD75A00210C34 /* Trie */,
A9104C812EB4022E00D160EA /* Extensions */, A9104C812EB4022E00D160EA /* Extensions */,
@@ -347,6 +366,24 @@
path = StickerSlackTests; path = StickerSlackTests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
A9BE30ED2F5B003A00A57668 /* Gifs */ = {
isa = PBXGroup;
children = (
A9BE30F12F5B004E00A57668 /* Gif.swift */,
A9BE30EE2F5B004800A57668 /* GifHoarder.swift */,
);
path = Gifs;
sourceTree = "<group>";
};
A9BE30F42F5B011400A57668 /* Stickers */ = {
isa = PBXGroup;
children = (
A9BE30F52F5B011A00A57668 /* StickerProtocol.swift */,
A9BE30F92F5B03F400A57668 /* Sticker.swift */,
);
path = Stickers;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@@ -515,12 +552,17 @@
A9EB724F2EB94A6B00658CEB /* TrieTestingView.swift in Sources */, A9EB724F2EB94A6B00658CEB /* TrieTestingView.swift in Sources */,
A924C3732EA9127200F20781 /* Emoji.swift in Sources */, A924C3732EA9127200F20781 /* Emoji.swift in Sources */,
A9D15B8B2EB1142C00404792 /* EmojiPack.swift in Sources */, A9D15B8B2EB1142C00404792 /* EmojiPack.swift in Sources */,
A9BE30FB2F5B03F400A57668 /* Sticker.swift in Sources */,
A9BE30F62F5B011A00A57668 /* StickerProtocol.swift in Sources */,
A921C2DF2ED067BB00E57B1A /* WelcomeView.swift in Sources */, A921C2DF2ED067BB00E57B1A /* WelcomeView.swift in Sources */,
A949B1F82EA04F2300215164 /* EmojiHoarder.swift in Sources */, A949B1F82EA04F2300215164 /* EmojiHoarder.swift in Sources */,
A9BBC5182EB8FA4500FFE82F /* ViewModifiers.swift in Sources */, A9BBC5182EB8FA4500FFE82F /* ViewModifiers.swift in Sources */,
A9EB72492EB948C400658CEB /* EmojiRow.swift in Sources */, A9EB72492EB948C400658CEB /* EmojiRow.swift in Sources */,
A921C2E22ED071C900E57B1A /* ListRow.swift in Sources */, A921C2E22ED071C900E57B1A /* ListRow.swift in Sources */,
A9773C2F2EA54AF000F3B753 /* EmojiPreview.swift in Sources */, A9773C2F2EA54AF000F3B753 /* EmojiPreview.swift in Sources */,
A9BE30F02F5B004800A57668 /* GifHoarder.swift in Sources */,
A9BE30F22F5B004E00A57668 /* Gif.swift in Sources */,
A9BE30EC2F5AFE1E00A57668 /* StickerType.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -529,9 +571,11 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A957C17B2ECE542D00EA3EE9 /* GifManager.swift in Sources */, A957C17B2ECE542D00EA3EE9 /* GifManager.swift in Sources */,
A9BE30F82F5B02BF00A57668 /* StickerProtocol.swift in Sources */,
A986A6C32EB6598100B6E0FA /* FilterCategory.swift in Sources */, A986A6C32EB6598100B6E0FA /* FilterCategory.swift in Sources */,
A9CD6C3A2EDDE6B500B7F421 /* EmojiPack.swift in Sources */, A9CD6C3A2EDDE6B500B7F421 /* EmojiPack.swift in Sources */,
A9EB724B2EB94A5700658CEB /* Trie.swift in Sources */, A9EB724B2EB94A5700658CEB /* Trie.swift in Sources */,
A9BE30FA2F5B03F400A57668 /* Sticker.swift in Sources */,
A986A6CD2EB659E000B6E0FA /* MessagesViewController.swift in Sources */, A986A6CD2EB659E000B6E0FA /* MessagesViewController.swift in Sources */,
A986A6CE2EB659E000B6E0FA /* StickerBrowserDataSource.swift in Sources */, A986A6CE2EB659E000B6E0FA /* StickerBrowserDataSource.swift in Sources */,
A957C17E2ECFAA1100EA3EE9 /* GifView.swift in Sources */, A957C17E2ECFAA1100EA3EE9 /* GifView.swift in Sources */,
@@ -550,9 +594,12 @@
A9104C7F2EB4022500D160EA /* MSSticker.swift in Sources */, A9104C7F2EB4022500D160EA /* MSSticker.swift in Sources */,
A9B9A8302EB2CD0B004C9245 /* Emoji.swift in Sources */, A9B9A8302EB2CD0B004C9245 /* Emoji.swift in Sources */,
A955B3F12EC22E9700E1732D /* BrowseView.swift in Sources */, A955B3F12EC22E9700E1732D /* BrowseView.swift in Sources */,
A9BE30F72F5B011A00A57668 /* StickerProtocol.swift in Sources */,
A9BE30FC2F5B03F400A57668 /* Sticker.swift in Sources */,
A9B9A82F2EB2CCED004C9245 /* EmojiHoarder.swift in Sources */, A9B9A82F2EB2CCED004C9245 /* EmojiHoarder.swift in Sources */,
A9CD6C3B2EDDE6B500B7F421 /* EmojiPack.swift in Sources */, A9CD6C3B2EDDE6B500B7F421 /* EmojiPack.swift in Sources */,
A921C2E32ED071C900E57B1A /* ListRow.swift in Sources */, A921C2E32ED071C900E57B1A /* ListRow.swift in Sources */,
A9BE30EF2F5B004800A57668 /* GifHoarder.swift in Sources */,
A9EB724A2EB948E000658CEB /* EmojiCollectionView.swift in Sources */, A9EB724A2EB948E000658CEB /* EmojiCollectionView.swift in Sources */,
A9EB724D2EB94A6B00658CEB /* TrieTestingView.swift in Sources */, A9EB724D2EB94A6B00658CEB /* TrieTestingView.swift in Sources */,
A9BBC51A2EB8FA4500FFE82F /* ViewModifiers.swift in Sources */, A9BBC51A2EB8FA4500FFE82F /* ViewModifiers.swift in Sources */,
@@ -567,6 +614,7 @@
A957C1782ECD008E00EA3EE9 /* Bundle.swift in Sources */, A957C1782ECD008E00EA3EE9 /* Bundle.swift in Sources */,
A921C2E02ED067BB00E57B1A /* WelcomeView.swift in Sources */, A921C2E02ED067BB00E57B1A /* WelcomeView.swift in Sources */,
A9B9A82E2EB2CCBE004C9245 /* StickerSlackTests.swift in Sources */, A9B9A82E2EB2CCBE004C9245 /* StickerSlackTests.swift in Sources */,
A9BE30F32F5B004E00A57668 /* Gif.swift in Sources */,
A9B9A8312EB2CD14004C9245 /* FilterCategory.swift in Sources */, A9B9A8312EB2CD14004C9245 /* FilterCategory.swift in Sources */,
A957C1802ECFAA1100EA3EE9 /* GifView.swift in Sources */, A957C1802ECFAA1100EA3EE9 /* GifView.swift in Sources */,
A9EB72502EB94FAD00658CEB /* EmojiPreview.swift in Sources */, A9EB72502EB94FAD00658CEB /* EmojiPreview.swift in Sources */,

View File

@@ -11,7 +11,7 @@ import SwiftUI
import Messages import Messages
import UniformTypeIdentifiers import UniformTypeIdentifiers
struct Emoji: Codable, Identifiable, Hashable { struct Emoji: StickerProtocol {
var id: UUID var id: UUID
var uiID: UUID var uiID: UUID
var name: String var name: String
@@ -21,31 +21,8 @@ struct Emoji: Codable, Identifiable, Hashable {
let fileExtension = ".\(split.last ?? "png")" let fileExtension = ".\(split.last ?? "png")"
return EmojiHoarder.container.absoluteString+id.uuidString+fileExtension return EmojiHoarder.container.absoluteString+id.uuidString+fileExtension
} }
var localImageURL: URL {
return URL(string: localImageURLString)!
}
var remoteImageURL: URL var remoteImageURL: URL
var isLocal: Bool {
return (try? Data(contentsOf: localImageURL)) != nil
}
var sticker: MSSticker? {
guard isLocal else {
return nil
}
return try? MSSticker(contentsOfFileURL: localImageURL, localizedDescription: name)
}
var image: UIImage? {
if let data = try? Data(contentsOf: localImageURL),
let img = UIImage(data: data) {
return img
} else {
return nil
}
}
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case id = "id" case id = "id"
case name = "name" case name = "name"
@@ -90,47 +67,11 @@ struct Emoji: Codable, Identifiable, Hashable {
return return
} }
func deleteImage() {
try? FileManager.default.removeItem(at: localImageURL)
return
}
@MainActor @MainActor
mutating func refresh() { mutating func refresh() {
withAnimation { self.uiID = UUID() } withAnimation { self.uiID = UUID() }
} }
func resize(image: UIImage, to targetSize: CGSize) -> UIImage {
let oldSize = image.size
let ratio: (x: CGFloat, y: CGFloat)
ratio.x = targetSize.width / oldSize.width
ratio.y = targetSize.height / oldSize.height
var newSize: CGSize
if ratio.x > ratio.y {
newSize = CGSize(width: oldSize.width * ratio.y, height: oldSize.height * ratio.y)
} else {
newSize = CGSize(width: oldSize.width * ratio.x, height: oldSize.height * ratio.x)
}
let rect = CGRect(origin: .zero, size: newSize)
if let frames = image.images {
var result: [UIImage] = []
for frame in frames {
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
frame.draw(in: rect)
result.append(UIGraphicsGetImageFromCurrentImageContext() ?? UIImage())
UIGraphicsEndImageContext()
}
return UIImage.animatedImage(with: result, duration: image.duration) ?? UIImage()
}
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}
static var test: Emoji = Emoji( static var test: Emoji = Emoji(
name: "s?", name: "s?",
url: URL(string: "https://neon443.github.io/images/fav.ico")! url: URL(string: "https://neon443.github.io/images/fav.ico")!

View File

@@ -0,0 +1,25 @@
//
// Gif.swift
// StickerSlack
//
// Created by neon443 on 06/03/2026.
//
import Foundation
//struct Gif: StickerProtocol {
// var id: UUID
// var uiID: UUID
// var name: String
// var localImageURLString: String {
//
// }
// var localImageURL: URL {
// return URL(string: localImageURLString)!
// }
// var remoteImageURL: URL
//
// var isLocal: Bool {
//
// }
//}

View File

@@ -0,0 +1,8 @@
//
// GifHoarder.swift
// StickerSlack
//
// Created by neon443 on 06/03/2026.
//
import Foundation

View File

@@ -0,0 +1,24 @@
//
// StickerType.swift
// StickerSlack
//
// Created by neon443 on 06/03/2026.
//
import Foundation
enum StickerType: CustomStringConvertible, CaseIterable, Identifiable {
case slackEmoji
case giphyGif
var id: String { self.description }
var description: String {
switch self {
case .slackEmoji:
return "Slack Emoji"
case .giphyGif:
return "Giphy GIF"
}
}
}

View File

@@ -0,0 +1,71 @@
//
// Sticker.swift
// StickerSlack
//
// Created by neon443 on 06/03/2026.
//
import Foundation
import Messages
extension StickerProtocol {
var localImageURL: URL {
return URL(string: localImageURLString)!
}
var isLocal: Bool {
return (try? Data(contentsOf: localImageURL)) != nil
}
var msSticker: MSSticker? {
guard isLocal else {
return nil
}
return try? MSSticker(contentsOfFileURL: localImageURL, localizedDescription: name)
}
var image: UIImage? {
if let data = try? Data(contentsOf: localImageURL),
let img = UIImage(data: data) {
return img
} else {
return nil
}
}
func deleteImage() {
try? FileManager.default.removeItem(at: localImageURL)
return
}
func resize(image: UIImage, to targetSize: CGSize) -> UIImage {
let oldSize = image.size
let ratio: (x: CGFloat, y: CGFloat)
ratio.x = targetSize.width / oldSize.width
ratio.y = targetSize.height / oldSize.height
var newSize: CGSize
if ratio.x > ratio.y {
newSize = CGSize(width: oldSize.width * ratio.y, height: oldSize.height * ratio.y)
} else {
newSize = CGSize(width: oldSize.width * ratio.x, height: oldSize.height * ratio.x)
}
let rect = CGRect(origin: .zero, size: newSize)
if let frames = image.images {
var result: [UIImage] = []
for frame in frames {
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
frame.draw(in: rect)
result.append(UIGraphicsGetImageFromCurrentImageContext() ?? UIImage())
UIGraphicsEndImageContext()
}
return UIImage.animatedImage(with: result, duration: image.duration) ?? UIImage()
}
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
return UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
}
}

View File

@@ -0,0 +1,30 @@
//
// StickerProtocol.swift
// StickerSlack
//
// Created by neon443 on 06/03/2026.
//
import Foundation
import Messages
protocol StickerProtocol: Codable, Identifiable, Hashable {
var id: UUID { get set }
var uiID: UUID { get set }
var name: String { get set }
var localImageURL: URL { get }
var localImageURLString: String { get }
var remoteImageURL: URL { get set }
var isLocal: Bool { get }
var msSticker: MSSticker? { get }
var image: UIImage? { get }
func downloadImage() async throws
func deleteImage()
mutating func refresh()
func resize(image: UIImage, to targetSize: CGSize) -> UIImage
static var test: Self { get }
}

View File

@@ -12,6 +12,12 @@ struct BrowseView: View {
var body: some View { var body: some View {
List { List {
Picker("", selection: .constant(StickerType.giphyGif)) {
ForEach(StickerType.allCases, id: \.self) { type in
Text(type.description)
}
}
.pickerStyle(.segmented)
ForEach(hoarder.emojis, id: \.self) { emoji in ForEach(hoarder.emojis, id: \.self) { emoji in
EmojiRow(hoarder: hoarder, emoji: emoji) EmojiRow(hoarder: hoarder, emoji: emoji)
} }

View File

@@ -10,6 +10,7 @@ import Haptics
struct ContentView: View { struct ContentView: View {
@ObservedObject var hoarder: EmojiHoarder = EmojiHoarder() @ObservedObject var hoarder: EmojiHoarder = EmojiHoarder()
// @ObservedObject var hoarder: = EmojiHoarder()
var body: some View { var body: some View {
Group { Group {

View File

@@ -16,7 +16,7 @@ class StickerBrowserDataSource: NSObject, MSStickerBrowserViewDataSource {
func numberOfStickers(in stickerBrowserView: MSStickerBrowserView) -> Int { func numberOfStickers(in stickerBrowserView: MSStickerBrowserView) -> Int {
guard emojis.isEmpty else { return emojis.count } guard emojis.isEmpty else { return emojis.count }
for emoji in hoarder.emojis { for emoji in hoarder.emojis {
guard let sticker = emoji.sticker else { continue } guard let sticker = emoji.msSticker else { continue }
emojis.append(sticker) emojis.append(sticker)
} }
return emojis.count return emojis.count