Feature: Replaced Crashlytics with Sentry

Crash logging is now handled by the Sentry service.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-02-26 01:11:55 -08:00
parent 30d9eeec2b
commit 4a0cca22b8
20 changed files with 232 additions and 304 deletions

1
.gitignore vendored
View file

@ -7,6 +7,7 @@ xcuserdata
# User-specific xcconfig files
Xcode-config/DEVELOPMENT_TEAM.xcconfig
Xcode-config/SENTRY_SETTINGS.xcconfig
# Plist derived from template at build time
/Info.plist

View file

@ -31,7 +31,9 @@
#import "PreferencesController.h"
@import Firebase;
#import "FeedbackController.h"
@import Sentry;
void *kAppControllerContext = &kAppControllerContext;
@ -166,18 +168,13 @@ static AppController *kAppController = nil;
return [key isEqualToString:@"currentEntry"];
}
static BOOL consentLastEnabled = NO;
- (void)awakeFromNib {
#if DEBUG
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions": @(NO) }];
#else
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions": @(YES) }];
#endif
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"crashlyticsConsented": @(NO),
@"crashlyticsAskedConsent": @(NO) }];
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"sentryConsented": @(NO),
@"sentryAskedConsent": @(NO) }];
[FIRApp configure];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.crashlyticsConsented" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kAppControllerContext];
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.sentryConsented" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:kAppControllerContext];
[[totalTimeField cell] setBackgroundStyle:NSBackgroundStyleRaised];
@ -323,10 +320,45 @@ static AppController *kAppController = nil;
return;
}
if([keyPath isEqualToString:@"values.crashlyticsConsented"]) {
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"crashlyticsConsented"];
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:enabled];
[FIRAnalytics setAnalyticsCollectionEnabled:enabled];
if([keyPath isEqualToString:@"values.sentryConsented"]) {
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"sentryConsented"];
if(enabled != consentLastEnabled) {
if(enabled) {
[SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
options.dsn = @"https://b5eda1c2390eb965a74dd735413b6392@cog-analytics.losno.co/3";
options.debug = YES; // Enabled debug when first installing is always helpful
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
// We recommend adjusting this value in production.
options.tracesSampleRate = @1.0;
// Adds IP for users.
// For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/
options.sendDefaultPii = YES;
// And now to set up user feedback prompting
options.onCrashedLastRun = ^void(SentryEvent * _Nonnull event) {
// capture user feedback
FeedbackController *fbcon = [[FeedbackController alloc] init];
[fbcon performSelectorOnMainThread:@selector(showWindow:) withObject:nil waitUntilDone:YES];
if([fbcon waitForCompletion]) {
SentryUserFeedback *userFeedback = [[SentryUserFeedback alloc] initWithEventId:[event eventId]];
userFeedback.comments = [fbcon comments];
userFeedback.email = [fbcon email];
userFeedback.name = [fbcon name];
[SentrySDK captureUserFeedback:userFeedback];
}
};
}];
} else {
if([SentrySDK isEnabled]) {
[SentrySDK close];
}
}
consentLastEnabled = enabled;
}
} else if([keyPath isEqualToString:@"playlistController.currentEntry"]) {
PlaylistEntry *entry = playlistController.currentEntry;
NSString *appTitle = NSLocalizedString(@"CogTitle", @"");

View file

@ -19,7 +19,7 @@
#import "Logging.h"
@import Firebase;
//@import Sentry;
extern BOOL kAppControllerShuttingDown;
@ -284,11 +284,11 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
if(!pe.url) {
pe.error = YES;
pe.errorMessage = NSLocalizedStringFromTableInBundle(@"ErrorMessageBadFile", nil, [NSBundle bundleForClass:[self class]], @"");
[[FIRCrashlytics crashlytics] log:@"Attempting to play bad file."];
//[[FIRCrashlytics crashlytics] log:@"Attempting to play bad file."];
return;
}
[[FIRCrashlytics crashlytics] logWithFormat:@"Playing track: %@", pe.url];
//[[FIRCrashlytics crashlytics] logWithFormat:@"Playing track: %@", pe.url];
DLog(@"PLAYLIST CONTROLLER: %@", [playlistController class]);
[playlistController setCurrentEntry:pe];
@ -767,15 +767,15 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
}
if(pe && pe.url) {
[[FIRCrashlytics crashlytics] logWithFormat:@"Beginning decoding track: %@", pe.url];
//[[FIRCrashlytics crashlytics] logWithFormat:@"Beginning decoding track: %@", pe.url];
[player setNextStream:pe.url withUserInfo:pe withRGInfo:makeRGInfo(pe)];
} else if(pe) {
[[FIRCrashlytics crashlytics] log:@"Invalid playlist entry reached."];
//[[FIRCrashlytics crashlytics] log:@"Invalid playlist entry reached."];
[player setNextStream:nil];
pe.error = YES;
pe.errorMessage = NSLocalizedStringFromTableInBundle(@"ErrorMessageBadFile", nil, [NSBundle bundleForClass:[self class]], @"");
} else {
[[FIRCrashlytics crashlytics] log:@"End of playlist reached."];
//[[FIRCrashlytics crashlytics] log:@"End of playlist reached."];
[player setNextStream:nil];
}
}
@ -786,7 +786,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
// Delay the action until this function has returned to the audio thread
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
if(pe) {
[[FIRCrashlytics crashlytics] logWithFormat:@"Updating UI with track: %@", pe.url];
//[[FIRCrashlytics crashlytics] logWithFormat:@"Updating UI with track: %@", pe.url];
}
[self->playlistController setCurrentEntry:pe];
@ -817,7 +817,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
}
if(status == CogStatusStopped) {
[[FIRCrashlytics crashlytics] log:@"Stopped."];
//[[FIRCrashlytics crashlytics] log:@"Stopped."];
[self setPosition:0];
[self setSeekable:NO]; // the player stopped, disable the slider
@ -825,11 +825,11 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
[[NSNotificationCenter defaultCenter] postNotificationName:CogPlaybackDidStopNotificiation object:nil];
} else // paused
{
[[FIRCrashlytics crashlytics] log:@"Paused."];
//[[FIRCrashlytics crashlytics] log:@"Paused."];
[[NSNotificationCenter defaultCenter] postNotificationName:CogPlaybackDidPauseNotificiation object:nil];
}
} else if(status == CogStatusPlaying) {
[[FIRCrashlytics crashlytics] log:@"Started playing."];
//[[FIRCrashlytics crashlytics] log:@"Started playing."];
if(!positionTimer) {
positionTimer = [NSTimer timerWithTimeInterval:0.2 target:self selector:@selector(updatePosition:) userInfo:nil repeats:YES];
@ -865,7 +865,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
- (void)audioPlayer:(AudioPlayer *)player didStopNaturally:(id)userInfo {
if([[NSUserDefaults standardUserDefaults] boolForKey:@"quitOnNaturalStop"]) {
[[FIRCrashlytics crashlytics] log:@"Terminating due to natural stop."];
//[[FIRCrashlytics crashlytics] log:@"Terminating due to natural stop."];
[NSApp terminate:nil];
}
}
@ -880,7 +880,7 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
- (void)audioPlayer:(AudioPlayer *)player restartPlaybackAtCurrentPosition:(id)userInfo {
PlaylistEntry *pe = [playlistController currentEntry];
BOOL paused = playbackStatus == CogStatusPaused;
[[FIRCrashlytics crashlytics] logWithFormat:@"Restarting playback of track: %@", pe.url];
//[[FIRCrashlytics crashlytics] logWithFormat:@"Restarting playback of track: %@", pe.url];
[player performSelectorOnMainThread:@selector(playBG:withUserInfo:withRGInfo:startPaused:andSeekTo:) withObjects:pe.url, pe, makeRGInfo(pe), @(paused), @(pe.seekable ? pe.currentPosition : 0.0), nil];
}

View file

@ -389,8 +389,6 @@ static NSString *xmlEscapeString(NSString * string) {
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\
<plist version=\"1.0\">\n\
<dict>\n\
\t<key>FirebaseCrashlyticsCollectionEnabled</key>\n\
\t<false/>\n\
\t<key>SUEnableInstallerLauncherService</key>\n\
\t<true/>\n\
\t<key>CFBundleDevelopmentRegion</key>\n\

View file

@ -1,23 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22113.1" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22113.1"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="FeedbackController">
<connections>
<outlet property="fromView" destination="5" id="37"/>
<outlet property="messageView" destination="15" id="38"/>
<outlet property="sendingIndicator" destination="12" id="39"/>
<outlet property="subjectView" destination="10" id="36"/>
<outlet property="emailView" destination="10" id="X4O-Qx-zUq"/>
<outlet property="messageView" destination="15" id="gwe-Bb-ZEz"/>
<outlet property="nameView" destination="5" id="9Uz-Hh-EVf"/>
<outlet property="window" destination="1" id="42"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Send Feedback" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="1" userLabel="FeedbackWindow">
<window title="Send Crash Feedback" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="1" userLabel="FeedbackWindow">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="168" y="357" width="480" height="376"/>
@ -27,7 +26,37 @@
<rect key="frame" x="0.0" y="0.0" width="480" height="376"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="10">
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8" userLabel="Name:">
<rect key="frame" x="17" y="339" width="58" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Name:" id="18" userLabel="Name:">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5" userLabel="Name Field">
<rect key="frame" x="80" y="337" width="356" height="22"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="21">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="nextKeyView" destination="10" id="CNG-sG-ab3"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
<rect key="frame" x="17" y="297" width="58" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Email:" id="22">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="10" userLabel="Email Field">
<rect key="frame" x="80" y="295" width="356" height="22"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" alignment="left" drawsBackground="YES" id="16">
@ -36,22 +65,13 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="nextKeyView" destination="15" id="30"/>
<outlet property="nextKeyView" destination="15" id="Xi7-6Y-bG1"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8">
<rect key="frame" x="17" y="297" width="58" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Subject:" id="18">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7">
<rect key="frame" x="17" y="262" width="66" height="17"/>
<rect key="frame" x="17" y="262" width="272" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Message:" id="19">
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Describe what you were doing:" id="19">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
@ -61,15 +81,15 @@
<rect key="frame" x="20" y="55" width="440" height="199"/>
<autoresizingMask key="autoresizingMask"/>
<clipView key="contentView" drawsBackground="NO" id="tK9-bv-5OD">
<rect key="frame" x="1" y="1" width="438" height="197"/>
<rect key="frame" x="1" y="1" width="423" height="197"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" usesRuler="YES" smartInsertDelete="YES" id="15">
<rect key="frame" x="0.0" y="0.0" width="438" height="197"/>
<rect key="frame" x="0.0" y="0.0" width="423" height="197"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="438" height="197"/>
<size key="minSize" width="423" height="197"/>
<size key="maxSize" width="863" height="10000000"/>
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
</textView>
@ -80,7 +100,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="14">
<rect key="frame" x="423" y="1" width="16" height="197"/>
<rect key="frame" x="424" y="1" width="15" height="197"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<connections>
@ -111,31 +131,6 @@
<outlet property="nextKeyView" destination="5" id="28"/>
</connections>
</button>
<progressIndicator horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" maxValue="100" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="12">
<rect key="frame" x="444" y="340" width="16" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</progressIndicator>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="80" y="337" width="356" height="22"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="21">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="nextKeyView" destination="10" id="33"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4">
<rect key="frame" x="17" y="339" width="71" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="Email:" id="22">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
<connections>

View file

@ -143,6 +143,7 @@
837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 837DC92F285B3F790005C58A /* DataModel.xcdatamodeld */; };
8381A09227C5F72F00A1C530 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8381A09127C5F72F00A1C530 /* SHA256Digest.m */; };
8384914018083E4E00E7332D /* filetype.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8384913D18083E4E00E7332D /* filetype.icns */; };
838770FA2D6F0996001455A0 /* FeedbackController.m in Sources */ = {isa = PBXBuildFile; fileRef = 838770F42D6F0996001455A0 /* FeedbackController.m */; };
838A33742D06A9B100D0D770 /* librubberband.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 838A33732D06A9B100D0D770 /* librubberband.3.dylib */; };
838A33752D06A9CE00D0D770 /* librubberband.3.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 838A33732D06A9B100D0D770 /* librubberband.3.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
838A337D2D06C14200D0D770 /* TempoSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 838A337C2D06C14200D0D770 /* TempoSlider.m */; };
@ -153,9 +154,6 @@
83922FBA286B1AA900A0B039 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83922FB6286B1AA900A0B039 /* WebKit.framework */; };
839614A2286ED97200D3EEDB /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614A0286ED97200D3EEDB /* AboutWindowController.xib */; };
839614AD286EDA5C00D3EEDB /* SpectrumWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 839614AB286EDA5C00D3EEDB /* SpectrumWindow.xib */; };
83978E16285C58190076ED21 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 83978E15285C58190076ED21 /* FirebaseCrashlytics */; };
83978E26285C596F0076ED21 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 83978E25285C596F0076ED21 /* FirebaseAnalytics */; };
83978E29285C5C0A0076ED21 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 83978E28285C5C0A0076ED21 /* GoogleService-Info.plist */; };
83988F0E27BE0A5900A0E89A /* RedundantPlaylistDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */; };
8399D4E21805A55000B503B1 /* XmlContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8399D4E01805A55000B503B1 /* XmlContainer.m */; };
839B837F286D7F8D00F529EE /* NumberHertzToStringTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839B837E286D7F8D00F529EE /* NumberHertzToStringTransformer.swift */; };
@ -182,6 +180,7 @@
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
83F9D8071A884C54007ABEC2 /* SilenceDecoder.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83F9D7F61A884B46007ABEC2 /* SilenceDecoder.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 83F9FFEE2D6EB75B00026576 /* Sentry */; };
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
@ -196,7 +195,7 @@
8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E8D41C70CBB0DA000135C1B /* Pls.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */; };
99EAACA80DD1BB7A00423C38 /* APL.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 566D321B0D538550004466A5 /* APL.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F5622E0C3BD8FB0019975C /* Preferences.preferencePane */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in Copy Files */ = {isa = PBXBuildFile; fileRef = 17F5622E0C3BD8FB0019975C /* Preferences.preferencePane */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
ED69CBC725BE32C00090B90D /* MASShortcut.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED69CBBF25BE328C0090B90D /* MASShortcut.framework */; };
ED69CBCA25BE32E80090B90D /* MASShortcut.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = ED69CBBF25BE328C0090B90D /* MASShortcut.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
EDAAA41F25A665C000731773 /* PositionSliderToolbarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDAAA41E25A665C000731773 /* PositionSliderToolbarItem.swift */; };
@ -662,14 +661,15 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
07DFC3930ECDF80100DA400D /* CopyFiles */ = {
07DFC3930ECDF80100DA400D /* Copy Files */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 7;
files = (
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in CopyFiles */,
ED69CA3B25BE2A390090B90D /* Preferences.preferencePane in Copy Files */,
);
name = "Copy Files";
runOnlyForDeploymentPostprocessing = 0;
};
177FD1000B90CB570011C3B5 /* CopyFiles */ = {
@ -969,6 +969,8 @@
8384912518080F2D00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
8384913D18083E4E00E7332D /* filetype.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = filetype.icns; sourceTree = "<group>"; };
83859520234FEB35004E9946 /* Cog.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Cog.entitlements; sourceTree = "<group>"; };
838770F32D6F0996001455A0 /* FeedbackController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedbackController.h; sourceTree = "<group>"; };
838770F42D6F0996001455A0 /* FeedbackController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedbackController.m; sourceTree = "<group>"; };
838A33732D06A9B100D0D770 /* librubberband.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = librubberband.3.dylib; path = ThirdParty/rubberband/lib/librubberband.3.dylib; sourceTree = "<group>"; };
838A33792D06C14200D0D770 /* PitchSlider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PitchSlider.h; path = Window/PitchSlider.h; sourceTree = "<group>"; };
838A337A2D06C14200D0D770 /* PitchSlider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = PitchSlider.m; path = Window/PitchSlider.m; sourceTree = "<group>"; };
@ -992,7 +994,6 @@
839614AC286EDA5C00D3EEDB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/SpectrumWindow.xib; sourceTree = "<group>"; };
839614AF286EDA6800D3EEDB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
839614B1286EDA6E00D3EEDB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/SpectrumWindow.strings; sourceTree = "<group>"; };
83978E28285C5C0A0076ED21 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
83988F0C27BE0A5900A0E89A /* RedundantPlaylistDataStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RedundantPlaylistDataStore.h; sourceTree = "<group>"; };
83988F0D27BE0A5900A0E89A /* RedundantPlaylistDataStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RedundantPlaylistDataStore.m; sourceTree = "<group>"; };
8399D4E01805A55000B503B1 /* XmlContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XmlContainer.m; sourceTree = "<group>"; };
@ -1081,11 +1082,10 @@
835FAC7E27BCDF5B00BA8562 /* libaom.a in Frameworks */,
837DC92B285B05710005C58A /* CoreData.framework in Frameworks */,
838A33742D06A9B100D0D770 /* librubberband.3.dylib in Frameworks */,
83978E26285C596F0076ED21 /* FirebaseAnalytics in Frameworks */,
17BB5CF90B8A86350009ACB1 /* AudioUnit.framework in Frameworks */,
17BB5CFA0B8A86350009ACB1 /* CoreAudio.framework in Frameworks */,
83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */,
17BB5CFB0B8A86350009ACB1 /* CoreAudioKit.framework in Frameworks */,
83978E16285C58190076ED21 /* FirebaseCrashlytics in Frameworks */,
17BB5EA60B8A87850009ACB1 /* IOKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1105,6 +1105,7 @@
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
838770F72D6F0996001455A0 /* Feedback */,
835F00B3279BD1CD00055FCF /* Formatters */,
177042960B8BC53600B86321 /* Application */,
17E0D5D20F520E75005B6FED /* Window */,
@ -1462,7 +1463,6 @@
isa = PBXGroup;
children = (
0A1B412E286F6301008A6A44 /* Localizable.stringsdict */,
83978E28285C5C0A0076ED21 /* GoogleService-Info.plist */,
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */,
83859520234FEB35004E9946 /* Cog.entitlements */,
080E96DDFE201D6D7F000001 /* Classes */,
@ -1798,6 +1798,15 @@
name = Visualization;
sourceTree = "<group>";
};
838770F72D6F0996001455A0 /* Feedback */ = {
isa = PBXGroup;
children = (
838770F32D6F0996001455A0 /* FeedbackController.h */,
838770F42D6F0996001455A0 /* FeedbackController.m */,
);
path = Feedback;
sourceTree = "<group>";
};
83B0669D180D5668008E3612 /* Products */ = {
isa = PBXGroup;
children = (
@ -1969,8 +1978,8 @@
8D1107290486CEB800E47090 /* Resources */,
8E757AEC09F3265E0080F1EE /* CopyFiles */,
177FD1000B90CB570011C3B5 /* CopyFiles */,
07DFC3930ECDF80100DA400D /* CopyFiles */,
83978E27285C5A4C0076ED21 /* Run Crashlytics symbol upload */,
07DFC3930ECDF80100DA400D /* Copy Files */,
83978E27285C5A4C0076ED21 /* Run Sentry symbol upload */,
);
buildRules = (
);
@ -2009,8 +2018,7 @@
);
name = Cog;
packageProductDependencies = (
83978E15285C58190076ED21 /* FirebaseCrashlytics */,
83978E25285C596F0076ED21 /* FirebaseAnalytics */,
83F9FFEE2D6EB75B00026576 /* Sentry */,
);
productInstallPath = /Applications;
productName = Cog;
@ -2054,7 +2062,7 @@
);
mainGroup = 29B97314FDCFA39411CA2CEA /* Cog */;
packageReferences = (
83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
83F9FFED2D6EB75B00026576 /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
);
projectDirPath = "";
projectReferences = (
@ -2477,7 +2485,6 @@
832923AF279FAC400048201E /* Cog.q1.json in Resources */,
17D1B2820CF8B2830028F5B5 /* vg.icns in Resources */,
17D1B2830CF8B2830028F5B5 /* xm.icns in Resources */,
83978E29285C5C0A0076ED21 /* GoogleService-Info.plist in Resources */,
836DF61E298F7F6E00CD0580 /* Scenes.scnassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -2504,7 +2511,7 @@
shellPath = /bin/sh;
shellScript = "$SCRIPT_INPUT_FILE_0 $SCRIPT_INPUT_FILE_1 $SCRIPT_OUTPUT_FILE_0\n";
};
83978E27285C5A4C0076ED21 /* Run Crashlytics symbol upload */ = {
83978E27285C5A4C0076ED21 /* Run Sentry symbol upload */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 12;
@ -2516,14 +2523,14 @@
"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}",
"$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)",
);
name = "Run Crashlytics symbol upload";
name = "Run Sentry symbol upload";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [[ \"${CONFIGURATION}\" = \"Release\" ]] || [[ \"${CONFIGURATION}\" = \"Adhoc\" ]]; then\n echo \"Uploading dSYMs...\"\n find \"${DWARF_DSYM_FOLDER_PATH}\" -name \"*.dSYM\" -print0 | xargs -0 -I \\{\\} \"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols\" -gsp \"${SRCROOT}/GoogleService-Info.plist\" -p mac \\{\\}\nelse\n echo \"Skip dSYMs upload\"\nfi\n\nexit 0\n";
shellScript = "if [[ \"x${SENTRY_URL}\" != \"x\" ]] && [[ \"x${SENTRY_PROJECT}\" != \"x\" ]] && [[ \"x${SENTRY_AUTH_TOKEN}\" != \"x\" ]]; then\n if [[ \"${CONFIGURATION}\" = \"Release\" ]] || [[ \"${CONFIGURATION}\" = \"Adhoc\" ]]; then\n echo \"Uploading dSYMs...\"\n export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin\n sentry-cli --url \"${SENTRY_URL}\" debug-files upload -p \"${SENTRY_PROJECT}\" --auth-token \"${SENTRY_AUTH_TOKEN}\" --include-sources \"${DWARF_DSYM_FOLDER_PATH}\"\n else\n echo \"Skip dSYMs upload\"\n fi\nelse\n echo \"Sentry settings not configured\"\nfi\n\nexit 0\n";
};
/* End PBXShellScriptBuildPhase section */
@ -2552,6 +2559,7 @@
1755E1F90BA0D2B600CA3560 /* PlaylistLoader.m in Sources */,
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */,
179790E10C087AB7001D6996 /* OpenURLPanel.m in Sources */,
838770FA2D6F0996001455A0 /* FeedbackController.m in Sources */,
837DC931285B3F790005C58A /* DataModel.xcdatamodeld in Sources */,
835FAC7927BCDF2A00BA8562 /* AVIFDecoder.m in Sources */,
EDAAA41F25A665C000731773 /* PositionSliderToolbarItem.swift in Sources */,
@ -3157,26 +3165,21 @@
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
83F9FFED2D6EB75B00026576 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
repositoryURL = "https://github.com/getsentry/sentry-cocoa.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 10.0.0;
minimumVersion = 8.45.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
83978E15285C58190076ED21 /* FirebaseCrashlytics */ = {
83F9FFEE2D6EB75B00026576 /* Sentry */ = {
isa = XCSwiftPackageProductDependency;
package = 83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseCrashlytics;
};
83978E25285C596F0076ED21 /* FirebaseAnalytics */ = {
isa = XCSwiftPackageProductDependency;
package = 83978E14285C58190076ED21 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseAnalytics;
package = 83F9FFED2D6EB75B00026576 /* XCRemoteSwiftPackageReference "sentry-cocoa" */;
productName = Sentry;
};
/* End XCSwiftPackageProductDependency section */

View file

@ -1,123 +1,15 @@
{
"originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329",
"originHash" : "7b5e54f81ac1ebaa640945691cb38c371b637198701f04fba811702fc8e7067e",
"pins" : [
{
"identity" : "abseil-cpp-binary",
"identity" : "sentry-cocoa",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"location" : "https://github.com/getsentry/sentry-cocoa.git",
"state" : {
"revision" : "194a6706acbd25e4ef639bcaddea16e8758a3e27",
"version" : "1.2024011602.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "3b62f154d00019ae29a71e9738800bb6f18b236d",
"version" : "10.19.2"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "eca84fd638116dd6adb633b5a3f31cc7befcbb7d",
"version" : "10.29.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "fe727587518729046fc1465625b9afd80b5ab361",
"version" : "10.28.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "a637d318ae7ae246b02d7305121275bc75ed5565",
"version" : "9.4.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6",
"version" : "7.13.3"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359",
"version" : "1.62.2"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "a2ab612cb980066ee56d90d60d8462992c07f24b",
"version" : "3.5.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "2d12673670417654f08f5f90fdd62926dc3a2648",
"version" : "100.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
"version" : "2.30910.0"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
"version" : "2.4.0"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "e17d61f26df0f0e06f58f6977ba05a097a720106",
"version" : "1.27.1"
"revision" : "3640aaf7849a9fc39996d777e6df866251bb98d6",
"version" : "8.45.0"
}
}
],
"version" : 2
"version" : 3
}

View file

@ -10,15 +10,18 @@
#import <Cocoa/Cocoa.h>
@interface FeedbackController : NSWindowController <FeedbackSocketDelegate> {
IBOutlet NSTextField* fromView;
IBOutlet NSTextField* subjectView;
IBOutlet NSTextField* nameView;
IBOutlet NSTextField* emailView;
IBOutlet NSTextView* messageView;
IBOutlet NSProgressIndicator* sendingIndicator;
FeedbackSocket* feedbackSocket;
}
- (IBAction)sendFeedback:(id)sender;
- (IBAction)cancel:(id)sender;
- (BOOL)waitForCompletion;
- (NSString *)name;
- (NSString *)email;
- (NSString *)comments;
@end

View file

@ -10,62 +10,67 @@
#import "Logging.h"
@implementation FeedbackController
@implementation FeedbackController {
BOOL showing;
BOOL sent;
NSString *name;
NSString *email;
NSString *comments;
}
- (id)init {
return [super initWithWindowNibName:@"Feedback"];
self = [super initWithWindowNibName:@"Feedback"];
if(self) {
showing = NO;
sent = NO;
}
return self;
}
- (IBAction)showWindow:(id)sender {
[fromView setStringValue:@""];
[subjectView setStringValue:@""];
[nameView setStringValue:@""];
[emailView setStringValue:@""];
[messageView setString:@""];
[super showWindow:sender];
}
- (void)alertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo {
if([(NSNumber *)CFBridgingRelease(contextInfo) boolValue] == YES) {
[[self window] close];
}
}
- (void)feedbackDidNotSend:(FeedbackSocket *)feedback {
ALog(@"Error sending feedback");
[sendingIndicator stopAnimation:self];
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:NSLocalizedString(@"FeedbackFailedMessageText", @"")];
[alert setInformativeText:NSLocalizedString(@"FeedbackFailedInformativeText", @"")];
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:(void *)CFBridgingRetain([NSNumber numberWithBool:NO])];
}
- (void)feedbackDidSend:(FeedbackSocket *)feedback {
[sendingIndicator stopAnimation:self];
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:NSLocalizedString(@"FeedbackSuccessMessageText", @"")];
[alert setInformativeText:NSLocalizedString(@"FeedbackSuccessInformativeText", @"")];
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:(void *)CFBridgingRetain([NSNumber numberWithBool:YES])];
showing = YES;
}
- (IBAction)sendFeedback:(id)sender {
[sendingIndicator startAnimation:self];
name = [nameView stringValue];
email = [emailView stringValue];
comments = [messageView string];
// Using this so that if its a bad connection, it doesnt sit there looking stupid..or should it
feedbackSocket = [[FeedbackSocket alloc] init];
[feedbackSocket setDelegate:self];
NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
[feedbackSocket sendFeedback:[fromView stringValue] subject:[subjectView stringValue] message:[messageView string] version:version];
[[self window] close];
sent = YES;
showing = NO;
}
- (IBAction)cancel:(id)sender {
[[self window] close];
sent = NO;
showing = NO;
}
- (BOOL)waitForCompletion {
while(showing) {
usleep(2000);
}
return sent;
}
- (NSString *)name {
return name;
}
- (NSString *)email {
return email;
}
- (NSString *)comments {
return comments;
}
@end

