Skip to content

Commit 61f7b59

Browse files
committed
Merge branch 'release/1.120.0'
2 parents 16228c9 + 298efc2 commit 61f7b59

21 files changed

Lines changed: 389 additions & 183 deletions

File tree

BMM.Api/BMM.Api.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11+
<PackageReference Include="Microsoft.Maui.Essentials" Version="8.0.100" />
1112
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
1213
<PackageReference Include="Tavis.UriTemplates" Version="2.0.0" />
1314
</ItemGroup>

BMM.Core/App.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Net.Http;
55
using System.Reflection;
66
using Akavache;
7+
using SQLitePCL;
78
using BMM.Api;
89
using BMM.Api.Abstraction;
910
using BMM.Api.Framework;
@@ -111,6 +112,9 @@ public override void Initialize()
111112
{
112113
var serverUri = new ApiBaseUri(GlobalConstants.ApiUrl);
113114

115+
// Initialize SQLite before Akavache to prevent hanging
116+
Batteries_V2.Init();
117+
114118
Registrations.Start(GlobalConstants.ApplicationName);
115119
BlobCache.ApplicationName = GlobalConstants.PackageName;
116120

@@ -129,7 +133,7 @@ public override void Initialize()
129133
Mvx.IoCProvider.RegisterType<IResponseDeserializer, ResponseDeserializer>();
130134
Mvx.IoCProvider.RegisterType<IBmmVersionProvider, BmmVersionProvider>();
131135

132-
Mvx.IoCProvider.RegisterType<IAnalytics, NewRelicAnalytics>();
136+
Mvx.IoCProvider.RegisterType<IAnalytics, RudderStackAnalytics>();
133137
Mvx.IoCProvider.LazyConstructAndRegisterSingleton<IDeepLinkHandler, DeepLinkHandler>();
134138
Mvx.IoCProvider.RegisterType<IShareLink, ShareLink>();
135139
Mvx.IoCProvider.RegisterType<IAppNavigator, AppNavigator>();

BMM.Core/BMM.Core.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@
1313

1414
<ItemGroup>
1515
<PackageReference Include="Acr.UserDialogs" Version="8.0.1" />
16-
<PackageReference Include="akavache" Version="9.1.7" />
16+
<PackageReference Include="akavache" Version="10.0.1" />
1717
<PackageReference Include="IdentityModel" Version="7.0.0" />
1818
<PackageReference Include="IdentityModel.OidcClient" Version="6.0.0" />
19+
<PackageReference Include="Microsoft.Maui.Essentials" Version="8.0.100" />
1920
<PackageReference Include="MvvmCross" Version="9.2.0" />
2021
<PackageReference Include="MvvmCross.Plugin.JsonLocalization" Version="9.2.0" />
2122
<PackageReference Include="MvvmCross.Plugin.Messenger" Version="9.2.0" />
2223
<PackageReference Include="MvvmCross.Plugin.Visibility" Version="9.2.0" />
24+
<PackageReference Include="RudderAnalytics" Version="2.0.0" />
2325
<PackageReference Include="Sentry" Version="5.0.1" />
26+
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />
2427
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.34.0" />
2528
<PackageReference Include="TagLibSharp" Version="2.3.0" />
2629
<PackageReference Update="Microsoft.Maui.Graphics" Version="8.0.80" />

BMM.Core/Constants/AnalyticsConstants.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ namespace BMM.Core.Constants
22
{
33
public class AnalyticsConstants
44
{
5-
public const string NewRelicEventType = "BMM";
65
public const string ConnectionParameterName = "ConnectionType";
76
}
87
}

BMM.Core/Helpers/GlobalConstants.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,13 @@ public class GlobalConstants
5757
public const int NetworkRequestTimeout = 10;
5858
public const int DefaultNumberOfPodcastTracksToDownload = 3;
5959
public const string SentryDsn = "#{SENTRY_DSN_PLACEHOLDER}#";
60-
public const string NewRelicAndroidToken = "#{NEW_RELIC_ANDROID_PLACEHOLDER}#";
61-
public const string NewRelic_iOSToken = "#{NEW_RELIC_IOS_PLACEHOLDER}#";
60+
#if ENV_INT
61+
public const string RudderStackWriteKey = "32pDUqtHHmqJPwc714c3rA2WKLm";
62+
public const string RudderStackDataPlaneUrl = "https://rs.bcc.media/";
63+
#else
64+
public const string RudderStackWriteKey = "#{RUDDERSTACK_WRITE_KEY_PLACEHOLDER}#";
65+
public const string RudderStackDataPlaneUrl = "#{RUDDERSTACK_DATA_PLANE_URL_PLACEHOLDER}#";
66+
#endif
6267

6368
public const string AndroidUpdateLink = "https://play.google.com/store/apps/details?id=org.brunstad.bmm";
6469
public const string IosUpdateLink = "itms-apps://apps.apple.com/no/app/bmm-brunstad/id777577855";

BMM.Core/Implementations/Analytics/NewRelicAnalytics.cs

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using System.Globalization;
2+
using BMM.Api.Framework;
3+
using BMM.Api.Implementation.Constants;
4+
using BMM.Core.Constants;
5+
using BMM.Core.Extensions;
6+
using BMM.Core.Helpers;
7+
using BMM.Core.Implementations.FirebaseRemoteConfig;
8+
using BMM.Core.Implementations.Security;
9+
using BMM.Core.Utils;
10+
using RudderStack;
11+
12+
namespace BMM.Core.Implementations.Analytics
13+
{
14+
public class RudderStackAnalytics : IAnalytics
15+
{
16+
private readonly ILogger _logger;
17+
private readonly IUserStorage _userStorage;
18+
private readonly IFirebaseRemoteConfig _remoteConfig;
19+
private readonly IConnection _connection;
20+
private static bool _isInitialized = false;
21+
22+
public RudderStackAnalytics(
23+
ILogger logger,
24+
IUserStorage userStorage,
25+
IFirebaseRemoteConfig remoteConfig,
26+
IConnection connection)
27+
{
28+
_logger = logger;
29+
_userStorage = userStorage;
30+
_remoteConfig = remoteConfig;
31+
_connection = connection;
32+
33+
InitializeIfNeeded();
34+
}
35+
36+
private void InitializeIfNeeded()
37+
{
38+
if (_isInitialized ||
39+
GlobalConstants.RudderStackWriteKey.Contains(GlobalConstants.Placeholder) ||
40+
GlobalConstants.RudderStackDataPlaneUrl.Contains(GlobalConstants.Placeholder))
41+
return;
42+
43+
try
44+
{
45+
var config = new RudderConfig(dataPlaneUrl: GlobalConstants.RudderStackDataPlaneUrl, async: true);
46+
RudderAnalytics.Initialize(GlobalConstants.RudderStackWriteKey, config);
47+
_isInitialized = true;
48+
_logger.Info("RudderStack", "RudderStack Analytics initialized successfully");
49+
}
50+
catch (Exception ex)
51+
{
52+
_logger.Error("RudderStack", $"Failed to initialize RudderStack: {ex.Message}");
53+
}
54+
}
55+
56+
public void LogEvent(string eventName)
57+
{
58+
LogEvent(eventName, new Dictionary<string, object>());
59+
}
60+
61+
public void LogEvent(string eventName, IDictionary<string, object> parameters)
62+
{
63+
if (!_isInitialized)
64+
{
65+
_logger.Warn("RudderStack", "RudderStack not initialized, skipping event");
66+
return;
67+
}
68+
69+
try
70+
{
71+
var user = _userStorage.GetUser();
72+
if (user != null)
73+
{
74+
parameters.AddIfNew(nameof(user.AnalyticsId), user.AnalyticsId);
75+
76+
if (user.Age != null)
77+
parameters.Add(nameof(user.Age), user.Age);
78+
}
79+
80+
if (!string.IsNullOrEmpty(_remoteConfig.ExperimentId))
81+
parameters.AddIfNew(HeaderNames.ExperimentId, _remoteConfig.ExperimentId);
82+
83+
parameters.Add(AnalyticsConstants.ConnectionParameterName, AnalyticsUtils.GetConnectionType(_connection));
84+
85+
var dString = parameters.ToDictionary(
86+
k => k.Key,
87+
k =>
88+
{
89+
return k.Value switch
90+
{
91+
null => "null",
92+
IFormattable formattable => formattable.ToString(null, CultureInfo.InvariantCulture),
93+
_ => k.Value.ToString()
94+
};
95+
});
96+
97+
_logger.Info("Analytics", eventName + " {" + string.Join(",", dString.Select(kv => $"{kv.Key}={kv.Value}")) + "}");
98+
99+
// Get the user ID for RudderStack tracking
100+
var userId = user?.AnalyticsId?.ToString() ?? "anonymous";
101+
102+
RudderAnalytics.Client.Track(userId, eventName, parameters);
103+
}
104+
catch (Exception ex)
105+
{
106+
_logger.Error("RudderStack", $"Failed to log event '{eventName}': {ex.Message}");
107+
}
108+
}
109+
}
110+
}

BMM.Core/Implementations/Logger/BaseLogger.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public abstract class BaseLogger : ILogger
1616
private readonly IConnection _connection;
1717
private readonly IUserStorage _userStorage;
1818

19+
protected IUserStorage UserStorage => _userStorage;
20+
1921
protected BaseLogger(
2022
IConnection connection,
2123
IUserStorage userStorage)

BMM.Core/Translation/fr/main.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"DailyMessage": "Message quotidien",
2929
"ValueCopiedToClipboard": "{0} copié dans le presse-papiers",
3030
"AddToFavorites": "Ajouter aux favoris",
31-
"RemoveFromFavorites": "Supprimer des favoris"
31+
"RemoveFromFavorites": "Supprimer des favoris",
32+
"NowPlaying": "En lecture"
3233
},
3334
"Streak": {
3435
"Message": "Enchaînement de la semaine",
@@ -43,7 +44,7 @@
4344
"WeekdayMonday": "L",
4445
"WeekdayTuesday": "M",
4546
"WeekdayWednesday": "Me",
46-
"WeekdayThursday": "J",
47+
"WeekdayThursday": "M",
4748
"WeekdayFriday": "V"
4849
},
4950
"DeepLinkHandler": {
@@ -76,7 +77,13 @@
7677
"AlbumFailedToAddAlreadyExists": "Cet album est déjà dans votre playlist.",
7778
"TrackAlreadyExistInTrackCollection": "Le titre existe déjà dans la playlist {0}",
7879
"ShufflePlay": "Lecture aléatoire",
79-
"PluralAlbums": "{0} albums"
80+
"PluralAlbums": "{0} albums",
81+
"Hour": "heure",
82+
"Hours": "heures",
83+
"Minute": "min",
84+
"Second": "sec",
85+
"RemainingFormatSingular": "{0} heure, {1} minute restante",
86+
"RemainingFormatPlural": "{0} heures, {1} minutes restantes"
8087
},
8188
"AlbumsViewModel": {
8289
"Title": "Archive",
@@ -244,7 +251,8 @@
244251
"AslaksenTheme1": "Crois au Dieu des miracles",
245252
"AslaksenTheme2": "J'ai été crucifié avec Christ",
246253
"AslaksenTheme3": "Craindre et aimer Dieu",
247-
"AslaksenTheme4": "L'humilité, c'est tout"
254+
"AslaksenTheme4": "L'humilité, c'est tout",
255+
"AllEpisodes": "Tous les épisodes"
248256
},
249257
"CuratedPlaylistViewModel": {
250258
"Title": "Playlist"
@@ -456,6 +464,7 @@
456464
"Track.Download": "Télécharger piste",
457465
"Track.MoreInformation": "Plus d'informations",
458466
"Track.Share": "Partager le titre",
467+
"Track.ShareFrom": "Partager depuis {0}",
459468
"Album.Play": "Lire",
460469
"Album.AddToPlaylist": "Ajouter l'album à la playlist",
461470
"Album.AddToMyTracks": "Ajouter l'album à mes pistes",
@@ -635,5 +644,12 @@
635644
},
636645
"HvheDetailsViewModel": {
637646
"Title": "Score global"
647+
},
648+
"CarPlay": {
649+
"ErrorTitle": "Une erreur s'est produite...",
650+
"TryAgainButton": "Réessayer",
651+
"LoadingText": "Chargement...",
652+
"SignIntoBMM": "Connectez-vous à BMM sur votre téléphone",
653+
"Refresh": "Actualiser"
638654
}
639655
}

0 commit comments

Comments
 (0)