Better UI

This commit is contained in:
Stephen 2025-03-27 14:15:56 -04:00
parent ff92a9dbea
commit 3cb5fbad77
7 changed files with 234 additions and 67 deletions

View file

@ -0,0 +1,44 @@
//
// Color.swift
// StikJIT
//
// Created by Stephen on 3/27/25.
//
import SwiftUI
extension Color {
func toHex() -> String? {
let components = UIColor(self).cgColor.components
let r = Float(components?[0] ?? 0)
let g = Float(components?[1] ?? 0)
let b = Float(components?[2] ?? 0)
let hex = String(format: "%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255))
return "#" + hex
}
init?(hex: String) {
let r, g, b: CGFloat
let start = hex.index(hex.startIndex, offsetBy: 1)
let hexColor = String(hex[start...])
if hexColor.count == 6, let hexNumber = Int(hexColor, radix: 16) {
r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
b = CGFloat(hexNumber & 0x0000ff) / 255
self.init(red: r, green: g, blue: b)
return
}
return nil
}
}
extension Color {
static let primaryBackground = Color.black
static let cardBackground = Color.white.opacity(0.2)
static let cardBackground2 = Color.blue.opacity(0.8)
static let primaryText = Color.white
static let secondaryText = Color.white.opacity(0.7)
}

View file

@ -0,0 +1,14 @@
//
// Font.swift
// StikJIT
//
// Created by Stephen on 3/27/25.
//
import SwiftUI
extension Font {
static let titleFont = Font.system(size: 24, weight: .bold)
static let bodyFont = Font.system(size: 18, weight: .regular)
static let captionFont = Font.system(size: 14, weight: .medium)
}

View file

@ -12,7 +12,7 @@ import em_proxy
struct HeartbeatApp: App {
var body: some Scene {
WindowGroup {
HomeView()
MainTabView()
.onAppear {
startProxy()
startHeartbeatInBackground()

View file

@ -1,32 +0,0 @@
//
// DebugView.swift
// StikJIT
//
// Created by Stephen on 3/27/25.
//
import SwiftUI
struct DebugView: View {
var body: some View {
VStack {
Spacer()
Text("Welcome to StikJIT")
.font(.largeTitle)
.bold()
.padding()
Text("Use the Debug tab to monitor the logs.")
.font(.body)
.foregroundColor(.secondary)
.padding()
Spacer()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(.systemBackground))
}
}
#Preview {
DebugView()
}

View file

@ -8,63 +8,44 @@
import SwiftUI
struct HomeView: View {
@AppStorage("username") private var username = "User"
@AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = Color.primaryBackground.toHex() ?? "#000000"
@State private var selectedBackgroundColor: Color = Color(hex: UserDefaults.standard.string(forKey: "customBackgroundColor") ?? "#000000") ?? Color.primaryBackground
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@AppStorage("bundleID") private var bundleID: String = ""
@State private var isProcessing = false
@State private var isShowingInstalledApps = false
var body: some View {
ZStack {
Color(.systemGroupedBackground)
.edgesIgnoringSafeArea(.all)
selectedBackgroundColor .edgesIgnoringSafeArea(.all)
VStack(spacing: 25) {
Spacer()
VStack(spacing: 5) {
Text("StikJIT")
Text("Welcome to StikJIT \(username)!")
.font(.system(.largeTitle, design: .rounded))
.fontWeight(.bold)
Text("Enter the app's Bundle ID and enable JIT.")
Text("Click enable jit to get started")
.font(.system(.subheadline, design: .rounded))
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
.padding(.top, 40)
RoundedTextField(placeholder: "Enter Bundle ID", text: $bundleID)
.padding(.horizontal, 20)
Button(action: {
HapticFeedbackHelper.trigger()
startJITInBackground(with: bundleID)
}) {
Label(isProcessing ? "Enabling..." : "Enable JIT",
systemImage: isProcessing ? "hourglass" : "bolt.fill")
.font(.system(.title3, design: .rounded))
.fontWeight(.semibold)
.frame(maxWidth: .infinity)
.padding()
.background(isProcessing ? Color.gray.opacity(0.6) : Color.blue)
.foregroundColor(.white)
.cornerRadius(16)
.shadow(color: .blue.opacity(0.3), radius: 8, x: 0, y: 4)
.animation(.easeInOut(duration: 0.2), value: isProcessing)
}
.disabled(isProcessing)
.padding(.horizontal, 20)
Button(action: {
isShowingInstalledApps = true
}) {
Label("View Installed Apps", systemImage: "list.bullet")
Label("Enable JIT", systemImage: "list.bullet")
.font(.system(.title3, design: .rounded))
.fontWeight(.semibold)
.frame(maxWidth: .infinity)
.padding()
.background(Color.green)
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(16)
.shadow(color: Color.green.opacity(0.3), radius: 8, x: 0, y: 4)
.shadow(color: Color.blue.opacity(0.3), radius: 8, x: 0, y: 4)
}
.padding(.horizontal, 20)
@ -72,6 +53,9 @@ struct HomeView: View {
}
.padding()
}
.onReceive(timer) { _ in
refreshBackground()
}
.sheet(isPresented: $isShowingInstalledApps) {
InstalledAppsListView { selectedBundle in
bundleID = selectedBundle
@ -82,6 +66,10 @@ struct HomeView: View {
}
}
private func refreshBackground() {
selectedBackgroundColor = Color(hex: customBackgroundColorHex) ?? Color.primaryBackground
}
private func startJITInBackground(with bundleID: String) {
isProcessing = true
DispatchQueue.global(qos: .background).async {
@ -130,6 +118,10 @@ class InstalledAppsViewModel: ObservableObject {
}
struct InstalledAppsListView: View {
@AppStorage("username") private var username = "User"
@AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = Color.primaryBackground.toHex() ?? "#000000"
@State private var selectedBackgroundColor: Color = Color(hex: UserDefaults.standard.string(forKey: "customBackgroundColor") ?? "#000000") ?? Color.primaryBackground
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@StateObject var viewModel = InstalledAppsViewModel()
@Environment(\.dismiss) var dismiss
@State private var searchText: String = ""
@ -147,8 +139,7 @@ struct InstalledAppsListView: View {
var body: some View {
NavigationView {
ZStack {
Color(.systemGroupedBackground)
.edgesIgnoringSafeArea(.all)
selectedBackgroundColor .edgesIgnoringSafeArea(.all)
List {
ForEach(filteredApps, id: \.self) { app in
@ -172,12 +163,19 @@ struct InstalledAppsListView: View {
}
}
}
.searchable(text: $searchText, prompt: "Search Bundle IDs")
.searchable(text: $searchText, prompt: "Search Apps")
}
.onReceive(timer) { _ in
refreshBackground()
}
}
}
private func refreshBackground() {
selectedBackgroundColor = Color(hex: customBackgroundColorHex) ?? Color.primaryBackground
}
}
#Preview {
HomeView()
}

View file

@ -14,9 +14,9 @@ struct MainTabView: View {
.tabItem {
Label("Home", systemImage: "house")
}
DebugView()
SettingsView()
.tabItem {
Label("Debug", systemImage: "ladybug")
Label("Swttings", systemImage: "gearshape.fill")
}
}
}

View file

@ -0,0 +1,143 @@
//
// SettingsView.swift
// StikJIT
//
// Created by Stephen on 3/27/25.
//
import SwiftUI
struct SettingsView: View {
@AppStorage("username") private var username = "User"
@AppStorage("customBackgroundColor") private var customBackgroundColorHex: String = Color.primaryBackground.toHex() ?? "#000000"
@AppStorage("selectedAppIcon") private var selectedAppIcon: String = "AppIcon"
@State private var selectedBackgroundColor: Color = Color.primaryBackground
@State private var showIconPopover = false
var body: some View {
ZStack {
selectedBackgroundColor
.ignoresSafeArea()
Form {
Section(header: Text("General").font(.headline).foregroundColor(.primaryText)) {
HStack {
Label("", systemImage: "person.fill")
.foregroundColor(.primaryText)
Spacer()
TextField("Username", text: $username)
.foregroundColor(.primaryText)
.padding(10)
.background(Color.cardBackground)
.cornerRadius(10)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(selectedBackgroundColor, lineWidth: 1)
)
}
.listRowBackground(Color.cardBackground)
}
Section(header: Text("Appearance").font(.headline).foregroundColor(.primaryText)) {
ColorPicker("Background Color", selection: $selectedBackgroundColor)
.onChange(of: selectedBackgroundColor) { newColor in
saveCustomBackgroundColor(newColor)
}
.listRowBackground(Color.cardBackground)
.foregroundColor(.primaryText)
}
Section(header: Text("About").font(.headline).foregroundColor(.primaryText)) {
HStack {
Text("Version:")
.foregroundColor(.secondaryText)
Spacer()
Text("1.0")
.foregroundColor(.primaryText)
}
.listRowBackground(Color.cardBackground)
HStack {
Text("App Creator:")
.foregroundColor(.secondaryText)
Spacer()
Text("Stephen")
.foregroundColor(.primaryText)
}
.listRowBackground(Color.cardBackground)
HStack {
Text("idevice & em_proxy Creator:")
.foregroundColor(.secondaryText)
Spacer()
Text("jkcoxson")
.foregroundColor(.primaryText)
}
.listRowBackground(Color.cardBackground)
Button(action: {
if let url = URL(string: "https://github.com/0-Blu/StikJIT") {
UIApplication.shared.open(url)
}
}) {
HStack {
Text("View Source Code")
.foregroundColor(.secondaryText)
Spacer()
Image(systemName: "arrow.up.right.square")
.foregroundColor(.primaryText)
}
}
.listRowBackground(Color.cardBackground)
}
}
.background(selectedBackgroundColor)
.scrollContentBackground(.hidden)
.navigationBarTitle("Settings")
.font(.bodyFont)
.accentColor(.accentColor)
}
.onAppear {
loadCustomBackgroundColor()
}
}
private func loadCustomBackgroundColor() {
selectedBackgroundColor = Color(hex: customBackgroundColorHex) ?? Color.primaryBackground
}
private func saveCustomBackgroundColor(_ color: Color) {
customBackgroundColorHex = color.toHex() ?? "#000000"
}
private func changeAppIcon(to iconName: String) {
selectedAppIcon = iconName
UIApplication.shared.setAlternateIconName(iconName == "AppIcon" ? nil : iconName) { error in
if let error = error {
print("Error changing app icon: \(error.localizedDescription)")
}
}
}
private func iconButton(_ label: String, icon: String) -> some View {
Button(action: {
changeAppIcon(to: icon)
showIconPopover = false
}) {
HStack {
Image(uiImage: UIImage(named: icon) ?? UIImage())
.resizable()
.frame(width: 24, height: 24)
.clipShape(RoundedRectangle(cornerRadius: 5))
Text(label)
.foregroundColor(.primaryText)
Spacer()
}
.padding()
.background(Color.white.opacity(0.2))
.cornerRadius(10)
}
.padding(.horizontal)
}
}