View file

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FirebaseCrashlyticsCollectionEnabled</key>
<false/>
<key>SUEnableInstallerLauncherService</key>
<true/>
<key>CFBundleDevelopmentRegion</key>

View file

@ -41,8 +41,6 @@
#import "SandboxBroker.h"
@import Firebase;
extern NSMutableDictionary<NSString *, AlbumArtwork *> *kArtworkDictionary;
@implementation PlaylistLoader
@ -748,7 +746,7 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path);
[op addExecutionBlock:^{
@autoreleasepool {
DLog(@"Loading metadata for %@", url);
[[FIRCrashlytics crashlytics] logWithFormat:@"Loading metadata for %@", url];
//[[FIRCrashlytics crashlytics] logWithFormat:@"Loading metadata for %@", url];
NSDictionary *entryProperties = [AudioPropertiesReader propertiesForURL:url];
if(entryProperties == nil)
@ -883,7 +881,7 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path);
PlaylistEntry *pe = [entries objectAtIndex:idx];
DLog(@"Loading metadata for %@", pe.url);
[[FIRCrashlytics crashlytics] logWithFormat:@"Loading metadata for %@", pe.url];
//[[FIRCrashlytics crashlytics] logWithFormat:@"Loading metadata for %@", pe.url];
NSDictionary *entryProperties = [AudioPropertiesReader propertiesForURL:pe.url];
if(entryProperties == nil)

View file

@ -16,8 +16,6 @@
#import "Logging.h"
@import Firebase;
static NSString *playlistSavedColumnsID = @"Playlist Saved Columns v0";
@implementation PlaylistView
@ -121,7 +119,7 @@ static NSString *playlistSavedColumnsID = @"Playlist Saved Columns v0";
// Reset to defaults
NSString *message = @"Reset playlist columns to default";
DLog(@"%@", message);
[[FIRCrashlytics crashlytics] logWithFormat:@"%@", message];
//[[FIRCrashlytics crashlytics] logWithFormat:@"%@", message];
for(NSTableColumn *col in columns) {
[self removeTableColumn:col];
}

View file

@ -443,7 +443,7 @@
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<binding destination="52" name="value" keyPath="values.crashlyticsConsented" id="GQu-a0-JJs"/>
<binding destination="52" name="value" keyPath="values.sentryConsented" id="7I0-0u-zKC"/>
</connections>
</button>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="crf-C9-9YF">

View file

@ -16,26 +16,26 @@
// For instance, for the first option to get this treatment, we want time stretching to stay enabled
// for existing installations, but disable itself by default on new installs, to spare processing.
void showCrashlyticsConsent(NSWindow *window) {
BOOL askedConsent = [[NSUserDefaults standardUserDefaults] boolForKey:@"crashlyticsAskedConsent"];
void showSentryConsent(NSWindow *window) {
BOOL askedConsent = [[NSUserDefaults standardUserDefaults] boolForKey:@"sentryAskedConsent"];
if(!askedConsent) {
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"rubberbandEngine": @"disabled" }];
[window orderFront:window];
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:NSLocalizedString(@"CrashlyticsConsentTitle", @"")];
[alert setInformativeText:NSLocalizedString(@"CrashlyticsConsentText", @"")];
[alert setMessageText:NSLocalizedString(@"SentryConsentTitle", @"")];
[alert setInformativeText:NSLocalizedString(@"SentryConsentText", @"")];
[alert addButtonWithTitle:NSLocalizedString(@"ConsentYes",@"")];
[alert addButtonWithTitle:NSLocalizedString(@"ConsentNo", @"")];
[alert beginSheetModalForWindow:window completionHandler:^(NSModalResponse returnCode) {
if(returnCode == NSAlertFirstButtonReturn) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"crashlyticsConsented"];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"sentryConsented"];
}
}];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"crashlyticsAskedConsent"];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"sentryAskedConsent"];
} else {
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"rubberbandEngine": @"faster" }];
}
@ -62,7 +62,7 @@ void showCrashlyticsConsent(NSWindow *window) {
[self showHDCDLogo:NO];
if(![[NSUserDefaults standardUserDefaults] boolForKey:@"miniMode"]) {
showCrashlyticsConsent(self);
showSentryConsent(self);
}
}

