mirror of
https://github.com/neon443/StickerSlack.git
synced 2026-03-11 13:26:17 +00:00
async let to parallelise stuff
fix crash when the fetched db doesnt exist added loadremoteDB to asyncly fetch remotedb fixed Tasks not running on background threads remove expiration from slackresponse emoji.uiid starts out as emoji.id added filtering emojis test hopefully optimised the display of images checking if its local imessage extension ios 15+ remove the "hii!!" and "hello world" from the emojji picker
This commit is contained in:
@@ -663,7 +663,7 @@
|
|||||||
INFOPLIST_FILE = StickerSlackiMessageExtension/Info.plist;
|
INFOPLIST_FILE = StickerSlackiMessageExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = StickerSlackiMessageExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = StickerSlackiMessageExtension;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@@ -695,7 +695,7 @@
|
|||||||
INFOPLIST_FILE = StickerSlackiMessageExtension/Info.plist;
|
INFOPLIST_FILE = StickerSlackiMessageExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = StickerSlackiMessageExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = StickerSlackiMessageExtension;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|||||||
@@ -13,13 +13,12 @@ import UniformTypeIdentifiers
|
|||||||
|
|
||||||
struct Emoji: Codable, Identifiable, Hashable {
|
struct Emoji: Codable, Identifiable, Hashable {
|
||||||
var id: UUID
|
var id: UUID
|
||||||
var uiID: UUID = UUID()
|
var uiID: UUID
|
||||||
var name: String
|
var name: String
|
||||||
var localImageURL: URL {
|
var localImageURL: URL {
|
||||||
let urlString = remoteImageURL.absoluteString
|
let urlString = remoteImageURL.absoluteString
|
||||||
let split = urlString.split(separator: ".")
|
let split = urlString.split(separator: ".")
|
||||||
let fileExtension = ".\(split.last ?? "png")"
|
let fileExtension = ".\(split.last ?? "png")"
|
||||||
// return EmojiHoarder.container.appendingPathComponent(id.uuidString+fileExtension, conformingTo: .image)
|
|
||||||
return URL(string: EmojiHoarder.container.absoluteString+id.uuidString+fileExtension)!
|
return URL(string: EmojiHoarder.container.absoluteString+id.uuidString+fileExtension)!
|
||||||
}
|
}
|
||||||
var remoteImageURL: URL
|
var remoteImageURL: URL
|
||||||
@@ -53,6 +52,7 @@ struct Emoji: Codable, Identifiable, Hashable {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
@@ -62,6 +62,7 @@ struct Emoji: Codable, Identifiable, Hashable {
|
|||||||
id: UUID = UUID()
|
id: UUID = UUID()
|
||||||
) {
|
) {
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.uiID = id
|
||||||
self.name = apiEmoji.name
|
self.name = apiEmoji.name
|
||||||
self.remoteImageURL = apiEmoji.url
|
self.remoteImageURL = apiEmoji.url
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ struct SlackResponse: Identifiable, Codable {
|
|||||||
var name: String
|
var name: String
|
||||||
var imageUrl: String
|
var imageUrl: String
|
||||||
var alias: String?
|
var alias: String?
|
||||||
var expiration: Date
|
|
||||||
|
|
||||||
static func toEmojis(from response: [SlackResponse]?) -> [Emoji]? {
|
static func toEmojis(from response: [SlackResponse]?) -> [Emoji]? {
|
||||||
guard let response else { return nil }
|
guard let response else { return nil }
|
||||||
|
|||||||
@@ -25,11 +25,9 @@ class EmojiHoarder: ObservableObject {
|
|||||||
withAnimation { self.emojis = loadLocalDB() }
|
withAnimation { self.emojis = loadLocalDB() }
|
||||||
withAnimation { self.filteredEmojis = self.emojis }
|
withAnimation { self.filteredEmojis = self.emojis }
|
||||||
|
|
||||||
Task(priority: .high) {
|
Task.detached {
|
||||||
if let fetched = await self.fetchRemoteDB() {
|
print(Thread.current)
|
||||||
withAnimation { self.emojis = fetched }
|
await self.loadRemoteDB()
|
||||||
withAnimation { self.filteredEmojis = fetched }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,12 +53,20 @@ class EmojiHoarder: ObservableObject {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadRemoteDB() async {
|
||||||
|
async let fetched = self.fetchRemoteDB()
|
||||||
|
if let fetched = await fetched {
|
||||||
|
withAnimation { self.emojis = fetched }
|
||||||
|
withAnimation { self.filteredEmojis = fetched }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func fetchRemoteDB() async -> [Emoji]? {
|
func fetchRemoteDB() async -> [Emoji]? {
|
||||||
do {
|
do {
|
||||||
let (data, _) = try await URLSession.shared.data(from: endpoint)
|
async let (data, _) = try URLSession.shared.data(from: endpoint)
|
||||||
decoder.dateDecodingStrategy = .iso8601
|
decoder.dateDecodingStrategy = .iso8601
|
||||||
let decoded: [SlackResponse] = try! decoder.decode([SlackResponse].self, from: data)
|
let decoded: [SlackResponse] = try decoder.decode([SlackResponse].self, from: await data)
|
||||||
storeDB(data: data)
|
try storeDB(data: await data)
|
||||||
return SlackResponse.toEmojis(from: decoded)
|
return SlackResponse.toEmojis(from: decoded)
|
||||||
} catch {
|
} catch {
|
||||||
print(error.localizedDescription)
|
print(error.localizedDescription)
|
||||||
@@ -69,12 +75,14 @@ class EmojiHoarder: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func refreshDB(withCallback callback: (() -> Void)? = nil) {
|
func refreshDB(withCallback callback: (() -> Void)? = nil) {
|
||||||
Task {
|
Task.detached {
|
||||||
guard let fetched = try? await fetchRemoteDB() else { return }
|
guard let fetched = await self.fetchRemoteDB() else { return }
|
||||||
withAnimation { self.emojis = fetched }
|
DispatchQueue.main.async {
|
||||||
withAnimation { self.filteredEmojis = fetched }
|
withAnimation { self.emojis = fetched }
|
||||||
if let callback {
|
withAnimation { self.filteredEmojis = fetched }
|
||||||
callback()
|
if let callback {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,8 +92,8 @@ class EmojiHoarder: ObservableObject {
|
|||||||
withAnimation(.interactiveSpring) { self.filteredEmojis = emojis }
|
withAnimation(.interactiveSpring) { self.filteredEmojis = emojis }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Task {
|
Task.detached {
|
||||||
let filtered = emojis.filter { $0.name.localizedCaseInsensitiveContains(searchTerm) }
|
let filtered = await self.emojis.filter { $0.name.localizedCaseInsensitiveContains(searchTerm) }
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
withAnimation(.interactiveSpring) { self.filteredEmojis = filtered }
|
withAnimation(.interactiveSpring) { self.filteredEmojis = filtered }
|
||||||
}
|
}
|
||||||
@@ -97,15 +105,15 @@ class EmojiHoarder: ObservableObject {
|
|||||||
filterEmojis(by: searchTerm)
|
filterEmojis(by: searchTerm)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Task {
|
self.filterEmojis(by: searchTerm)
|
||||||
filterEmojis(by: searchTerm)
|
DispatchQueue.main.async {
|
||||||
switch category {
|
switch category {
|
||||||
case .none:
|
case .none:
|
||||||
fallthrough
|
fallthrough
|
||||||
case .downloaded:
|
case .downloaded:
|
||||||
withAnimation(.interactiveSpring) { filteredEmojis = filteredEmojis.filter { $0.isLocal } }
|
withAnimation(.interactiveSpring) { self.filteredEmojis = self.filteredEmojis.filter { $0.isLocal } }
|
||||||
case .notDownloaded:
|
case .notDownloaded:
|
||||||
withAnimation(.interactiveSpring) { filteredEmojis = filteredEmojis.filter { !$0.isLocal } }
|
withAnimation(.interactiveSpring) { self.filteredEmojis = self.filteredEmojis.filter { !$0.isLocal } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ struct EmojiPreview: View {
|
|||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text(emoji.name)
|
Text(emoji.name)
|
||||||
Group {
|
Group {
|
||||||
if let localImage = try? Data(contentsOf: emoji.localImageURL),
|
if emoji.isLocal {
|
||||||
let image = UIImage(data: localImage) {
|
Image(uiImage: emoji.image!)
|
||||||
Image(uiImage: image)
|
|
||||||
.resizable().scaledToFit()
|
.resizable().scaledToFit()
|
||||||
.border(.orange)
|
.border(.orange)
|
||||||
.overlay(alignment: .bottomLeading) {
|
.overlay(alignment: .bottomLeading) {
|
||||||
|
|||||||
@@ -23,4 +23,13 @@ struct StickerSlackTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test func filteringEmojis() async throws {
|
||||||
|
let searchQueries = ["heavysob", "yay", "afsdjk", "afhjskf", "g4", "aqua-osx", "neotunes", "", "", ""]
|
||||||
|
for query in searchQueries {
|
||||||
|
print(query)
|
||||||
|
hoarder.filteredEmojis = []
|
||||||
|
hoarder.filterEmojis(by: query)
|
||||||
|
print(hoarder.filteredEmojis.count)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,19 +15,8 @@
|
|||||||
<view key="view" contentMode="scaleToFill" id="zMn-AG-sqS">
|
<view key="view" contentMode="scaleToFill" id="zMn-AG-sqS">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="528"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="528"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hello World" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d1e-fi-ked">
|
|
||||||
<rect key="frame" x="116" y="254.00000000000003" width="88" height="20.333333333333343"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<viewLayoutGuide key="safeArea" id="LDy-ih-0nr"/>
|
<viewLayoutGuide key="safeArea" id="LDy-ih-0nr"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="centerY" secondItem="d1e-fi-ked" secondAttribute="centerY" id="H0s-hz-dDP"/>
|
|
||||||
<constraint firstAttribute="centerX" secondItem="d1e-fi-ked" secondAttribute="centerX" id="wFy-hW-Bib"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||||
<size key="freeformSize" width="320" height="528"/>
|
<size key="freeformSize" width="320" height="528"/>
|
||||||
|
|||||||
@@ -20,13 +20,6 @@ class MessagesViewController: MSMessagesAppViewController {
|
|||||||
// MARK: - Conversation Handling
|
// MARK: - Conversation Handling
|
||||||
|
|
||||||
override func willBecomeActive(with conversation: MSConversation) {
|
override func willBecomeActive(with conversation: MSConversation) {
|
||||||
let l = UILabel()
|
|
||||||
l.frame = CGRect(x: 20, y: 20, width: 200, height: 40)
|
|
||||||
l.textColor = .systemOrange
|
|
||||||
l.text = "hii!"
|
|
||||||
view.addSubview(l)
|
|
||||||
view.bringSubviewToFront(l)
|
|
||||||
|
|
||||||
let stickerBrowser = MSStickerBrowserView(frame: .zero, stickerSize: .regular)
|
let stickerBrowser = MSStickerBrowserView(frame: .zero, stickerSize: .regular)
|
||||||
stickerBrowser.frame = CGRect(x: 60, y: 20, width: 200, height: 600)
|
stickerBrowser.frame = CGRect(x: 60, y: 20, width: 200, height: 600)
|
||||||
stickerBrowser.dataSource = dataSource
|
stickerBrowser.dataSource = dataSource
|
||||||
|
|||||||
Reference in New Issue
Block a user