diff --git a/CHANGELOG.md b/CHANGELOG.md index f2ad44dd2..d5fb48db3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added List detail view. [#155](https://github.com/verse-pbc/issues/issues/155) - Added view for managing users in a list. [#135](https://github.com/verse-pbc/issues/issues/135) - Added ability to delete lists. [#136](https://github.com/verse-pbc/issues/issues/136) +- Added analytics for feed source selection and lists. [#129](https://github.com/verse-pbc/issues/issues/129) ### Internal Changes - Added function for creating a new list and a test verifying list editing. [#112](https://github.com/verse-pbc/issues/issues/112) diff --git a/Nos/Service/Analytics.swift b/Nos/Service/Analytics.swift index 945396d5e..409dccccf 100644 --- a/Nos/Service/Analytics.swift +++ b/Nos/Service/Analytics.swift @@ -301,4 +301,67 @@ class Analytics { func mentionsAutocompleteOpened() { track("Mentions Autocomplete Opened") } + + // MARK: - Feed Source + + /// Tracks when the user selects a list from the feed picker at the top of the home feed. + func listFeedOpened() { + track("List Feed Opened") + } + + /// Tracks when the user selects a relay from the feed picker at the top of the home feed. + func relayFeedOpened() { + track("Relay Feed Opened") + } + + /// Tracks when the user selects the Following feed at the top of the home feed. + func followFeedOpened() { + track("Follow Feed Opened") + } + + /// Tracks when the user opens the ``FeedCustomizerView``. + func feedCustomizerOpened() { + track("Feed Customizer Opened") + } + + /// Tracks when the user closes the ``FeedCustomizerView``. + func feedCustomizerClosed() { + track("Feed Customizer Closed") + } + + /// Tracks when the user toggles on a list in the ``FeedCustomizerView``. + func listPinned() { + track("List Pinned") + } + + /// Tracks when the user toggles off a list in the ``FeedCustomizerView``. + func listUnpinned() { + track("List Unpinned") + } + + /// Tracks when the user toggles on a relay in the ``FeedCustomizerView``. + func relayPinned() { + track("Relay Pinned") + } + + /// Tracks when the user toggles off a relay in the ``FeedCustomizerView``. + func relayUnpinned() { + track("Relay Unpinned") + } + + // MARK: - Lists + + /// Tracks when the user creates a new list. + func listCreated() { + track("List Created") + } + + /// Tracks when the user edits a list. + /// - Parameter numberOfUsers: The number of users in the list. + func listEdited(numberOfUsers: Int) { + track( + "List Edited", + properties: ["Number of users": numberOfUsers] + ) + } } diff --git a/Nos/Views/Home/FeedCustomizerView.swift b/Nos/Views/Home/FeedCustomizerView.swift index 826898efd..7958083f7 100644 --- a/Nos/Views/Home/FeedCustomizerView.swift +++ b/Nos/Views/Home/FeedCustomizerView.swift @@ -1,3 +1,4 @@ +import Dependencies import SwiftUI enum FeedTab: String { @@ -31,6 +32,7 @@ extension FeedTab: NosSegmentedPickerItem { struct FeedCustomizerView: View { + @Dependency(\.analytics) private var analytics @Environment(FeedController.self) var feedController let author: Author @Binding var shouldNavigateToLists: Bool @@ -73,6 +75,7 @@ struct FeedCustomizerView: View { font: .clarity(.semibold, textStyle: .footnote), image: Image(systemName: "slider.horizontal.3") ) { + analytics.feedCustomizerClosed() shouldNavigateToLists = true } } @@ -97,6 +100,7 @@ struct FeedCustomizerView: View { } .padding() .onTapGesture { + analytics.feedCustomizerClosed() shouldNavigateToRelays = true } }, diff --git a/Nos/Views/Home/FeedPicker.swift b/Nos/Views/Home/FeedPicker.swift index c0530142e..f33e0973f 100644 --- a/Nos/Views/Home/FeedPicker.swift +++ b/Nos/Views/Home/FeedPicker.swift @@ -1,9 +1,11 @@ import CoreData +import Dependencies import SwiftUI /// A picker view used to pick which source a feed should show notes from. struct FeedPicker: View { @Environment(FeedController.self) var feedController + @Dependency(\.analytics) private var analytics var body: some View { BeveledContainerView { @@ -12,6 +14,15 @@ struct FeedPicker: View { HStack(spacing: 0) { ForEach(feedController.enabledSources, id: \.self) { source in Button(action: { + switch source { + case .following: + analytics.followFeedOpened() + case .relay: + analytics.relayFeedOpened() + case .list: + analytics.listFeedOpened() + } + withAnimation(nil) { feedController.selectedSource = source } diff --git a/Nos/Views/Home/FeedSourceToggleView.swift b/Nos/Views/Home/FeedSourceToggleView.swift index 142d53a9d..1ffb57ae5 100644 --- a/Nos/Views/Home/FeedSourceToggleView.swift +++ b/Nos/Views/Home/FeedSourceToggleView.swift @@ -1,6 +1,8 @@ +import Dependencies import SwiftUI struct FeedSourceToggleView: View { + @Dependency(\.analytics) private var analytics @Environment(FeedController.self) var feedController let author: Author @@ -48,6 +50,22 @@ struct FeedSourceToggleView: View { .fixedSize(horizontal: false, vertical: true) .padding(.vertical, 10) .onChange(of: item.isOn) { _, _ in + switch item.source { + case .list: + if item.isOn { + analytics.listPinned() + } else { + analytics.listUnpinned() + } + case .relay: + if item.isOn { + analytics.relayPinned() + } else { + analytics.relayUnpinned() + } + default: + break + } feedController.toggleSourceEnabled(item.source) } } diff --git a/Nos/Views/Home/HomeFeedView.swift b/Nos/Views/Home/HomeFeedView.swift index 5ff00cd46..86b134608 100644 --- a/Nos/Views/Home/HomeFeedView.swift +++ b/Nos/Views/Home/HomeFeedView.swift @@ -164,6 +164,12 @@ struct HomeFeedView: View { } ToolbarItem(placement: .navigationBarTrailing) { Button { + if showFeedSelector { + analytics.feedCustomizerClosed() + } else { + analytics.feedCustomizerOpened() + } + withAnimation { showFeedSelector.toggle() showFeedTip = false diff --git a/Nos/Views/Lists/AuthorListManageUsersView.swift b/Nos/Views/Lists/AuthorListManageUsersView.swift index 6c40f1c6d..3c0c6fd82 100644 --- a/Nos/Views/Lists/AuthorListManageUsersView.swift +++ b/Nos/Views/Lists/AuthorListManageUsersView.swift @@ -1,3 +1,4 @@ +import Dependencies import Logger import SwiftUI @@ -19,6 +20,7 @@ struct AuthorListManageUsersView: View { } } + @Dependency(\.analytics) private var analytics @Environment(\.dismiss) private var dismiss @Environment(RelayService.self) private var relayService @Environment(CurrentUser.self) private var currentUser @@ -153,6 +155,13 @@ struct AuthorListManageUsersView: View { } else { dismiss() } + + switch mode { + case .create: + analytics.listCreated() + case .update: + analytics.listEdited(numberOfUsers: authors.count) + } } catch { Log.error("Error when creating list: \(error.localizedDescription)") }