View file

@ -12,7 +12,7 @@
extern NSString *iTunesDropType;
extern void showCrashlyticsConsent(NSWindow *window);
extern void showSentryConsent(NSWindow *window);
@implementation MiniWindow
@ -44,7 +44,7 @@ extern void showCrashlyticsConsent(NSWindow *window);
[self registerForDraggedTypes:@[NSPasteboardTypeFileURL, iTunesDropType]];
if([[NSUserDefaults standardUserDefaults] boolForKey:@"miniMode"]) {
showCrashlyticsConsent(self);
showSentryConsent(self);
}
}

View file

@ -47,3 +47,8 @@
// CODE_SIGN_IDENTITY = …;
// CODE_SIGN_STYLE = Manual/Automatic;
// Please make sure not to commit them to source control.
#include? "SENTRY_SETTINGS.xcconfig"
// Also, create this file if you wish to upload symbols to your server on build.
// It should define SENTRY_URL, SENTRY_PROJECT to the ID number, and finally
// SENTRY_AUTH_TOKEN to the developer authorization token for your instance.

View file

@ -1,15 +1,15 @@
/* Class = "NSWindow"; title = "Send Feedback"; ObjectID = "1"; */
"1.title" = "Send Feedback";
/* Class = "NSWindow"; title = "Send Crash Feedback"; ObjectID = "1"; */
"1.title" = "Send Crash Feedback";
/* Class = "NSButtonCell"; title = "Send"; ObjectID = "17"; */
"17.title" = "Send";
/* Class = "NSTextFieldCell"; title = "Subject:"; ObjectID = "18"; */
"18.title" = "Subject:";
/* Class = "NSTextFieldCell"; title = "Name:"; ObjectID = "18"; */
"18.title" = "Name:";
/* Class = "NSTextFieldCell"; title = "Message:"; ObjectID = "19"; */
"19.title" = "Message:";
/* Class = "NSTextFieldCell"; title = "Describe what you were doing:"; ObjectID = "19"; */
"19.title" = "Describe what you were doing:";
/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "20"; */
"20.title" = "Cancel";

