Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cl
polar: # Replace with a single Polar username
buy_me_a_coffee: sameerasw
thanks_dev: # Replace with a single thanks.dev username
custom: ['airsync.sameerasw.com'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
custom: ['store.sameerasw.com'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

#template for @sameerasw
112 changes: 112 additions & 0 deletions AirSync.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,116 @@
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
11F6093B2EA2A88900AB6BDC /* Self Compiled */ = {
isa = XCBuildConfiguration;
baseConfigurationReferenceAnchor = B9673B592E35A2A1006D284A /* airsync-mac */;
baseConfigurationReferenceRelativePath = Configs/SelfCompiled.xcconfig;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = WCB4HTANA6;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = NO;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 26.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = macosx;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_COMPILATION_MODE = wholemodule;
};
name = "Self Compiled";
};
11F6093C2EA2A88900AB6BDC /* Self Compiled */ = {
isa = XCBuildConfiguration;
baseConfigurationReferenceAnchor = B9673B592E35A2A1006D284A /* airsync-mac */;
baseConfigurationReferenceRelativePath = Configs/SelfCompiled.xcconfig;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
AUTOMATION_APPLE_EVENTS = NO;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 11;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = WCB4HTANA6;
ENABLE_APP_SANDBOX = NO;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = NO;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "airsync-mac/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = AirSync;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
INFOPLIST_KEY_LSUIElement = NO;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.5;
MARKETING_VERSION = 2.1.1;
PRODUCT_BUNDLE_IDENTIFIER = "sameerasw.airsync-mac";
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO;
RUNTIME_EXCEPTION_ALLOW_JIT = NO;
RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY = NO;
RUNTIME_EXCEPTION_DEBUGGING_TOOL = NO;
RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION = NO;
RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
};
name = "Self Compiled";
};
B9673B602E35A2A3006D284A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
Expand Down Expand Up @@ -387,6 +497,7 @@
buildConfigurations = (
B9673B602E35A2A3006D284A /* Debug */,
B9673B612E35A2A3006D284A /* Release */,
11F6093B2EA2A88900AB6BDC /* Self Compiled */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
Expand All @@ -396,6 +507,7 @@
buildConfigurations = (
B9673B632E35A2A3006D284A /* Debug */,
B9673B642E35A2A3006D284A /* Release */,
11F6093C2EA2A88900AB6BDC /* Self Compiled */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2600"
version = "2.2">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<AutocreatedTestPlanReference>
</AutocreatedTestPlanReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B9673B562E35A2A1006D284A"
BuildableName = "AirSync.app"
BlueprintName = "AirSync"
ReferencedContainer = "container:AirSync.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Self Compiled"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Self Compiled"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B9673B562E35A2A1006D284A"
BuildableName = "AirSync.app"
BlueprintName = "AirSync"
ReferencedContainer = "container:AirSync.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Self Compiled"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B9673B562E35A2A1006D284A"
BuildableName = "AirSync.app"
BlueprintName = "AirSync"
ReferencedContainer = "container:AirSync.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Self Compiled">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Self Compiled"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
11 changes: 10 additions & 1 deletion AirSync.xcodeproj/xcshareddata/xcschemes/AirSync.xcscheme
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "2600"
version = "2.0">
version = "2.2">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
Expand All @@ -21,6 +21,15 @@
ReferencedContainer = "container:AirSync.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<AutocreatedTestPlanReference>
</AutocreatedTestPlanReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
- Min : macOS 14.5
- Opt: scrcpy, adb & media-control brew installs

## Building Locally
In XCode, select the `AirSync Self Compiled` Scheme. Then at the menu bar, select `Product -> Archive`. Once this process is finished, the organizer window will pop up. Select `Distribute`, then `Custom`. Select `Copy App`, then select the folder for output. `AirSync.app` will be located in that folder.

## Contributors <3

<a href="https://github.com/sameerasw/airsync-mac/graphs/contributors">
Expand All @@ -43,3 +46,4 @@
- [httpswift/swifter](https://github.com/httpswift/swifter)
- [sparkle-project/Sparkle](https://github.com/sparkle-project/Sparkle)
- [ungive/media-control](https://github.com/ungive/media-control)
- [tfmart/LottieUI](https://github.com/tfmart/LottieUI)
1 change: 1 addition & 0 deletions airsync-mac/Configs/SelfCompiled.xcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SWIFT_ACTIVE_COMPILATION_CONDITIONS=SELF_COMPILED
6 changes: 6 additions & 0 deletions airsync-mac/Core/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,15 @@ class AppState: ObservableObject {
startClipboardMonitoring()
}

#if SELF_COMPILED
self.isPlus = true
UserDefaults.standard.set(true, forKey: "isPlus")
UserDefaults.standard.lastLicenseSuccessfulCheckDate = Date().addingTimeInterval(-(24 * 60 * 60))
#else
Task {
await Gumroad().checkLicenseIfNeeded()
}
#endif

self.scrcpyBitrate = UserDefaults.standard.integer(forKey: "scrcpyBitrate")
if self.scrcpyBitrate == 0 { self.scrcpyBitrate = 4 }
Expand Down
30 changes: 15 additions & 15 deletions airsync-mac/Localization/de.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
{
"app.name": "AirSync",
"menu.mirror": "Mirror",
"menu.about": "About AirSync",
"menu.checkUpdates": "Check for Updates",
"menu.mirror": "Spiegeln",
"menu.about": "Über AirSync",
"menu.checkUpdates": "Auf Updates prüfen...",
"menu.quit": "Beenden",
"home.title": "AirSync",
"home.sidebar.ready": "Ready",
"onboarding.title": "Welcome to AirSync",
"notifications.empty.title": "You're all caught up!",
"home.sidebar.ready": "Fertig",
"onboarding.title": "Willkommen bei AirSync",
"notifications.empty.title": "Du bist auf dem Laufenden!",
"notifications.empty.emoji": "└(=^‥^=)┐",
"notifications.actions.hide": "Hide",
"notifications.actions.dismiss": "Dismiss",
"notifications.actions.hide": "Ausblenden",
"notifications.actions.dismiss": "Verwerfen",
"notifications.tab": "Benachrichtigungen",
"apps.tab": "Apps",
"transfers.tab": "Transfers",
"transfers.tab": "Übertragungen",
"settings.tab": "Einstellungen",
"qr.tab": "Scan QR",
"transfers.empty": "Nothing transferred yet",
"qr.tab": "QR-Code scannen",
"transfers.empty": "Noch nichts übertragen",
"plus.title": "AirSync+",
"plus.why": "Why Plus?",
"plus.why.body": "Keeps me inspired to continue and maybe even to publish to the Apple app store and Google Play Store. Think of it as a little donation to keep this project alive and evolving.\nThat said, I know not everyone who wants the full experience can afford it. If that’s you, please don’t hesitate to reach out. 😊\n\nThe source code is available on GitHub, and you're more than welcome to build with all Plus features free — for personal use which also opens for contributions which is a win-win!.\nAs a thank-you for supporting the app, AirSync+ unlocks some nice extras: media controls, synced widgets, low battery alerts, wireless ADB, and more to come as I keep adding new features.\n\nEnjoy the app!\n(っ◕‿◕)っ",
"license.enterKey": "Enter license key",
"plus.why": "Wieso Plus?",
"plus.why.body": "Es motiviert mich, weiterzumachen und vielleicht sogar im Apple App Store und Google Play Store zu veröffentlichen. Betrachte es als eine kleine Spende, um dieses Projekt am Leben zu erhalten und weiterzuentwickeln.\nAllerdings weiß ich, dass sich das nicht jeder, der das volle Erlebnis genießen möchte, leisten kann. Wenn das auf dich zutrifft, zöger bitte nicht, mich zu kontaktieren. 😊\n\nDer Quellcode ist auf GitHub verfügbar und du kannst gerne das Projekt selber bauen um alle Plus-Funktionen für den persönlichen Gebrauch kostenlos zu nutzen. Außerdem ermöglicht es das Mitwirken am Projekt. Eine Win-Win-Situation!\nAls Dankeschön für deine Unterstützung der App schaltet AirSync+ einige nette Extras frei: Mediensteuerung, synchronisierte Widgets, Warnungen bei niedrigem Akkustand, drahtloses ADB und weitere Funktionen, die ich nach und nach hinzufügen werde.\n\nViel Spaß mit der App!\n(っ◕‿◕)っ\n\nÜbersetzt mit DeepL.com (kostenlose Version)",
"license.enterKey": "Lizenz-Key eingeben",
"status.battery": "Batterie",
"status.volume": "Lautstärke",
"media.play": "Spiel",
"media.play": "Abspielen",
"media.pause": "Pause"
}
6 changes: 6 additions & 0 deletions airsync-mac/Model/LicensePlanType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ import Foundation
enum LicensePlanType: String, CaseIterable, Codable, Identifiable {
case membership
case oneTime
#if SELF_COMPILED
case selfCompiled
#endif

var id: String { rawValue }

var displayName: String {
switch self {
case .membership: return "Membership"
case .oneTime: return "One-Time"
#if SELF_COMPILED
case .selfCompiled: return "Self-Compiled"
#endif
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct PlusUnlockedSheet: View {
}

HStack(spacing: 8) {
#if !SELF_COMPILED
GlassButtonView(
label: "Unregister",
systemImage: "xmark.circle",
Expand All @@ -55,6 +56,7 @@ struct PlusUnlockedSheet: View {
}
)
.focusable(false)
#endif

GlassButtonView(
label: "Awesome",
Expand Down
Loading