add app icon, rename to Sticker Cloner, pack thumbnails, sort list, smaller stickers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-03 17:28:53 +01:00
parent 8d120f4d56
commit fae1159536
19 changed files with 50 additions and 4 deletions

View File

@@ -89,6 +89,15 @@ final class StickerStore {
return urls
}
func firstStickerURL(forPack name: String) -> URL? {
let packDir = packDirectory(name: name)
guard let files = try? fileManager.contentsOfDirectory(at: packDir, includingPropertiesForKeys: nil) else { return nil }
return files
.filter { $0.pathExtension == "png" }
.sorted { $0.lastPathComponent < $1.lastPathComponent }
.first
}
// MARK: - Migration from old sandbox
private func migrateIfNeeded() {

View File

@@ -1,70 +1,83 @@
{
"images" : [
{
"filename" : "icon_58x58.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "icon_87x87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "icon_120x90.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x45"
},
{
"filename" : "icon_180x135.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x45"
},
{
"filename" : "icon_58x58.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "icon_134x100.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "67x50"
},
{
"filename" : "icon_148x110.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "74x55"
},
{
"filename" : "icon_1024x1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
},
{
"filename" : "icon_54x40.png",
"idiom" : "universal",
"platform" : "ios",
"scale" : "2x",
"size" : "27x20"
},
{
"filename" : "icon_81x60.png",
"idiom" : "universal",
"platform" : "ios",
"scale" : "3x",
"size" : "27x20"
},
{
"filename" : "icon_64x48.png",
"idiom" : "universal",
"platform" : "ios",
"scale" : "2x",
"size" : "32x24"
},
{
"filename" : "icon_96x72.png",
"idiom" : "universal",
"platform" : "ios",
"scale" : "3x",
"size" : "32x24"
},
{
"filename" : "icon_1024x768.png",
"idiom" : "ios-marketing",
"platform" : "ios",
"scale" : "1x",

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -4,6 +4,15 @@ import UIKit
final class StickerBrowserViewController: MSStickerBrowserViewController {
private var stickers: [MSSticker] = []
init() {
super.init(stickerSize: .small)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) is not supported")
}
func reloadStickers() {
let urls = StickerStore.shared.stickerFileURLs()
stickers = urls.compactMap { url in

View File

@@ -261,7 +261,7 @@
DEVELOPMENT_TEAM = NG5W75WE8U;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "StickerCloner MessagesExtension/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = StickerCloner;
INFOPLIST_KEY_CFBundleDisplayName = "Sticker Cloner";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -291,7 +291,7 @@
DEVELOPMENT_TEAM = NG5W75WE8U;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "StickerCloner MessagesExtension/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = StickerCloner;
INFOPLIST_KEY_CFBundleDisplayName = "Sticker Cloner";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -441,6 +441,7 @@
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = NG5W75WE8U;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "Sticker Cloner";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
@@ -466,6 +467,7 @@
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = NG5W75WE8U;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "Sticker Cloner";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";

View File

@@ -1,10 +1,12 @@
import SwiftUI
import UIKit
struct AddPackView: View {
@State private var urlText = ""
@State private var isLoading = false
@State private var errorMessage: String?
@State private var packs: [SavedPack] = StickerStore.shared.savedPacks
.sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == .orderedAscending }
var body: some View {
NavigationStack {
@@ -42,7 +44,15 @@ struct AddPackView: View {
if !packs.isEmpty {
Section("Saved Packs") {
ForEach(packs, id: \.name) { pack in
HStack {
HStack(spacing: 12) {
if let url = StickerStore.shared.firstStickerURL(forPack: pack.name),
let data = try? Data(contentsOf: url),
let uiImage = UIImage(data: data) {
Image(uiImage: uiImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 44, height: 44)
}
VStack(alignment: .leading) {
Text(pack.title)
Text("\(pack.stickerCount) stickers")
@@ -56,7 +66,7 @@ struct AddPackView: View {
}
}
}
.navigationTitle("Sticker Packs")
.navigationTitle("Sticker Cloner")
.navigationBarTitleDisplayMode(.inline)
}
}
@@ -78,6 +88,7 @@ struct AddPackView: View {
let response = try await StickerClonerAPI.fetchStickerSet(name: name)
try await StickerStore.shared.addPack(response: response)
packs = StickerStore.shared.savedPacks
.sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == .orderedAscending }
urlText = ""
} catch {
errorMessage = error.localizedDescription
@@ -91,6 +102,7 @@ struct AddPackView: View {
StickerStore.shared.removePack(name: packs[index].name)
}
packs = StickerStore.shared.savedPacks
.sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == .orderedAscending }
}
private func extractPackName(from input: String) -> String {

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -1,6 +1,7 @@
{
"images" : [
{
"filename" : "AppIcon.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"