Files
Sportstime/SportsTime/Export/Sharing/ShareService.swift
Trey t 244ea5e107 feat: redesign all share cards, remove unused achievement types, fix sport selector
Redesign trip, progress, and achievement share cards with premium
sports-media aesthetic. Remove unused milestone/context achievement card
types (only used in debug exporter). Fix gold text unreadable in light
mode. Fix sport selector to only show stroke on selected sport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 14:55:53 -06:00

122 lines
3.5 KiB
Swift

//
// ShareService.swift
// SportsTime
//
// Handles Instagram direct share and fallback to system share sheet.
//
import SwiftUI
import UIKit
@MainActor
final class ShareService {
static let shared = ShareService()
private init() {}
// MARK: - Share to Instagram
func shareToInstagram(image: UIImage) -> Bool {
guard let imageData = image.pngData() else { return false }
// Check if Instagram is installed
guard let instagramURL = URL(string: "instagram-stories://share"),
UIApplication.shared.canOpenURL(instagramURL) else {
return false
}
// Set up pasteboard with image
let pasteboardItems: [String: Any] = [
"com.instagram.sharedSticker.backgroundImage": imageData
]
UIPasteboard.general.setItems(
[pasteboardItems],
options: [.expirationDate: Date().addingTimeInterval(300)]
)
// Open Instagram Stories
let urlString = "instagram-stories://share?source_application=com.88oakapps.SportsTime"
if let url = URL(string: urlString) {
UIApplication.shared.open(url)
return true
}
return false
}
// MARK: - Copy to Clipboard
func copyToClipboard(image: UIImage) {
UIPasteboard.general.image = image
}
// MARK: - System Share Sheet
func presentShareSheet(image: UIImage, from viewController: UIViewController) {
let activityVC = UIActivityViewController(
activityItems: [image],
applicationActivities: nil
)
// iPad support
if let popover = activityVC.popoverPresentationController {
popover.sourceView = viewController.view
popover.sourceRect = CGRect(
x: viewController.view.bounds.midX,
y: viewController.view.bounds.midY,
width: 0,
height: 0
)
}
viewController.present(activityVC, animated: true)
}
}
// MARK: - Theme Persistence
enum ShareThemePreferences {
private static let tripKey = "shareTheme.trip"
private static let achievementKey = "shareTheme.achievement"
private static let progressKey = "shareTheme.progress"
static var tripTheme: ShareTheme {
get { ShareTheme.theme(byId: UserDefaults.standard.string(forKey: tripKey) ?? "dark") }
set { UserDefaults.standard.set(newValue.id, forKey: tripKey) }
}
static var achievementTheme: ShareTheme {
get { ShareTheme.theme(byId: UserDefaults.standard.string(forKey: achievementKey) ?? "dark") }
set { UserDefaults.standard.set(newValue.id, forKey: achievementKey) }
}
static var progressTheme: ShareTheme {
get { ShareTheme.theme(byId: UserDefaults.standard.string(forKey: progressKey) ?? "dark") }
set { UserDefaults.standard.set(newValue.id, forKey: progressKey) }
}
static func theme(for cardType: ShareCardType) -> ShareTheme {
switch cardType {
case .tripSummary:
return tripTheme
case .achievementSpotlight, .achievementCollection:
return achievementTheme
case .stadiumProgress:
return progressTheme
}
}
static func setTheme(_ theme: ShareTheme, for cardType: ShareCardType) {
switch cardType {
case .tripSummary:
tripTheme = theme
case .achievementSpotlight, .achievementCollection:
achievementTheme = theme
case .stadiumProgress:
progressTheme = theme
}
}
}