Quality of life enhancements

This commit is contained in:
Stephen 2025-05-30 02:39:47 -04:00
parent 3aa9b4603e
commit 47dfbbed6c
11 changed files with 443 additions and 91 deletions

View file

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,35 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,95 @@
//
// DebugWidget.swift
// DebugWidget
//
// Created by Stephen on 5/30/25.
//
import WidgetKit
import SwiftUI
import UIKit
// MARK: - Timeline Entry
struct AppsEntry: TimelineEntry {
let date: Date
let bundleIDs: [String]
}
// MARK: - Provider
struct AppsProvider: TimelineProvider {
private let sharedDefaults = UserDefaults(suiteName: "group.com.stik.sj")
func placeholder(in context: Context) -> AppsEntry {
AppsEntry(date: .now, bundleIDs: [])
}
func getSnapshot(in context: Context, completion: @escaping (AppsEntry) -> Void) {
completion(makeEntry())
}
func getTimeline(in context: Context, completion: @escaping (Timeline<AppsEntry>) -> Void) {
let entry = makeEntry()
completion(Timeline(entries: [entry], policy: .never))
}
private func makeEntry() -> AppsEntry {
let favs = sharedDefaults?.stringArray(forKey: "favoriteApps") ?? []
let bundleIDs = Array(favs.prefix(4))
return AppsEntry(date: .now, bundleIDs: bundleIDs)
}
}
// MARK: - Widget View
struct AppsWidgetEntryView: View {
let entry: AppsEntry
var body: some View {
HStack(spacing: 8) {
ForEach(0..<4, id: \.self) { idx in
if idx < entry.bundleIDs.count {
IconCell(bundleID: entry.bundleIDs[idx])
} else {
PlaceholderCell()
}
}
}
.padding(8)
.containerBackground(Color(UIColor.systemBackground), for: .widget)
}
@ViewBuilder
private func IconCell(bundleID: String) -> some View {
if let img = loadIcon(for: bundleID) {
Link(destination: URL(string: "stikjit://enable-jit?bundle-id=\(bundleID)")!) {
Image(uiImage: img)
.resizable()
.aspectRatio(1, contentMode: .fit)
.cornerRadius(12)
}
} else {
PlaceholderCell()
}
}
@ViewBuilder
private func PlaceholderCell() -> some View {
ZStack {
RoundedRectangle(cornerRadius: 12)
.fill(Color(UIColor.systemGray5))
Image(systemName: "plus")
.font(.system(size: 24, weight: .medium))
.foregroundColor(.gray)
}
.aspectRatio(1, contentMode: .fit)
}
private func loadIcon(for bundleID: String) -> UIImage? {
guard let container = FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: "group.com.stik.sj")
else { return nil }
let url = container
.appendingPathComponent("icons", isDirectory: true)
.appendingPathComponent("\(bundleID).png")
return UIImage(contentsOfFile: url.path)
}
}

View file

@ -0,0 +1,23 @@
//
// DebugWidgetBundle.swift
// DebugWidget
//
// Created by Stephen on 5/30/25.
//
import WidgetKit
import SwiftUI
@main
struct AppsWidget: Widget {
let kind: String = "AppsWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: AppsProvider()) { entry in
AppsWidgetEntryView(entry: entry)
}
.configurationDisplayName("StikDebug Favorites")
.description("Quick-launch your top 4 favorite debug targets.")
.supportedFamilies([.systemMedium])
}
}

11
DebugWidget/Info.plist Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>