Add player info and support links to UI

Extended TornResponse to include player name and ID, and updated API selections to fetch basic info. StatusView now displays the player's name and ID if available. SettingsView adds a 'Tip Me' section for developer support and a GitHub source link.
This commit is contained in:
Paweł Orzech 2026-01-17 19:29:13 +00:00
parent 802fdfa1a3
commit 974556b24c
No known key found for this signature in database
3 changed files with 104 additions and 17 deletions

View file

@ -2,6 +2,8 @@ import Foundation
// MARK: - Root Response
struct TornResponse: Codable {
let name: String?
let playerId: Int?
let energy: Bar?
let nerve: Bar?
let life: Bar?
@ -10,6 +12,13 @@ struct TornResponse: Codable {
let travel: Travel?
let error: TornError?
enum CodingKeys: String, CodingKey {
case name
case playerId = "player_id"
case energy, nerve, life, happy
case cooldowns, travel, error
}
// Convenience computed property
var bars: Bars? {
guard let energy = energy,
@ -90,7 +99,7 @@ struct TornError: Codable {
// MARK: - API Configuration
enum TornAPI {
static let baseURL = "https://api.torn.com/user/"
static let selections = "bars,cooldowns,travel"
static let selections = "basic,bars,cooldowns,travel"
static func url(for apiKey: String) -> URL? {
URL(string: "\(baseURL)?selections=\(selections)&key=\(apiKey)")

View file

@ -4,6 +4,9 @@ struct SettingsView: View {
@EnvironmentObject var appState: AppState
@State private var inputKey: String = ""
// Developer ID for tip feature (bombel)
private let developerID = 2362436
var body: some View {
VStack(spacing: 16) {
// Header
@ -52,10 +55,73 @@ struct SettingsView: View {
}
.toggleStyle(.switch)
.padding(.horizontal)
Divider()
.padding(.vertical, 4)
// Tip Me section
tipMeSection
// GitHub link
githubSection
}
.padding()
.onAppear {
inputKey = appState.apiKey
}
}
// MARK: - Tip Me Section
private var tipMeSection: some View {
VStack(spacing: 8) {
HStack {
Image(systemName: "gift.fill")
.foregroundColor(.purple)
Text("Support the Developer")
.font(.caption.bold())
}
Text("Send me some Xanax or cash :)")
.font(.caption2)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
Button {
openTornProfile()
} label: {
HStack {
Image(systemName: "paperplane.fill")
Text("Send Xanax to bombel")
}
.font(.caption)
.padding(.vertical, 8)
.padding(.horizontal, 16)
.background(Color.purple.opacity(0.15))
.cornerRadius(8)
}
.buttonStyle(.plain)
}
.padding()
.background(Color.purple.opacity(0.05))
.cornerRadius(8)
}
// MARK: - GitHub Section
private var githubSection: some View {
HStack {
Image(systemName: "chevron.left.forwardslash.chevron.right")
.foregroundColor(.gray)
Link("View Source on GitHub",
destination: URL(string: "https://github.com/pawelorzech/MacTorn")!)
.font(.caption)
}
}
// MARK: - Helpers
private func openTornProfile() {
let url = "https://www.torn.com/profiles.php?XID=\(developerID)"
if let url = URL(string: url) {
NSWorkspace.shared.open(url)
}
}
}

View file

@ -39,23 +39,35 @@ struct StatusView: View {
// MARK: - Header
private var headerSection: some View {
HStack {
Text("Torn Status")
.font(.headline)
Spacer()
if appState.isLoading {
ProgressView()
.scaleEffect(0.6)
} else {
Button {
appState.refreshNow()
} label: {
Image(systemName: "arrow.clockwise")
VStack(alignment: .leading, spacing: 4) {
HStack {
if let name = appState.data?.name, let id = appState.data?.playerId {
VStack(alignment: .leading, spacing: 2) {
Text(name)
.font(.headline)
Text("[\(String(id))]")
.font(.caption2.monospacedDigit())
.foregroundColor(.secondary)
}
} else {
Text("Torn Status")
.font(.headline)
}
Spacer()
if appState.isLoading {
ProgressView()
.scaleEffect(0.6)
} else {
Button {
appState.refreshNow()
} label: {
Image(systemName: "arrow.clockwise")
}
.buttonStyle(.plain)
.foregroundColor(.secondary)
}
.buttonStyle(.plain)
.foregroundColor(.secondary)
}
}
}