mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-15 20:10:30 +00:00
Better UI
This commit is contained in:
parent
ff92a9dbea
commit
3cb5fbad77
7 changed files with 234 additions and 67 deletions
44
StikJIT/Extensions & Stuff/Color.swift
Normal file
44
StikJIT/Extensions & Stuff/Color.swift
Normal 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)
|
||||
}
|
||||
14
StikJIT/Extensions & Stuff/Font.swift
Normal file
14
StikJIT/Extensions & Stuff/Font.swift
Normal 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)
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ import em_proxy
|
|||
struct HeartbeatApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
HomeView()
|
||||
MainTabView()
|
||||
.onAppear {
|
||||
startProxy()
|
||||
startHeartbeatInBackground()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ struct MainTabView: View {
|
|||
.tabItem {
|
||||
Label("Home", systemImage: "house")
|
||||
}
|
||||
DebugView()
|
||||
SettingsView()
|
||||
.tabItem {
|
||||
Label("Debug", systemImage: "ladybug")
|
||||
Label("Swttings", systemImage: "gearshape.fill")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
143
StikJIT/Views/SettingsView.swift
Normal file
143
StikJIT/Views/SettingsView.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue