feat: conditional buy me a coffee
This commit is contained in:
28
Gaze/Services/AppStoreDetector.swift
Normal file
28
Gaze/Services/AppStoreDetector.swift
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// AppStoreDetector.swift
|
||||||
|
// Gaze
|
||||||
|
//
|
||||||
|
// Created by Mike Freno on 1/10/26.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum AppStoreDetector {
|
||||||
|
/// Returns true if the app was downloaded from the Mac App Store
|
||||||
|
static var isAppStoreVersion: Bool {
|
||||||
|
#if DEBUG
|
||||||
|
return false
|
||||||
|
#else
|
||||||
|
guard let receiptURL = Bundle.main.appStoreReceiptURL else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if receipt exists and is in the expected App Store location
|
||||||
|
let fileManager = FileManager.default
|
||||||
|
let receiptExists = fileManager.fileExists(atPath: receiptURL.path)
|
||||||
|
let isInMASReceipt = receiptURL.path.contains("_MASReceipt")
|
||||||
|
|
||||||
|
return receiptExists && isInMASReceipt
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -101,13 +101,15 @@ struct BlinkSetupView: View {
|
|||||||
Button(action: {
|
Button(action: {
|
||||||
showPreviewWindow()
|
showPreviewWindow()
|
||||||
}) {
|
}) {
|
||||||
HStack {
|
HStack(spacing: 8) {
|
||||||
Image(systemName: "eye")
|
Image(systemName: "eye")
|
||||||
.foregroundColor(.accentColor)
|
.foregroundColor(.white)
|
||||||
Text("Preview Reminder")
|
Text("Preview Reminder")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
|
.foregroundColor(.white)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 44, alignment: .center)
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.vertical, 10)
|
||||||
}
|
}
|
||||||
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
|
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,13 +122,15 @@ struct LookAwaySetupView: View {
|
|||||||
Button(action: {
|
Button(action: {
|
||||||
showPreviewWindow()
|
showPreviewWindow()
|
||||||
}) {
|
}) {
|
||||||
HStack {
|
HStack(spacing: 8) {
|
||||||
Image(systemName: "eye")
|
Image(systemName: "eye")
|
||||||
.foregroundColor(.accentColor)
|
.foregroundColor(.white)
|
||||||
Text("Preview Reminder")
|
Text("Preview Reminder")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
|
.foregroundColor(.white)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 44, alignment: .center)
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.vertical, 10)
|
||||||
}
|
}
|
||||||
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
|
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,13 +101,15 @@ struct PostureSetupView: View {
|
|||||||
Button(action: {
|
Button(action: {
|
||||||
showPreviewWindow()
|
showPreviewWindow()
|
||||||
}) {
|
}) {
|
||||||
HStack {
|
HStack(spacing: 8) {
|
||||||
Image(systemName: "eye")
|
Image(systemName: "eye")
|
||||||
.foregroundColor(.accentColor)
|
.foregroundColor(.white)
|
||||||
Text("Preview Reminder")
|
Text("Preview Reminder")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
|
.foregroundColor(.white)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 44, alignment: .center)
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.vertical, 10)
|
||||||
}
|
}
|
||||||
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
|
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,36 +132,37 @@ struct SettingsOnboardingView: View {
|
|||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 10))
|
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 10))
|
||||||
|
|
||||||
// Buy Me a Coffee
|
if !AppStoreDetector.isAppStoreVersion {
|
||||||
Button(action: {
|
Button(action: {
|
||||||
if let url = URL(string: "https://buymeacoffee.com/placeholder") {
|
if let url = URL(string: "https://buymeacoffee.com/placeholder") {
|
||||||
NSWorkspace.shared.open(url)
|
NSWorkspace.shared.open(url)
|
||||||
}
|
|
||||||
}) {
|
|
||||||
HStack {
|
|
||||||
Image(systemName: "cup.and.saucer.fill")
|
|
||||||
.font(.title3)
|
|
||||||
.foregroundColor(.orange)
|
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
|
||||||
Text("Buy Me a Coffee")
|
|
||||||
.font(.subheadline)
|
|
||||||
.fontWeight(.semibold)
|
|
||||||
Text("Support development of Gaze")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
}
|
}
|
||||||
Spacer()
|
}) {
|
||||||
Image(systemName: "arrow.up.right")
|
HStack {
|
||||||
.font(.caption)
|
Image(systemName: "cup.and.saucer.fill")
|
||||||
|
.font(.title3)
|
||||||
|
.foregroundColor(.orange)
|
||||||
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
Text("Buy Me a Coffee")
|
||||||
|
.font(.subheadline)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
Text("Support development of Gaze")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: "arrow.up.right")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.background(Color.orange.opacity(0.1))
|
||||||
|
.cornerRadius(10)
|
||||||
}
|
}
|
||||||
.padding()
|
.buttonStyle(.plain)
|
||||||
.frame(maxWidth: .infinity)
|
.glassEffect(
|
||||||
.background(Color.orange.opacity(0.1))
|
.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 10))
|
||||||
.cornerRadius(10)
|
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
|
||||||
.glassEffect(
|
|
||||||
.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 10))
|
|
||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
|
|||||||
17
GazeTests/Services/AppStoreDetectorTests.swift
Normal file
17
GazeTests/Services/AppStoreDetectorTests.swift
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// AppStoreDetectorTests.swift
|
||||||
|
// GazeTests
|
||||||
|
//
|
||||||
|
// Created by Mike Freno on 1/10/26.
|
||||||
|
//
|
||||||
|
|
||||||
|
@testable import Gaze
|
||||||
|
import Testing
|
||||||
|
|
||||||
|
struct AppStoreDetectorTests {
|
||||||
|
|
||||||
|
@Test func isAppStoreVersionReturnsFalseInDebug() {
|
||||||
|
// In test/debug builds, should always return false
|
||||||
|
#expect(AppStoreDetector.isAppStoreVersion == false)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user