mirror of
https://github.com/neon443/StickerSlack.git
synced 2026-03-11 05:19:13 +00:00
animations in emojirow
animated deleting/downloading emojis stopped it glitching when downloading/deleting an emoji removed refresh() and uiID cos its not necessary sob moved downloadImage() to stickerprotocol extension bundled an image so test emoji loading is faster
This commit is contained in:
BIN
Resources/image.png
Normal file
BIN
Resources/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
@@ -55,6 +55,9 @@
|
|||||||
A986A6CE2EB659E000B6E0FA /* StickerBrowserDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = A986A6CB2EB659E000B6E0FA /* StickerBrowserDataSource.swift */; };
|
A986A6CE2EB659E000B6E0FA /* StickerBrowserDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = A986A6CB2EB659E000B6E0FA /* StickerBrowserDataSource.swift */; };
|
||||||
A986A6CF2EB659E000B6E0FA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A986A6C62EB659E000B6E0FA /* Assets.xcassets */; };
|
A986A6CF2EB659E000B6E0FA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A986A6C62EB659E000B6E0FA /* Assets.xcassets */; };
|
||||||
A986A6D12EB659E000B6E0FA /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A986A6C92EB659E000B6E0FA /* MainInterface.storyboard */; };
|
A986A6D12EB659E000B6E0FA /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A986A6C92EB659E000B6E0FA /* MainInterface.storyboard */; };
|
||||||
|
A99589AF2F5E0D83003A4A8C /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = A99589AE2F5E0D83003A4A8C /* image.png */; };
|
||||||
|
A99589B02F5E0D83003A4A8C /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = A99589AE2F5E0D83003A4A8C /* image.png */; };
|
||||||
|
A99589B12F5E0D83003A4A8C /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = A99589AE2F5E0D83003A4A8C /* image.png */; };
|
||||||
A9B9A82E2EB2CCBE004C9245 /* StickerSlackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B9A82C2EB2CCBE004C9245 /* StickerSlackTests.swift */; };
|
A9B9A82E2EB2CCBE004C9245 /* StickerSlackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B9A82C2EB2CCBE004C9245 /* StickerSlackTests.swift */; };
|
||||||
A9B9A82F2EB2CCED004C9245 /* EmojiHoarder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949B1F72EA04F2300215164 /* EmojiHoarder.swift */; };
|
A9B9A82F2EB2CCED004C9245 /* EmojiHoarder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949B1F72EA04F2300215164 /* EmojiHoarder.swift */; };
|
||||||
A9B9A8302EB2CD0B004C9245 /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = A924C3712EA9127200F20781 /* Emoji.swift */; };
|
A9B9A8302EB2CD0B004C9245 /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = A924C3712EA9127200F20781 /* Emoji.swift */; };
|
||||||
@@ -156,6 +159,7 @@
|
|||||||
A986A6C82EB659E000B6E0FA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
A986A6C82EB659E000B6E0FA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||||
A986A6CA2EB659E000B6E0FA /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
|
A986A6CA2EB659E000B6E0FA /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
|
||||||
A986A6CB2EB659E000B6E0FA /* StickerBrowserDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerBrowserDataSource.swift; sourceTree = "<group>"; };
|
A986A6CB2EB659E000B6E0FA /* StickerBrowserDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerBrowserDataSource.swift; sourceTree = "<group>"; };
|
||||||
|
A99589AE2F5E0D83003A4A8C /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image.png; sourceTree = "<group>"; };
|
||||||
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>"; };
|
||||||
@@ -206,6 +210,7 @@
|
|||||||
A9104C742EB3AE4700D160EA /* Resources */ = {
|
A9104C742EB3AE4700D160EA /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A99589AE2F5E0D83003A4A8C /* image.png */,
|
||||||
A9104C732EB3AE4700D160EA /* StickerSlack.icon */,
|
A9104C732EB3AE4700D160EA /* StickerSlack.icon */,
|
||||||
A949B1EF2EA04E8200215164 /* Assets.xcassets */,
|
A949B1EF2EA04E8200215164 /* Assets.xcassets */,
|
||||||
A9104C722EB3AE4700D160EA /* Icon.pxd */,
|
A9104C722EB3AE4700D160EA /* Icon.pxd */,
|
||||||
@@ -504,6 +509,7 @@
|
|||||||
A9104C762EB3AE4700D160EA /* StickerSlack.icon in Resources */,
|
A9104C762EB3AE4700D160EA /* StickerSlack.icon in Resources */,
|
||||||
A949B1F32EA04E8200215164 /* Assets.xcassets in Resources */,
|
A949B1F32EA04E8200215164 /* Assets.xcassets in Resources */,
|
||||||
A9104C752EB3AE4700D160EA /* Icon.pxd in Resources */,
|
A9104C752EB3AE4700D160EA /* Icon.pxd in Resources */,
|
||||||
|
A99589AF2F5E0D83003A4A8C /* image.png in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -512,6 +518,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A986A6CF2EB659E000B6E0FA /* Assets.xcassets in Resources */,
|
A986A6CF2EB659E000B6E0FA /* Assets.xcassets in Resources */,
|
||||||
|
A99589B12F5E0D83003A4A8C /* image.png in Resources */,
|
||||||
A986A6D12EB659E000B6E0FA /* MainInterface.storyboard in Resources */,
|
A986A6D12EB659E000B6E0FA /* MainInterface.storyboard in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@@ -523,6 +530,7 @@
|
|||||||
A9104C772EB3AE4700D160EA /* Icon.pxd in Resources */,
|
A9104C772EB3AE4700D160EA /* Icon.pxd in Resources */,
|
||||||
A9104C7C2EB3AE6300D160EA /* Assets.xcassets in Resources */,
|
A9104C7C2EB3AE6300D160EA /* Assets.xcassets in Resources */,
|
||||||
A9104C782EB3AE4700D160EA /* StickerSlack.icon in Resources */,
|
A9104C782EB3AE4700D160EA /* StickerSlack.icon in Resources */,
|
||||||
|
A99589B02F5E0D83003A4A8C /* image.png in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import UniformTypeIdentifiers
|
|||||||
|
|
||||||
struct Emoji: StickerProtocol {
|
struct Emoji: StickerProtocol {
|
||||||
var id: UUID
|
var id: UUID
|
||||||
var uiID: UUID
|
|
||||||
var name: String
|
var name: String
|
||||||
var localImageURLString: String {
|
var localImageURLString: String {
|
||||||
let urlString = remoteImageURL.absoluteString
|
let urlString = remoteImageURL.absoluteString
|
||||||
@@ -32,7 +31,6 @@ struct Emoji: StickerProtocol {
|
|||||||
init(from decoder: any Decoder) throws {
|
init(from decoder: any Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
self.id = try container.decode(UUID.self, forKey: .id)
|
self.id = try container.decode(UUID.self, forKey: .id)
|
||||||
self.uiID = id
|
|
||||||
self.name = try container.decode(String.self, forKey: .name)
|
self.name = try container.decode(String.self, forKey: .name)
|
||||||
self.remoteImageURL = try container.decode(URL.self, forKey: .remoteImageURL)
|
self.remoteImageURL = try container.decode(URL.self, forKey: .remoteImageURL)
|
||||||
}
|
}
|
||||||
@@ -43,37 +41,12 @@ struct Emoji: StickerProtocol {
|
|||||||
id: UUID = UUID()
|
id: UUID = UUID()
|
||||||
) {
|
) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.uiID = id
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.remoteImageURL = url
|
self.remoteImageURL = url
|
||||||
}
|
}
|
||||||
|
|
||||||
nonisolated
|
|
||||||
func downloadImage() async throws {
|
|
||||||
if let data = try? await Data(contentsOf: localImageURL),
|
|
||||||
let _ = UIImage(data: data) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var (data, _) = try await URLSession.shared.data(from: remoteImageURL)
|
|
||||||
|
|
||||||
if let uiImage = UIImage(data: data),
|
|
||||||
let cgImage = uiImage.cgImage,
|
|
||||||
await !self.localImageURLString.contains(".gif"),
|
|
||||||
cgImage.width < 300 || cgImage.height < 300 {
|
|
||||||
data = await resize(image: uiImage, to: CGSize(width: 300, height: 300)).pngData()!
|
|
||||||
}
|
|
||||||
try! await data.write(to: localImageURL)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
mutating func refresh() {
|
|
||||||
withAnimation { self.uiID = UUID() }
|
|
||||||
}
|
|
||||||
|
|
||||||
static var test: Emoji = Emoji(
|
static var test: Emoji = Emoji(
|
||||||
name: "s?",
|
name: "a test slack emoji",
|
||||||
url: URL(string: "https://files.catbox.moe/d8go4n.png")!
|
url: Bundle.main.url(forResource: "image", withExtension: "png")!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class EmojiHoarder: ObservableObject {
|
|||||||
self.showWelcome = !UserDefaults.standard.bool(forKey: "showWelcome")
|
self.showWelcome = !UserDefaults.standard.bool(forKey: "showWelcome")
|
||||||
|
|
||||||
let localDB = loadLocalDB()
|
let localDB = loadLocalDB()
|
||||||
withAnimation { self.emojis = localDB }
|
withAnimation(.snappy) { self.emojis = localDB }
|
||||||
loadTrie()
|
loadTrie()
|
||||||
if !skipIndex { buildTrie() }
|
if !skipIndex { buildTrie() }
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ class EmojiHoarder: ObservableObject {
|
|||||||
private func loadRemoteDB() async {
|
private func loadRemoteDB() async {
|
||||||
async let fetched = self.fetchRemoteDB()
|
async let fetched = self.fetchRemoteDB()
|
||||||
if let fetched = await fetched {
|
if let fetched = await fetched {
|
||||||
withAnimation { self.emojis = fetched }
|
withAnimation(.snappy) { self.emojis = fetched }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ class EmojiHoarder: ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
withAnimation { self.emojis = fetched }
|
withAnimation(.snappy) { self.emojis = fetched }
|
||||||
buildTrie()
|
buildTrie()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,11 +241,12 @@ class EmojiHoarder: ObservableObject {
|
|||||||
try? await emoji.downloadImage()
|
try? await emoji.downloadImage()
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
if !skipStoreIndex {
|
if !skipStoreIndex {
|
||||||
|
withAnimation(.snappy) {
|
||||||
self.downloadedEmojis.insert(emoji.name)
|
self.downloadedEmojis.insert(emoji.name)
|
||||||
self.downloadedEmojisArr.append(emoji.name)
|
self.downloadedEmojisArr.append(emoji.name)
|
||||||
|
}
|
||||||
self.storeDownloadedIndexes()
|
self.storeDownloadedIndexes()
|
||||||
}
|
}
|
||||||
self.trie.dict[emoji.name]?.refresh()
|
|
||||||
if !skipStoreIndex { Haptic.success.trigger() }
|
if !skipStoreIndex { Haptic.success.trigger() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,11 +255,12 @@ class EmojiHoarder: ObservableObject {
|
|||||||
func delete(emoji: Emoji, skipStoreIndex: Bool = false) {
|
func delete(emoji: Emoji, skipStoreIndex: Bool = false) {
|
||||||
emoji.deleteImage()
|
emoji.deleteImage()
|
||||||
if !skipStoreIndex {
|
if !skipStoreIndex {
|
||||||
|
withAnimation(.snappy) {
|
||||||
downloadedEmojis.remove(emoji.name)
|
downloadedEmojis.remove(emoji.name)
|
||||||
downloadedEmojisArr.removeAll(where: { $0 == emoji.name })
|
downloadedEmojisArr.removeAll(where: { $0 == emoji.name })
|
||||||
|
}
|
||||||
storeDownloadedIndexes()
|
storeDownloadedIndexes()
|
||||||
}
|
}
|
||||||
self.trie.dict[emoji.name]?.refresh()
|
|
||||||
if !skipStoreIndex { Haptic.heavy.trigger() }
|
if !skipStoreIndex { Haptic.heavy.trigger() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import UniformTypeIdentifiers
|
|||||||
|
|
||||||
struct Gif: StickerProtocol {
|
struct Gif: StickerProtocol {
|
||||||
var id: UUID
|
var id: UUID
|
||||||
var uiID: UUID
|
|
||||||
var name: String
|
var name: String
|
||||||
var localImageURLString: String {
|
var localImageURLString: String {
|
||||||
let urlString = remoteImageURL.absoluteString
|
let urlString = remoteImageURL.absoluteString
|
||||||
@@ -32,7 +31,6 @@ struct Gif: StickerProtocol {
|
|||||||
id: UUID = UUID()
|
id: UUID = UUID()
|
||||||
) {
|
) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.uiID = id
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.remoteImageURL = url
|
self.remoteImageURL = url
|
||||||
}
|
}
|
||||||
@@ -56,11 +54,6 @@ struct Gif: StickerProtocol {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
|
||||||
mutating func refresh() {
|
|
||||||
withAnimation { self.uiID = UUID() }
|
|
||||||
}
|
|
||||||
|
|
||||||
static var test: Gif = Gif(
|
static var test: Gif = Gif(
|
||||||
name: "doesheknow",
|
name: "doesheknow",
|
||||||
url: URL(string: "https://media1.tenor.com/m/FN9udnZmQU8AAAAd/does-he-know-batman.gif")!
|
url: URL(string: "https://media1.tenor.com/m/FN9udnZmQU8AAAAd/does-he-know-batman.gif")!
|
||||||
|
|||||||
@@ -33,6 +33,25 @@ extension StickerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nonisolated
|
||||||
|
func downloadImage() async throws {
|
||||||
|
if let data = try? await Data(contentsOf: localImageURL),
|
||||||
|
let _ = UIImage(data: data) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var (data, _) = try await URLSession.shared.data(from: remoteImageURL)
|
||||||
|
|
||||||
|
if let uiImage = UIImage(data: data),
|
||||||
|
let cgImage = uiImage.cgImage,
|
||||||
|
await !self.localImageURLString.contains(".gif"),
|
||||||
|
cgImage.width < 300 || cgImage.height < 300 {
|
||||||
|
data = await resize(image: uiImage, to: CGSize(width: 300, height: 300)).pngData()!
|
||||||
|
}
|
||||||
|
try! await data.write(to: localImageURL)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func deleteImage() {
|
func deleteImage() {
|
||||||
try? FileManager.default.removeItem(at: localImageURL)
|
try? FileManager.default.removeItem(at: localImageURL)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import Messages
|
|||||||
|
|
||||||
protocol StickerProtocol: Codable, Identifiable, Hashable {
|
protocol StickerProtocol: Codable, Identifiable, Hashable {
|
||||||
var id: UUID { get set }
|
var id: UUID { get set }
|
||||||
var uiID: UUID { get set }
|
|
||||||
var name: String { get set }
|
var name: String { get set }
|
||||||
|
|
||||||
var localImageURL: URL { get }
|
var localImageURL: URL { get }
|
||||||
@@ -24,7 +23,6 @@ protocol StickerProtocol: Codable, Identifiable, Hashable {
|
|||||||
|
|
||||||
func downloadImage() async throws
|
func downloadImage() async throws
|
||||||
func deleteImage()
|
func deleteImage()
|
||||||
mutating func refresh()
|
|
||||||
func resize(image: UIImage, to targetSize: CGSize) -> UIImage
|
func resize(image: UIImage, to targetSize: CGSize) -> UIImage
|
||||||
static var test: Self { get }
|
static var test: Self { get }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,26 +15,38 @@ struct EmojiRow: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
EmojiPreview(hoarder: hoarder, emoji: emoji)
|
EmojiPreview(hoarder: hoarder, emoji: emoji)
|
||||||
.frame(maxWidth: 100, maxHeight: 100)
|
.frame(width: 100, height: 100)
|
||||||
.padding(.trailing, 20)
|
.padding(.trailing, 10)
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: 5) {
|
||||||
|
ZStack {
|
||||||
|
RoundedRectangle(cornerRadius: 5)
|
||||||
|
.foregroundStyle(.gray.opacity(0.1))
|
||||||
Text(emoji.name)
|
Text(emoji.name)
|
||||||
|
.font(.caption)
|
||||||
Spacer()
|
.bold(hoarder.downloadedEmojis.contains(emoji.name))
|
||||||
|
.foregroundColor(hoarder.downloadedEmojis.contains(emoji.name) ? .green : .primary)
|
||||||
|
.padding(3)
|
||||||
|
}
|
||||||
|
.fixedSize()
|
||||||
|
if hoarder.downloadedEmojis.contains(emoji.name) {
|
||||||
Image(systemName: "arrow.down.circle.fill")
|
Image(systemName: "arrow.down.circle.fill")
|
||||||
.resizable().scaledToFit()
|
.resizable().scaledToFit()
|
||||||
.frame(width: 20, height: 20)
|
.frame(width: 20, height: 20)
|
||||||
.symbolRenderingMode(.hierarchical)
|
.symbolRenderingMode(.hierarchical)
|
||||||
.foregroundStyle(.gray)
|
.foregroundStyle(.gray)
|
||||||
.padding(.trailing, 20)
|
.transition(.scale)
|
||||||
.opacity(hoarder.downloadedEmojis.contains(emoji.name) ? 1 : 0)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
if hoarder.downloadedEmojis.contains(emoji.name) {
|
if hoarder.downloadedEmojis.contains(emoji.name) {
|
||||||
Button("", systemImage: "trash") {
|
Button("", systemImage: "trash") {
|
||||||
hoarder.delete(emoji: emoji)
|
hoarder.delete(emoji: emoji)
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
|
.transition(.scale)
|
||||||
} else {
|
} else {
|
||||||
Button("", systemImage: "arrow.down.circle") {
|
Button("", systemImage: "arrow.down.circle") {
|
||||||
Task {
|
Task {
|
||||||
@@ -42,14 +54,21 @@ struct EmojiRow: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
|
.transition(.scale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
|
List {
|
||||||
|
EmojiRow(
|
||||||
|
hoarder: EmojiHoarder(localOnly: true),
|
||||||
|
emoji: Emoji.test
|
||||||
|
)
|
||||||
EmojiRow(
|
EmojiRow(
|
||||||
hoarder: EmojiHoarder(localOnly: true),
|
hoarder: EmojiHoarder(localOnly: true),
|
||||||
emoji: Emoji.test
|
emoji: Emoji.test
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ struct SearchView: View {
|
|||||||
EmojiRow(hoarder: hoarder, emoji: hoarder.trie.dict[name]!)
|
EmojiRow(hoarder: hoarder, emoji: hoarder.trie.dict[name]!)
|
||||||
}
|
}
|
||||||
.onChange(of: hoarder.searchTerm) { _ in
|
.onChange(of: hoarder.searchTerm) { _ in
|
||||||
withAnimation { filterResult = hoarder.trie.search(prefix: hoarder.searchTerm) }
|
withAnimation(.snappy) { filterResult = hoarder.trie.search(prefix: hoarder.searchTerm) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.searchable(text: $hoarder.searchTerm)
|
.searchable(text: $hoarder.searchTerm)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ struct TrieTestingView: View {
|
|||||||
.textFieldStyle(.roundedBorder)
|
.textFieldStyle(.roundedBorder)
|
||||||
.border(.orange)
|
.border(.orange)
|
||||||
.onChange(of: filterTerm) { _ in
|
.onChange(of: filterTerm) { _ in
|
||||||
withAnimation { filterResult = hoarder.trie.search(prefix: filterTerm) }
|
withAnimation(.snappy) { filterResult = hoarder.trie.search(prefix: filterTerm) }
|
||||||
}
|
}
|
||||||
Text("\(filterResult.count)")
|
Text("\(filterResult.count)")
|
||||||
.modifier(numericTextCompat())
|
.modifier(numericTextCompat())
|
||||||
@@ -65,7 +65,7 @@ struct TrieTestingView: View {
|
|||||||
.textFieldStyle(.roundedBorder)
|
.textFieldStyle(.roundedBorder)
|
||||||
.border(.orange)
|
.border(.orange)
|
||||||
.onChange(of: filterTerm2) { _ in
|
.onChange(of: filterTerm2) { _ in
|
||||||
withAnimation { filterResult = hoarder.emojis.filter({ $0.name.localizedCaseInsensitiveContains(filterTerm2) }).map({ $0.name }) }
|
withAnimation(.snappy) { filterResult = hoarder.emojis.filter({ $0.name.localizedCaseInsensitiveContains(filterTerm2) }).map({ $0.name }) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if uikit {
|
if uikit {
|
||||||
|
|||||||
Reference in New Issue
Block a user