View file

@ -2,8 +2,8 @@
"CogTitle" = "Cog";
"ConsentNo" = "No";
"ConsentYes" = "Yes";
"CrashlyticsConsentText" = "Would you like to allow Crashlytics to submit crash reports? You may turn this off again in Preferences. We won't ask you again.";
"CrashlyticsConsentTitle" = "Crashlytics crash collection";
"SentryConsentText" = "Would you like to allow Sentry to submit crash reports? You may turn this off again in Preferences. We won't ask you again.";
"SentryConsentTitle" = "Sentry crash collection";
"ErrorInvalidTrackId" = "Invalid track ID sent to SQLite request.";
"ErrorMessageBadFile" = "Unable to parse metadata for bad file.";
"ErrorMetadata" = "Unable to retrieve metadata.";

View file

@ -1,18 +1,18 @@
/* Class = "NSWindow"; title = "Send Feedback"; ObjectID = "1"; */
"1.title" = "Enviar comentarios";
/* Class = "NSWindow"; title = "Send Crash Feedback"; ObjectID = "1"; */
"1.title" = "Enviar comentarios por fallo";
/* Class = "NSButtonCell"; title = "Send"; ObjectID = "17"; */
"17.title" = "Enviar";
/* Class = "NSTextFieldCell"; title = "Subject:"; ObjectID = "18"; */
"18.title" = "Asunto:";
/* Class = "NSTextFieldCell"; title = "Name:"; ObjectID = "18"; */
"18.title" = "Nombre:";
/* Class = "NSTextFieldCell"; title = "Message:"; ObjectID = "19"; */
"19.title" = "Mensaje:";
/* Class = "NSTextFieldCell"; title = "Describe what you were doing:"; ObjectID = "19"; */
"19.title" = "Describe lo que estabas haciendo:";
/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "20"; */
"20.title" = "Cancelar";
/* Class = "NSTextFieldCell"; title = "Email:"; ObjectID = "22"; */
"22.title" = "Correo electrónico:";
"22.title" = "Email:";

View file

@ -2,8 +2,8 @@
"CogTitle" = "Cog";
"ConsentNo" = "No";
"ConsentYes" = "Sí";
"CrashlyticsConsentText" = "¿Te gustaría permitir que Crashlytics envíe informes de fallos? Puedes volver a desactivarlo en Preferencias. No te volveremos a preguntar.";
"CrashlyticsConsentTitle" = "Colección de fallos de Crashlytics";
"SentryConsentText" = "¿Te gustaría permitir que Sentry envíe informes de fallos? Puedes volver a desactivarlo en Preferencias. No te volveremos a preguntar.";
"CrashlyticsConsentTitle" = "Colección de fallos de Sentry";
"ErrorInvalidTrackId" = "ID de pista inválida enviada a la solicitud de SQLite.";
"ErrorMessageBadFile" = "No se han podido analizar los metadatos de un archivo defectuoso.";
"ErrorMetadata" = "No se pueden recuperar los metadatos.";