mirror of
https://github.com/neon443/StickerSlack.git
synced 2026-03-11 05:19:13 +00:00
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:
@@ -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 */,
|
||||||
|
|||||||
@@ -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")!
|
||||||
|
|||||||
25
StickerSlack/Gifs/Gif.swift
Normal file
25
StickerSlack/Gifs/Gif.swift
Normal 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 {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//}
|
||||||
8
StickerSlack/Gifs/GifHoarder.swift
Normal file
8
StickerSlack/Gifs/GifHoarder.swift
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//
|
||||||
|
// GifHoarder.swift
|
||||||
|
// StickerSlack
|
||||||
|
//
|
||||||
|
// Created by neon443 on 06/03/2026.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
24
StickerSlack/StickerType.swift
Normal file
24
StickerSlack/StickerType.swift
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
71
StickerSlack/Stickers/Sticker.swift
Normal file
71
StickerSlack/Stickers/Sticker.swift
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
30
StickerSlack/Stickers/StickerProtocol.swift
Normal file
30
StickerSlack/Stickers/StickerProtocol.swift
Normal 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 }
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user